From jay.krell at cornell.edu Sun Feb 1 14:55:59 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 13:55:59 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: How about thread/posix/x86? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jkrell at elego.de > Date: Fri, 30 Jan 2009 14:43:24 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Probably the wrong place for this. If it is x86-dependent it should > go somewhere in the x86 hierarchy, not in a top-level directory like > "context". > > On 30 Jan 2009, at 04:25, Jay Krell wrote: > >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/01/30 04:25:37 >> >> Added files: >> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >> >> Log message: >> highly non-portable working version of set/get/make/swapcontext for >> NT386; >> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >> non-x86, >> though again, it is highly system specific, and inline assembly >> syntax >> is very different between Visual C++ and gcc From jay.krell at cornell.edu Sun Feb 1 15:05:30 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:05:30 +0000 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? Message-ID: Does anyone think the division between m3core/runtime/RTThread and m3core/thread/posix makes sense, is correct, is important, is at all "good", etc.? thread/posix is the only user of RTThread. RTThread was forked into platform-specific variants, but they are all nearly identical. I think this code belongs in m3core/thread/posix/ThreadPosix.m3 or m3core/thread/posix/ThreadPosixC.c and have begun making it so. It is not much code, but it is multiplied out per-platform. There is already RTThreadC.c for many platforms, and introducing ThreadPosixC.c gives me a place to park related C code, in a less disruptive way (ie: ThreadPosixC.c and RTThreadC.c could be merged at some point, probably by deleting RTThreadC.c, once ThreadPosixC.c is complete). My /real/ agenda here is to move to "my rewritten drastically reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), which reduce porting effort, but I feel I can't do that unless user thread support is there, so I am "cleaning up" user thread support along a few lines (make it work on LINUXLIBC6, make it more portable). - Jay From jay.krell at cornell.edu Sun Feb 1 15:11:07 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:11:07 +0000 Subject: [M3devel] solaris RTThread__Transfer? Message-ID: SOLgnu/SOLsun have this: void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { if (getcontext(from) == 0) { to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp return */ setcontext(to); /* fire it up */ } } Two questions: The longjmp emulation is unnecessary, right? (and platform specific) getcontext + setcontext could just be swapcontext, right? Specifically, the "entire function" could "just" be: (yeah yeah, only a slight reduction). void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { swapcontext(from, to); } or even RTThread.i3 PROCEDURE Transfer(...); Yes, I notice the error checking, but a) why would it ever fail b) is that really complete anyway? Just silently ignore the error? ? - Jay From jay.krell at cornell.edu Sun Feb 1 15:44:20 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:44:20 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? Message-ID: I'd like to consider further reducing "system dependent cloned headers". Upthread.i3 in particular. We have for example: pthread_mutex_t = ARRAY[1..6] OF INTEGER; Now, pthread_mutex_t is used in two ways. Some statically allocated variables: VAR activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *) slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *) initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *) Some untraced heap allocated variables: PROCEDURE InitMutex (m: Mutex) = VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO END; IF m.mutex # NIL THEN RETURN END; mutex := NEW(UNTRACED REF pthread_mutex_t); WITH r = Upthread.mutex_init(mutex^, NIL) DO END; m.mutex := mutex; FINALLY WITH r = Upthread.mutex_unlock(initMu) DO END; END; RTHeapRep.RegisterFinalCleanup (m, CleanMutex); END InitMutex; The statically allocated variables can just be moved to C, trivial. And their initialization then kept efficient. What is the right way to translate the untraced allocation? OR, here is kind of the opposite question: Why is the mutex heap allocated anyway? Why not embed it "by value"? Granted, that makes it more difficult to smush out platform-specificity. And then to address that: I would kind of like the idea of an "extern type". An extern type is a type whose instances may only be embedded within heap allocated objects, possibly only at the end, possibly with an implied alignment=maximum, their size would be exposed via constant C variable, probably they would have a designated initialization function, or be zeroed. They could also be "standalone" heap allocated objects. Specifically, something like this: TYPE pthread_t; TYPE Thread.T = RECORD (* Modula-3 stuff *) pthread: pthread_t; END; Thread := NEW(Thread.T); roughly equiv to Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); pthread.c: extern const size_t pthread_t_size = sizeof(pthread_t); You know -- so that they can be implemented "portably". Given that they are already opaque and all the Modula-3 code knows is their size, alignment, and what functions they can be passed to. - Jay From hosking at cs.purdue.edu Sun Feb 1 23:31:44 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:31:44 +1100 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? In-Reply-To: References: Message-ID: These divisions are largely historical, and so long as we preserve the required interfaces (see the language report) I don't see a problem with this plan. On 2 Feb 2009, at 01:05, Jay wrote: > > Does anyone think the division between > m3core/runtime/RTThread and m3core/thread/posix makes sense, > is correct, is important, is at all "good", etc.? > > > thread/posix is the only user of RTThread. > RTThread was forked into platform-specific variants, > but they are all nearly identical. > > > I think this code belongs in m3core/thread/posix/ThreadPosix.m3 > or m3core/thread/posix/ThreadPosixC.c and have begun making it so. > > > It is not much code, but it is multiplied out per-platform. > > > There is already RTThreadC.c for many platforms, and > introducing ThreadPosixC.c gives me a place to park related C > code, in a less disruptive way (ie: ThreadPosixC.c and > RTThreadC.c could be merged at some point, probably by deleting > RTThreadC.c, once ThreadPosixC.c is complete). > > > My /real/ agenda here is to move to "my rewritten drastically > reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), > which reduce porting effort, but I feel > I can't do that unless user thread support is there, > so I am "cleaning up" user thread support along a few lines > (make it work on LINUXLIBC6, make it more portable). > > > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:32:56 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:32:56 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> What is the purpose of this code? On 2 Feb 2009, at 00:55, Jay wrote: > > How about thread/posix/x86? > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jkrell at elego.de >> Date: Fri, 30 Jan 2009 14:43:24 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Probably the wrong place for this. If it is x86-dependent it should >> go somewhere in the x86 hierarchy, not in a top-level directory like >> "context". >> >> On 30 Jan 2009, at 04:25, Jay Krell wrote: >> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>> >>> Added files: >>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>> >>> Log message: >>> highly non-portable working version of set/get/make/swapcontext for >>> NT386; >>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>> non-x86, >>> though again, it is highly system specific, and inline assembly >>> syntax >>> is very different between Visual C++ and gcc From hosking at cs.purdue.edu Sun Feb 1 23:41:29 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:41:29 +1100 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: References: Message-ID: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Sorry, I had mis-remembered that code as using swapcontext, which it clearly does not. I seem to recall that the longjmp emulation was necessary for some reason, but I forget why right now. Was Transfer being called from some place as if it was a longjmp? Hmm... It's been 10 years since I wrote that code for the Solaris port... ;-) On 2 Feb 2009, at 01:11, Jay wrote: > > SOLgnu/SOLsun have this: > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > if (getcontext(from) == 0) { > to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp > return */ > setcontext(to); /* fire it up */ > } > } > > Two questions: > The longjmp emulation is unnecessary, right? (and platform specific) > getcontext + setcontext could just be swapcontext, right? > > > Specifically, the "entire function" could "just" be: (yeah yeah, > only a slight reduction). > > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > swapcontext(from, to); > } > > > or even > > > RTThread.i3 > PROCEDURE Transfer(...); > > > Yes, I notice the error checking, but a) why would it ever fail b) > is that really complete anyway? > Just silently ignore the error? > > > ? > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:54:27 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:54:27 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: Message-ID: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> On 2 Feb 2009, at 01:44, Jay wrote: > I'd like to consider further reducing "system dependent cloned > headers". > Upthread.i3 in particular. > > > We have for example: > > > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Now, pthread_mutex_t is used in two ways. > > > Some statically allocated variables: > > > VAR > activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of > active threads *) > slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread > slot table *) > initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for > initializers *) > > > Some untraced heap allocated variables: > > > PROCEDURE InitMutex (m: Mutex) = > VAR mutex: UNTRACED REF pthread_mutex_t; > BEGIN > TRY > WITH r = Upthread.mutex_lock(initMu) DO END; > IF m.mutex # NIL THEN RETURN END; > mutex := NEW(UNTRACED REF pthread_mutex_t); > WITH r = Upthread.mutex_init(mutex^, NIL) DO END; > m.mutex := mutex; > FINALLY > WITH r = Upthread.mutex_unlock(initMu) DO END; > END; > RTHeapRep.RegisterFinalCleanup (m, CleanMutex); > END InitMutex; > > > The statically allocated variables can just be moved to C, trivial. > And their initialization then kept efficient. Sure, except that now you smear code across the C and Modula-3 universes. Lack of clarity... > What is the right way to translate the untraced allocation? Not sure what you mean by "translate". We are writing Modula-3 in Modula-3 here, so why translate it? I suppose you could invoke some C code to allocate the mutex and return it, but then you have a call to malloc that might not play nice with the Modula-3 code. In the old days this was certainly the case (on user-level thread systems we need malloc to be atomic with respect to thread transfer). Thus, NEW(UNTRACED REF ...) does bottom out at malloc, but RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching around the call to malloc (these disable switching on user-thread platforms, but are no-ops on system threading platforms where malloc should already be thread-safe). How about simply having some C variable that records sizeof(pthread_mutex_t) and use that in a call to new: array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) mutex := ADR(array[0]) > OR, here is kind of the opposite question: > > > Why is the mutex heap allocated anyway? > > Why not embed it "by value"? Because it is difficult to embed by value when the type is opaque. > Granted, that makes it more difficult to smush out platform- > specificity. Indeed. And the rest of what you say here is a pretty disgusting hack. Modula-3 has pretty clean type semantics and you are compromising that in a rather gross way. > > And then to address that: > > > I would kind of like the idea of an "extern type". > An extern type is a type whose instances may only be embedded within > heap allocated objects, > possibly only at the end, possibly with an implied > alignment=maximum, their size > would be exposed via constant C variable, probably they would have a > designated initialization > function, or be zeroed. They could also be "standalone" heap > allocated objects. > > > Specifically, something like this: > > > TYPE pthread_t; > > > TYPE Thread.T = RECORD > (* Modula-3 stuff *) > pthread: pthread_t; > END; > Thread := NEW(Thread.T); > > > roughly equiv to > Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); > > > pthread.c: > > > extern const size_t pthread_t_size = sizeof(pthread_t); > > > You know -- so that they can be implemented "portably". > Given that they are already opaque and all the Modula-3 code knows > is their size, alignment, and what functions they can be passed to. > > > - Jay From jay.krell at cornell.edu Sun Feb 1 23:59:27 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 22:59:27 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > What is the purpose of this code? OpenBSD does not have the *context functions. This provides them for OpenBSD/x86. I /assume/ their only user will be ThreadPosix.m3. That there will be unix/common/ucontext.i3 that declares them. Even if that is a little bit "dishonest" on platforms that lack them. Eh, I guess that begs for the answer, they belong in unix/common/x86? (forking for x86-thisos, x86-thatos, if/as needed) A reason not to put in unix/common/x86 however is if there are compromises that make them not meet the general spec, but adequate for ThreadPosix.m3. I don't have any in mind currently. Restricting makecontext to have argc=1 is tempting, but so far avoided. Perhaps I will see about getting these into OpenBSD. I also anticipate trying to implement them for other systems e.g. PPC_DARWIN. (again, current 10.5 Darwin has them, older 10.4 does not). Possibly in both cases I can just use the "real" versions, I should have thought of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, copy them. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:32:56 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > What is the purpose of this code? > > On 2 Feb 2009, at 00:55, Jay wrote: > >> >> How about thread/posix/x86? >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jkrell at elego.de >>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Probably the wrong place for this. If it is x86-dependent it should >>> go somewhere in the x86 hierarchy, not in a top-level directory like >>> "context". >>> >>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>> >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>> >>>> Added files: >>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>> >>>> Log message: >>>> highly non-portable working version of set/get/make/swapcontext for >>>> NT386; >>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>> non-x86, >>>> though again, it is highly system specific, and inline assembly >>>> syntax >>>> is very different between Visual C++ and gcc > From jay.krell at cornell.edu Mon Feb 2 00:10:17 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:10:17 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: I meant translate Modula-3 to C -- C because it knows size and alignment. I didn't presume I could just call malloc. Even if untraced, I thought calling "the allocator" might have some positive interaction with the garbage collector. Maybe not? (I should look at the code....could be untraced really does just call malloc and no gc interaction. Oops.) > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) That is good. I must have had some hangup about it. NEW is guaranteed to be "very aligned" so there is no alignment issue here? > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... I agree. I'm conflicted here. Look at for example at the dealings with "ackSem". It is a "simple transform" but "transform" is the suspicious word there, not wholly exonerated by "simple". The static variables may also have an issue on Darwin -- can't have non-static variables in a shared object or somesuch. So I'll hold off. (no access to Darwin past few days) Solution could be wrapping the variables up in functions, or every operation on them, like for ackSem. Both kind of not ideal though. On the other hand, the RTThread / RTThreadStk / ThreadPosix split is also a bit smearing/unclear -- you know, FreeStack vs. DisposeStack. But two wrongs don't make a right, I understand. I do consider the user thread code to be a second class citizen. >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. Why? I understand issues of "binary compatibility + dynamic linking". "Pointers are good because they never change size." "Pointers are good for opaque types because they never change size. Better than an int because int often can't store a pointer." But I think we ignore these issues in Modula-3. I know I have been. > hack Seemed a good way to generalize what I'm thinking about for pthread/mutex/etc. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:54:27 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > On 2 Feb 2009, at 01:44, Jay wrote: > >> I'd like to consider further reducing "system dependent cloned >> headers". >> Upthread.i3 in particular. >> >> >> We have for example: >> >> >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Now, pthread_mutex_t is used in two ways. >> >> >> Some statically allocated variables: >> >> >> VAR >> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >> active threads *) >> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >> slot table *) >> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >> initializers *) >> >> >> Some untraced heap allocated variables: >> >> >> PROCEDURE InitMutex (m: Mutex) = >> VAR mutex: UNTRACED REF pthread_mutex_t; >> BEGIN >> TRY >> WITH r = Upthread.mutex_lock(initMu) DO END; >> IF m.mutex # NIL THEN RETURN END; >> mutex := NEW(UNTRACED REF pthread_mutex_t); >> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >> m.mutex := mutex; >> FINALLY >> WITH r = Upthread.mutex_unlock(initMu) DO END; >> END; >> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >> END InitMutex; >> >> >> The statically allocated variables can just be moved to C, trivial. >> And their initialization then kept efficient. > > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... > >> What is the right way to translate the untraced allocation? > > Not sure what you mean by "translate". We are writing Modula-3 in > Modula-3 here, so why translate it? I suppose you could invoke some C > code to allocate the mutex and return it, but then you have a call to > malloc that might not play nice with the Modula-3 code. In the old > days this was certainly the case (on user-level thread systems we need > malloc to be atomic with respect to thread transfer). Thus, > NEW(UNTRACED REF ...) does bottom out at malloc, but > RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching > around the call to malloc (these disable switching on user-thread > platforms, but are no-ops on system threading platforms where malloc > should already be thread-safe). How about simply having some C > variable that records sizeof(pthread_mutex_t) and use that in a call > to new: > > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > mutex := ADR(array[0]) > >> OR, here is kind of the opposite question: >> >> >> Why is the mutex heap allocated anyway? >> >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. > >> Granted, that makes it more difficult to smush out platform- >> specificity. > > Indeed. > > And the rest of what you say here is a pretty disgusting hack. > Modula-3 has pretty clean type semantics and you are compromising that > in a rather gross way. > >> >> And then to address that: >> >> >> I would kind of like the idea of an "extern type". >> An extern type is a type whose instances may only be embedded within >> heap allocated objects, >> possibly only at the end, possibly with an implied >> alignment=maximum, their size >> would be exposed via constant C variable, probably they would have a >> designated initialization >> function, or be zeroed. They could also be "standalone" heap >> allocated objects. >> >> >> Specifically, something like this: >> >> >> TYPE pthread_t; >> >> >> TYPE Thread.T = RECORD >> (* Modula-3 stuff *) >> pthread: pthread_t; >> END; >> Thread := NEW(Thread.T); >> >> >> roughly equiv to >> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >> >> >> pthread.c: >> >> >> extern const size_t pthread_t_size = sizeof(pthread_t); >> >> >> You know -- so that they can be implemented "portably". >> Given that they are already opaque and all the Modula-3 code knows >> is their size, alignment, and what functions they can be passed to. >> >> >> - Jay > From jay.krell at cornell.edu Mon Feb 2 00:14:32 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:14:32 +0000 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> References: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Message-ID: > sorry No problem. I just want to understand, if possible, for when I handle other platforms. > Was Transfer being called from some place as if it was a longjmp? I don't think so but I'll double check. The primary use of it I think ignores the return value. Thanks, - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:41:29 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] solaris RTThread__Transfer? > > Sorry, I had mis-remembered that code as using swapcontext, which it > clearly does not. > > I seem to recall that the longjmp emulation was necessary for some > reason, but I forget why right now. Was Transfer being called from > some place as if it was a longjmp? > > Hmm... > > It's been 10 years since I wrote that code for the Solaris port... ;-) > > On 2 Feb 2009, at 01:11, Jay wrote: > >> >> SOLgnu/SOLsun have this: >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> if (getcontext(from) == 0) { >> to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp >> return */ >> setcontext(to); /* fire it up */ >> } >> } >> >> Two questions: >> The longjmp emulation is unnecessary, right? (and platform specific) >> getcontext + setcontext could just be swapcontext, right? >> >> >> Specifically, the "entire function" could "just" be: (yeah yeah, >> only a slight reduction). >> >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> swapcontext(from, to); >> } >> >> >> or even >> >> >> RTThread.i3 >> PROCEDURE Transfer(...); >> >> >> Yes, I notice the error checking, but a) why would it ever fail b) >> is that really complete anyway? >> Just silently ignore the error? >> >> >> ? >> - Jay > From wagner at elegosoft.com Mon Feb 2 00:12:43 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 02 Feb 2009 00:12:43 +0100 Subject: [M3devel] ssh outage on birch.elegosoft.com, was: Re: ssh down? In-Reply-To: References: Message-ID: <20090202001243.csodfhd1scg4o8ws@mail.elegosoft.com> Currently all ssh services on birch are out of order. We don't have direct access to this machine; we'll be able to get access again tomorrow morning at 9 CET (without further costs). I expect that Michael will be able to get everything working again soon after, if there is no unrecoverable hardware failure. Restoring from backup would take some hours, I'd expect... Sorry for the inconveniences, Olaf Quoting Jay : > > C:\Documents and Settings\jay>ssh -v -v -v -v jkrell at birch.elegosoft.com > OpenSSH_5.1p1, OpenSSL 0.9.8i 15 Sep 2008 > debug2: ssh_connect: needpriv 0 > debug1: Connecting to birch.elegosoft.com [88.198.39.217] port 22. > debug1: connect to address 88.198.39.217 port 22: Connection refused > ssh: connect to host birch.elegosoft.com port 22: Connection refused > > > C:\Documents and Settings\jay>ping birch.elegosoft.com > PING birch.elegosoft.com (88.198.39.217): 56 data bytes > 64 bytes from 88.198.39.217: icmp_seq=0 ttl=59 time=206 ms > 64 bytes from 88.198.39.217: icmp_seq=1 ttl=59 time=217 ms > ----birch.elegosoft.com PING Statistics---- > 2 packets transmitted, 2 packets received, 0.0% packet loss > round-trip (ms) min/avg/max/med = 206/212/217/212 > > - Jay -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 2 00:27:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:27:46 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> On 2 Feb 2009, at 10:10, Jay wrote: > > I meant translate Modula-3 to C -- C because it knows size and > alignment. > I didn't presume I could just call malloc. > Even if untraced, I thought calling "the allocator" might > have some positive interaction with the garbage collector. > Maybe not? > (I should look at the code....could be untraced really > does just call malloc and no gc interaction. Oops.) No GC interaction at all. Just user-level thread interaction to make malloc atomic w.r. to thread switches. >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > > > That is good. I must have had some hangup about it. > NEW is guaranteed to be "very aligned" so there is no alignment > issue here? Hmm, yes, you are right that there is a possible alignment issue. I am used to pthread_mutext_t being a simple reference. But surely in C the type of the pthread_mutex_t struct would have appropriate alignment padding anyway so as to allow allocation using malloc(sizeof pthread_mutex_t)? So, it all should just work right? >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... > > > I agree. I'm conflicted here. > Look at for example at the dealings with "ackSem". > It is a "simple transform" but "transform" is the suspicious > word there, not wholly exonerated by "simple". I don't have your code in front of me at the moment, but I am leery. > The static variables may also have an issue on Darwin -- can't have > non-static variables in a shared object or somesuch. So I'll hold off. > (no access to Darwin past few days) > Solution could be wrapping the variables up in functions, or every > operation on them, like for ackSem. Both kind of not ideal though. Function call would be fine. You could cache the value in a module variable as needed. > On the other hand, the RTThread / RTThreadStk / ThreadPosix > split is also a bit smearing/unclear -- you know, FreeStack vs. > DisposeStack. > But two wrongs don't make a right, I understand. Indeed, but they originally encapsulated unrelated things. > I do consider the user thread code to be a second class citizen. That's still no reason to muddy it's implementation... :-) >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. > > Why? > I understand issues of "binary compatibility + dynamic linking". > "Pointers are good because they never change size." > "Pointers are good for opaque types because they never change size. > Better than an int because int often can't store a pointer." > > But I think we ignore these issues in Modula-3. I know I have been. I would like to think that we don't ignore these issues and as a result we get a cleaner system. Err on the side of promoting elegance rather than lowering ourselves to the standards of legacy code. >> hack > > Seemed a good way to generalize what I'm thinking about for pthread/ > mutex/etc. > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:54:27 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> On 2 Feb 2009, at 01:44, Jay wrote: >> >>> I'd like to consider further reducing "system dependent cloned >>> headers". >>> Upthread.i3 in particular. >>> >>> >>> We have for example: >>> >>> >>> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >>> >>> >>> Now, pthread_mutex_t is used in two ways. >>> >>> >>> Some statically allocated variables: >>> >>> >>> VAR >>> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >>> active threads *) >>> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >>> slot table *) >>> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >>> initializers *) >>> >>> >>> Some untraced heap allocated variables: >>> >>> >>> PROCEDURE InitMutex (m: Mutex) = >>> VAR mutex: UNTRACED REF pthread_mutex_t; >>> BEGIN >>> TRY >>> WITH r = Upthread.mutex_lock(initMu) DO END; >>> IF m.mutex # NIL THEN RETURN END; >>> mutex := NEW(UNTRACED REF pthread_mutex_t); >>> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >>> m.mutex := mutex; >>> FINALLY >>> WITH r = Upthread.mutex_unlock(initMu) DO END; >>> END; >>> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >>> END InitMutex; >>> >>> >>> The statically allocated variables can just be moved to C, trivial. >>> And their initialization then kept efficient. >> >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... >> >>> What is the right way to translate the untraced allocation? >> >> Not sure what you mean by "translate". We are writing Modula-3 in >> Modula-3 here, so why translate it? I suppose you could invoke some C >> code to allocate the mutex and return it, but then you have a call to >> malloc that might not play nice with the Modula-3 code. In the old >> days this was certainly the case (on user-level thread systems we >> need >> malloc to be atomic with respect to thread transfer). Thus, >> NEW(UNTRACED REF ...) does bottom out at malloc, but >> RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching >> around the call to malloc (these disable switching on user-thread >> platforms, but are no-ops on system threading platforms where malloc >> should already be thread-safe). How about simply having some C >> variable that records sizeof(pthread_mutex_t) and use that in a call >> to new: >> >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) >> mutex := ADR(array[0]) >> >>> OR, here is kind of the opposite question: >>> >>> >>> Why is the mutex heap allocated anyway? >>> >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. >> >>> Granted, that makes it more difficult to smush out platform- >>> specificity. >> >> Indeed. >> >> And the rest of what you say here is a pretty disgusting hack. >> Modula-3 has pretty clean type semantics and you are compromising >> that >> in a rather gross way. >> >>> >>> And then to address that: >>> >>> >>> I would kind of like the idea of an "extern type". >>> An extern type is a type whose instances may only be embedded within >>> heap allocated objects, >>> possibly only at the end, possibly with an implied >>> alignment=maximum, their size >>> would be exposed via constant C variable, probably they would have a >>> designated initialization >>> function, or be zeroed. They could also be "standalone" heap >>> allocated objects. >>> >>> >>> Specifically, something like this: >>> >>> >>> TYPE pthread_t; >>> >>> >>> TYPE Thread.T = RECORD >>> (* Modula-3 stuff *) >>> pthread: pthread_t; >>> END; >>> Thread := NEW(Thread.T); >>> >>> >>> roughly equiv to >>> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >>> >>> >>> pthread.c: >>> >>> >>> extern const size_t pthread_t_size = sizeof(pthread_t); >>> >>> >>> You know -- so that they can be implemented "portably". >>> Given that they are already opaque and all the Modula-3 code knows >>> is their size, alignment, and what functions they can be passed to. >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Mon Feb 2 00:30:22 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:30:22 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: On 2 Feb 2009, at 09:59, Jay wrote: >> What is the purpose of this code? > > > OpenBSD does not have the *context functions. > This provides them for OpenBSD/x86. Are they correct w.r. to signals and floating point state? > I /assume/ their only user will be ThreadPosix.m3. > That there will be unix/common/ucontext.i3 that declares them. > Even if that is a little bit "dishonest" on platforms that lack them. > Eh, I guess that begs for the answer, they belong in > unix/common/x86? Yeah, that's where I thought they might go. > (forking for x86-thisos, x86-thatos, if/as needed) > > > A reason not to put in unix/common/x86 however is if there are > compromises that make them not meet the general spec, but adequate > for ThreadPosix.m3. I don't have any in mind currently. > Restricting makecontext to have argc=1 is tempting, but so far > avoided. > > > Perhaps I will see about getting these into OpenBSD. > I also anticipate trying to implement them for other systems e.g. > PPC_DARWIN. > (again, current 10.5 Darwin has them, older 10.4 does not). > Possibly in both cases I can just use the "real" versions, I should > have thought > of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, > copy them. Why do we care about older Darwin versions? The support on Darwin has become much more stable since I first did the port to 10.3, as the base platform has become more reliable. As far as I can tell, prior to 10.5 Darwin still showed signs of being a work in progress (at least w.r. to POSIX compatibility). > > > > - Jay > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:32:56 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> What is the purpose of this code? >> >> On 2 Feb 2009, at 00:55, Jay wrote: >> >>> >>> How about thread/posix/x86? >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jkrell at elego.de >>>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Probably the wrong place for this. If it is x86-dependent it should >>>> go somewhere in the x86 hierarchy, not in a top-level directory >>>> like >>>> "context". >>>> >>>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>>> >>>>> Added files: >>>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>>> >>>>> Log message: >>>>> highly non-portable working version of set/get/make/swapcontext >>>>> for >>>>> NT386; >>>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>>> non-x86, >>>>> though again, it is highly system specific, and inline assembly >>>>> syntax >>>>> is very different between Visual C++ and gcc >> From jay.krell at cornell.edu Mon Feb 2 01:13:04 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 00:13:04 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > Tony > > Are they correct w.r. to signals and floating point state? > >> Jay Eh, I guess that begs for the answer, they belong in >> unix/common/x86? > > Yeah, that's where I thought they might go. > > Why do we care about older Darwin versions? The support on Darwin has > become much more stable since I first did the port to 10.3, as the > Floating point state and signal mask Not sure. NetBSD getcontext: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/arch/i386/sys/getcontext.S?rev=1.3&content-type=text/x-cvsweb-markup&only_with_tag=MAIN doesn't do anything here...oh..but that clearly isn't the entire implementation.. I'll have to dig around. I will have to write a test case with a bunch of threads and floating point and signal mask changes..and compare to setjmp/longjmp.. You really think 10.5 is so much better than previous? As a user I never noticed much change since 10.2. Anyone else here using prior to 10.5 or care to support them? (I suspect nobody is using any Darwin version but...) But again, IF their get/make/swap/setcontext in 10.5 is all usermode, and presumably BSD-licensed, we can just copy it into m3core. (I suspect the bit I haven't found in NetBSD is in the kernel. Should only take a few minutes to find, but I have to run..) I'll move to unix/src/common/x86 as we both thought of, if it works. Or maybe just work on a system that provides *context. - Jay From mika at async.caltech.edu Mon Feb 2 01:42:32 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sun, 01 Feb 2009 16:42:32 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." Message-ID: <200902020042.n120gXij073476@camembert.async.caltech.edu> I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin (10.3 -> 10.4), all Hell broke loose, too... Mika >> >> Why do we care about older Darwin versions? The support on Darwin has >> become much more stable since I first did the port to 10.3, as the > From jay.krell at cornell.edu Mon Feb 2 02:00:40 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 01:00:40 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: Ok, I forgot to qualify the question -- do you care about user threads? - Jay ---------------------------------------- > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > Date: Sun, 1 Feb 2009 16:42:32 -0800 > From: mika at async.caltech.edu > > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:36:30 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:36:30 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <306B482E-57C1-4711-8760-C5C53C8DED7F@cs.purdue.edu> The CM3 transition 10.2-10.3 was much more difficult than 10.4-10.5. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:37:02 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:37:02 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <17D3AB18-01A2-49B8-8D4F-3EB349401E76@cs.purdue.edu> Sorry, meant 10.4-10.5 much easier than previous. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From mika at async.caltech.edu Tue Feb 3 07:21:53 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Mon, 02 Feb 2009 22:21:53 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> Message-ID: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Jay Krell writes: >CVSROOT: /usr/cvs >Changes by: jkrell at birch. 09/02/03 06:17:25 > >Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 > RTAllocator.m3 > >Log message: > expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely you can't have Free in a non-UNSAFE interface... Mika > introduce internal RTAlloc.MallocUninitialized > > These include Disable/EnableSwitching, and > raising exceptions upon failure. > (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 07:50:21 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 17:50:21 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <931183AC-9652-4F06-8EEB-A5D077669667@cs.purdue.edu> Indeed! I just repaired this. On 3 Feb 2009, at 17:21, Mika Nystrom wrote: > Jay Krell writes: >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/02/03 06:17:25 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >> Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:07:55 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:07:55 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: Sorry, fair enough. I don't think about safety much. Can I put these in a new unsafe RTAllocateUnsafe.i3 or RTUnsafeAllocator.i3? And then the function names I had come up with MallocUninitialized, MallocZeroed. Using array of char seems non-ideal to me somehow. It seems like a "workaround". It doesn't seem really any safer than not having a type at all. I understand, the array, the type, does imply a size, and so I would get some bounds checking against it, except I never access these things anyway, I just pass them on to unsafe C code. Related but tangential question, something I also didn't pay close enough attention to: What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise OutOfMemory directly? - Jay ---------------------------------------- > To: jkrell at elego.de > Date: Mon, 2 Feb 2009 22:21:53 -0800 > From: mika at async.caltech.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Jay Krell writes: >>CVSROOT: /usr/cvs >>Changes by: jkrell at birch. 09/02/03 06:17:25 >> >>Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >>Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 09:35:38 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 19:35:38 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> On 3 Feb 2009, at 19:07, Jay wrote: > > Sorry, fair enough. I don't think about safety much. > > > Can I put these in a new unsafe RTAllocateUnsafe.i3 or > RTUnsafeAllocator.i3? > And then the function names I had come up with MallocUninitialized, > MallocZeroed. What do you need them for? RTAllocator is there so one can allocate by typecode. I don't see the point of Malloc/Free. > Using array of char seems non-ideal to me somehow. > It seems like a "workaround". > It doesn't seem really any safer than not having a type at all. > I understand, the array, the type, does imply a size, and so I would > get some bounds checking against it, except I never access these > things anyway, I just pass them on to unsafe C code. > > > Related but tangential question, something I also didn't pay close > enough attention to: > What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? The first is an explicit exception while the latter is implicit. > Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise > OutOfMemory directly? Because the exception is implicit. Any procedure can raise a RuntimeError. > > > > - Jay > > > ---------------------------------------- >> To: jkrell at elego.de >> Date: Mon, 2 Feb 2009 22:21:53 -0800 >> From: mika at async.caltech.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Jay Krell writes: >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>> RTAllocator.m3 >>> >>> Log message: >>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >> >> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >> you can't have Free in a non-UNSAFE interface... >> >> Mika >> >>> introduce internal RTAlloc.MallocUninitialized >>> >>> These include Disable/EnableSwitching, and >>> raising exceptions upon failure. >>> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:58:53 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:58:53 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: > What do you need them for? RTAllocator is there so one can allocate How do I get a typecode in C? Perhaps the attached is unnecessarily elaborate? Or the new/dispose functions should be moved to Modula-3? Or eliminated and the small number of callers can say NEW(ARRAY OF CHAR, Uucontext.Size)? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Tue, 3 Feb 2009 19:35:38 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) > > On 3 Feb 2009, at 19:07, Jay wrote: > >> >> Sorry, fair enough. I don't think about safety much. >> >> >> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >> RTUnsafeAllocator.i3? >> And then the function names I had come up with MallocUninitialized, >> MallocZeroed. > > What do you need them for? RTAllocator is there so one can allocate > by typecode. I don't see the point of Malloc/Free. > >> Using array of char seems non-ideal to me somehow. >> It seems like a "workaround". >> It doesn't seem really any safer than not having a type at all. >> I understand, the array, the type, does imply a size, and so I would >> get some bounds checking against it, except I never access these >> things anyway, I just pass them on to unsafe C code. >> >> >> Related but tangential question, something I also didn't pay close >> enough attention to: >> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? > > The first is an explicit exception while the latter is implicit. > >> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >> OutOfMemory directly? > > Because the exception is implicit. Any procedure can raise a > RuntimeError. > >> >> >> >> - Jay >> >> >> ---------------------------------------- >>> To: jkrell at elego.de >>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>> From: mika at async.caltech.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Jay Krell writes: >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>> >>>> Modified files: >>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>> RTAllocator.m3 >>>> >>>> Log message: >>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>> >>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >>> you can't have Free in a non-UNSAFE interface... >>> >>> Mika >>> >>>> introduce internal RTAlloc.MallocUninitialized >>>> >>>> These include Disable/EnableSwitching, and >>>> raising exceptions upon failure. >>>> (Disable/Enable only do something for user threads). > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.c URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.i3 URL: From hosking at cs.purdue.edu Tue Feb 3 11:42:00 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 21:42:00 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: This will highly likely break. Let me take a look and see if there's an alternative. On 3 Feb 2009, at 19:58, Jay wrote: > >> What do you need them for? RTAllocator is there so one can allocate > > How do I get a typecode in C? > > Perhaps the attached is unnecessarily elaborate? > Or the new/dispose functions should be moved to Modula-3? > Or eliminated and the small number of callers can say NEW(ARRAY OF > CHAR, Uucontext.Size)? > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Tue, 3 Feb 2009 19:35:38 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) >> >> On 3 Feb 2009, at 19:07, Jay wrote: >> >>> >>> Sorry, fair enough. I don't think about safety much. >>> >>> al >>> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >>> RTUnsafeAllocator.i3? >>> And then the function names I had come up with MallocUninitialized, >>> MallocZeroed. >> >> What do you need them for? RTAllocator is there so one can allocate >> by typecode. I don't see the point of Malloc/Free. >> >>> Using array of char seems non-ideal to me somehow. >>> It seems like a "workaround". >>> It doesn't seem really any safer than not having a type at all. >>> I understand, the array, the type, does imply a size, and so I would >>> get some bounds checking against it, except I never access these >>> things anyway, I just pass them on to unsafe C code. >>> >>> >>> Related but tangential question, something I also didn't pay close >>> enough attention to: >>> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? >> >> The first is an explicit exception while the latter is implicit. >> >>> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >>> OutOfMemory directly? >> >> Because the exception is implicit. Any procedure can raise a >> RuntimeError. >> >>> >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> To: jkrell at elego.de >>>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>>> From: mika at async.caltech.edu >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Jay Krell writes: >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>>> RTAllocator.m3 >>>>> >>>>> Log message: >>>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>>> >>>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? >>>> Surely >>>> you can't have Free in a non-UNSAFE interface... >>>> >>>> Mika >>>> >>>>> introduce internal RTAlloc.MallocUninitialized >>>>> >>>>> These include Disable/EnableSwitching, and >>>>> raising exceptions upon failure. >>>>> (Disable/Enable only do something for user threads). > From martinbishop at bellsouth.net Tue Feb 3 20:22:06 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:22:06 -0600 Subject: [M3devel] Initialize array to zero? Message-ID: <4988995E.4040605@bellsouth.net> Quick question, is it possible to initialize an array to all zeros? I tried: VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; but I get errors...I also tried just {0} but that errors too. From martinbishop at bellsouth.net Tue Feb 3 20:45:12 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:45:12 -0600 Subject: [M3devel] Initialize array to zero? In-Reply-To: <4988995E.4040605@bellsouth.net> References: <4988995E.4040605@bellsouth.net> Message-ID: <49889EC8.8060103@bellsouth.net> Martin Bishop wrote: > Quick question, is it possible to initialize an array to all zeros? > > I tried: > > VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; > > but I get errors...I also tried just {0} but that errors too. > Never mind, I figured it out, it's {0, ..} :) From jay.krell at cornell.edu Tue Feb 3 23:05:51 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 22:05:51 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: > Hmm, yes, you are right that there is a possible alignment issue. I > am used to pthread_mutext_t being a simple reference. But surely in C > the type of the pthread_mutex_t struct would have appropriate > alignment padding anyway so as to allow allocation using malloc(sizeof > pthread_mutex_t)? So, it all should just work right? I think "the other way around" and same conclusion. malloc should return something "maximally aligned" so that pthread_mutex_t* x = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); works. pthread_mutex_t doesn't need the padding, malloc does, so to speak. Just as long as we don't have TYPE Foo = RECORD a: pthread_mutex_t; b: pthread_mutex_t; c: pthread_t; d: pthread_t; e: pthread_cond_t; f: pthread_cond_t; END; and such, ok. malloc on NT returns something with 2 * sizeof(void*) alignment. I think on Win9x only 4 alignment, thus there is _malloc_aligned for dealing with SSE stuff. Something like that. I didn't realize untraced allocations were basically just malloc but indeed they are. I'm still mulling over the possible deoptimizations here. I'm reluctant to increase heap allocations. - Jay From hosking at cs.purdue.edu Tue Feb 3 23:54:01 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 09:54:01 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> I suggest you come up with a proposal for us to look over before you change the code base for this. On 4 Feb 2009, at 09:05, Jay wrote: > >> Hmm, yes, you are right that there is a possible alignment issue. I >> am used to pthread_mutext_t being a simple reference. But surely in C >> the type of the pthread_mutex_t struct would have appropriate >> alignment padding anyway so as to allow allocation using >> malloc(sizeof >> pthread_mutex_t)? So, it all should just work right? > > > I think "the other way around" and same conclusion. > malloc should return something "maximally aligned" so that > > pthread_mutex_t* x = (pthread_mutex_t*) > malloc(sizeof(pthread_mutex_t)); > > > works. pthread_mutex_t doesn't need the padding, malloc does, so to > speak. > > > Just as long as we don't have > > > TYPE Foo = RECORD > a: pthread_mutex_t; > b: pthread_mutex_t; > c: pthread_t; > d: pthread_t; > e: pthread_cond_t; > f: pthread_cond_t; > END; > > > and such, ok. > > > malloc on NT returns something with 2 * sizeof(void*) alignment. > I think on Win9x only 4 alignment, thus there is _malloc_aligned for > dealing with SSE stuff. > Something like that. > > > I didn't realize untraced allocations were basically just malloc but > indeed they are. > > > I'm still mulling over the possible deoptimizations here. > I'm reluctant to increase heap allocations. > > > > - Jay From jay.krell at cornell.edu Wed Feb 4 01:06:24 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:06:24 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: There are a few possibilities: Roughly: Where there is INTERFACE Upthread; TYPE pthread_t = ... system specific ... pthread_cond_t = ... system specific ... pthread_mutex_t = ... system specific ... PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); MODULE PThread; VAR a: pthread_t; b: pthread_cond_t; c: pthread_mutex_t; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; change to: INTERFACE Upthread; TYPE pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type pthread_cond_t = RECORD END; ditto pthread_mutex_t = RECORD END; ditto PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); INTERFACE PThreadC.i3 PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; or possibly extern VAR PThreadC.c static pthread_t a = PTHREAD_INIT; static pthread_cond_t b = PTHREAD_COND_INIT; static pthread_mutex_t c = PTHREAD_MUTEX_INIT; pthread_t* GetA() { return &a; } pthread_cond_t* GetB() { return &b; } pthread_mutex_t* GetC() { return &c; } MODULE PThread; VAR a := PThreadC.GetA(); b := PThreadC.GetB(); c := PThreadC.GetA(); PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a^); Upthread.pthread_cond_init_or_whatever(b^); Upthread.pthread_mutex_init_or_whatever(c^); END Foo; or, again, possibly they are variables and it goes a little smaller/quicker: FROM UPthreadC IMPORT a, b, c; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; I think that is pretty cut and dry, no controversy. What is less clear is what to do with non-statically allocated variables. Let's say: MODULE PThread; TYPE T = RECORD a:int; b:pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T) BEGIN Upthread.init_or_whatever(t.b); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b); DISPOSE(t); END; The desire is something that does not know the size of pthread_t, something like: TYPE T = RECORD a:int; b:UNTRACED REF pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T); BEGIN t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) Upthread.init_or_whatever(t.b^); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b^); DISPOSE(t.b); DISPOSE(t); END; However that incurs an extra heap allocation, which is not great. In at least one place, the pointer-indirection-and-heap-allocation is already there so this isn't a deoptimization. However "reoptimizing" it might be nice. What I would prefer a pattern I often use in C -- merging allocations, something like, /assuming/ t is untraced, which I grant it might not be. And ensuring that BYTESIZE(T) is properly aligned: PROCEDURE CreateT():UNTRACED REF T= VAR p : ADDRESS; t : UNTRACED REF T; BEGIN (* Again I would prefer RTAllocator.MallocZeroed *) p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); t := LOOPHOLE(UNTRACED REF T, p); t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); Upthread.init_or_whatever(t.b^); RETURN t; END; That is -- opaque types, size not known at compile-time, but size known at runtime, and do not incur an extra heap allocation for lack of knowing sizes at compile-time. For the statically allocated variables I think there is no controversy. There might a tiny bit of overhead in the use, but it'd be very small, and possibly even removable in the future. I'd rather avoid the variables, as all writable data is to be avoided. Read only pages are better and all that, but ok.. However the value is mainly realized only if statically and dynamically allocated variables are handled. The result of this would be further reduction in platform-specificity when cloning C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 09:54:01 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I suggest you come up with a proposal for us to look over before you > change the code base for this. > > On 4 Feb 2009, at 09:05, Jay wrote: > >> >>> Hmm, yes, you are right that there is a possible alignment issue. I >>> am used to pthread_mutext_t being a simple reference. But surely in C >>> the type of the pthread_mutex_t struct would have appropriate >>> alignment padding anyway so as to allow allocation using >>> malloc(sizeof >>> pthread_mutex_t)? So, it all should just work right? >> >> >> I think "the other way around" and same conclusion. >> malloc should return something "maximally aligned" so that >> >> pthread_mutex_t* x = (pthread_mutex_t*) >> malloc(sizeof(pthread_mutex_t)); >> >> >> works. pthread_mutex_t doesn't need the padding, malloc does, so to >> speak. >> >> >> Just as long as we don't have >> >> >> TYPE Foo = RECORD >> a: pthread_mutex_t; >> b: pthread_mutex_t; >> c: pthread_t; >> d: pthread_t; >> e: pthread_cond_t; >> f: pthread_cond_t; >> END; >> >> >> and such, ok. >> >> >> malloc on NT returns something with 2 * sizeof(void*) alignment. >> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >> dealing with SSE stuff. >> Something like that. >> >> >> I didn't realize untraced allocations were basically just malloc but >> indeed they are. >> >> >> I'm still mulling over the possible deoptimizations here. >> I'm reluctant to increase heap allocations. >> >> >> >> - Jay > From jay.krell at cornell.edu Wed Feb 4 01:35:04 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:35:04 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: Addendum: if size <= BYTESIZE(ADDRESS), which is common, it is desirable to avoid the extra heap allocation and just use the space for the pointer. You end up with like: TYPE T = RECORD ... pthread: UNTRACED REF pthread_t END; PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t BEGIN IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); ELSE RETURN t.pthread; END GetPThread; - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 00:06:24 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation is already there > so this isn't a deoptimization. However "reoptimizing" it might be nice. > > > What I would prefer a pattern I often use in C -- merging allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at compile-time. > > > For the statically allocated variables I think there is no controversy. > There might a tiny bit of overhead in the use, but it'd be very small, and possibly > even removable in the future. I'd rather avoid the variables, as all writable > data is to be avoided. Read only pages are better and all that, but ok.. > > > However the value is mainly realized only if statically and dynamically allocated variables are handled. > > The result of this would be further reduction in platform-specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Wed Feb 4 02:50:41 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:50:41 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: You need to be careful here w.r. to traced heap allocation, since objects can move. It is not safe to return the address of any field of a traced object. On 4 Feb 2009, at 11:35, Jay wrote: > > Addendum: > if size <= BYTESIZE(ADDRESS), which is common, it is desirable to > avoid the extra heap allocation and just use the space for the > pointer. > > You end up with like: > > TYPE T = RECORD > ... > pthread: UNTRACED REF pthread_t > END; > > > PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t > BEGIN > IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) > RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); > ELSE > RETURN t.pthread; > END GetPThread; > > > - Jay > > > > > > > > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 00:06:24 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, but >> ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment >>>>> issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned >>>> for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc >>>> but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> From hosking at cs.purdue.edu Wed Feb 4 02:53:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:53:54 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: I am very leery of this proposal -- the code will be inherently opaque and unmaintainable. I don't see any advantage to it. On 4 Feb 2009, at 11:06, Jay wrote: > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque > preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/ > quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated > variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, > something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF > CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := > RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation > is already there > so this isn't a deoptimization. However "reoptimizing" it might be > nice. > > > What I would prefer a pattern I often use in C -- merging > allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + > BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size > known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at > compile-time. > > > For the statically allocated variables I think there is no > controversy. > There might a tiny bit of overhead in the use, but it'd be very > small, and possibly > even removable in the future. I'd rather avoid the variables, as > all writable > data is to be avoided. Read only pages are better and all that, > but ok.. > > > However the value is mainly realized only if statically and > dynamically allocated variables are handled. > > The result of this would be further reduction in platform- > specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new > platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely >>>> in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From martinbishop at bellsouth.net Wed Feb 4 04:51:33 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 21:51:33 -0600 Subject: [M3devel] opencm3 favicon Message-ID: <498910C5.6050902@bellsouth.net> A little off-topic maybe, but I though opencm3.net needed a favicon. I made 2 different ones: http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue square with a white 3, nice and simple. http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by giving the Modula-3 logo to some online favicon generator. Same as the first one really, only "zoomed in" looking. Feel free to use either one if you want. From wagner at elegosoft.com Wed Feb 4 08:05:07 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 08:05:07 +0100 Subject: [M3devel] tinderbox regression Message-ID: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> The build on LINUXLIBC6 fails: /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command not found ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory Fatal Error: incomplete program *** execution of cm3 -build -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? failed *** Mike, anything changed on birch since yesterday? Or a real M3 problem? One more test fails since yesterday: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 e020 e026 +e029 >>> 13 in test_m3tests 2009-02-03-02-31-01 today: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 r004 e020 e026 e029 >>> 14 in test_m3tests 2009-02-04-02-31-17 /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 It seems to be a runtest checking an error: r_test ("r0", "r004", "negative size for an open array") It's just the diff that fails because the line has changed: --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 @@ -3,6 +3,6 @@ *** *** runtime error: *** An enumeration or subrange value was out of range. -*** file "../src/runtime/common/RTAllocator.m3", line 309 +*** file "../src/runtime/common/RTAllocator.m3", line 307 *** Can anybody have a look? Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From michael.anderson at elego.de Wed Feb 4 09:33:56 2009 From: michael.anderson at elego.de (Michael Anderson) Date: Wed, 04 Feb 2009 09:33:56 +0100 Subject: [M3devel] tinderbox regression In-Reply-To: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> References: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> Message-ID: <20090204093356.r1r472b21sgkw4so@mail.elegosoft.com> Quoting Olaf Wagner : > The build on LINUXLIBC6 fails: > > /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command > not > found > ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory > Fatal Error: incomplete program > *** execution of cm3 -build > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? failed *** > > Mike, anything changed on birch since yesterday? Or a real M3 problem? Nothing that I'm aware of, except an apache redirect for the Subversion 1.6 news article, which just redirects a google link to the english page... I'll have a look around. > > One more test fails since yesterday: > > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > e020 e026 +e029 > >>> 13 in test_m3tests 2009-02-03-02-31-01 > > today: > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > r004 e020 e026 e029 > >>> 14 in test_m3tests 2009-02-04-02-31-17 > /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 > > It seems to be a runtest checking an error: > r_test ("r0", "r004", "negative size for an open array") > > It's just the diff that fails because the line has changed: > > --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 > +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 > @@ -3,6 +3,6 @@ > *** > *** runtime error: > *** An enumeration or subrange value was out of range. > -*** file "../src/runtime/common/RTAllocator.m3", line 309 > +*** file "../src/runtime/common/RTAllocator.m3", line 307 > *** > > Can anybody have a look? > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 10:42:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 09:42:12 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: It gains something, but maybe it isn't enough to be worthwhile. The issue is in the subjectivity. It would remove e.g. the following system-dependent lines: Linux: pthread_t = ADDRESS; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Linux/32: pthread_attr_t = ARRAY[1..9] OF INTEGER; pthread_mutex_t = ARRAY[1..6] OF INTEGER; Linux/64: pthread_attr_t = ARRAY[1..7] OF INTEGER; pthread_mutex_t = ARRAY[1..5] OF INTEGER; FreeBSD: pthread_t = ADDRESS; pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; HP-UX: (* trick from darwin-generic/Upthread.i3 *) X32 = ORD(BITSIZE(INTEGER) = 32); X64 = ORD(BITSIZE(INTEGER) = 64); pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Cygwin: pthread_t = ADDRESS; (* opaque *) pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Solaris: pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) Darwin: (only ppc32 currently) pthread_t = INTEGER; (* opaque *) pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (plus AIX, Irix, VMS, Tru64.) Another approach would be make them all ADDRESS and introduce a portable C layer of "varything thickness", using the same logic. It would look just like the native pthreads, but there'd be extra allocate/cleanup calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. The two layers would be clear and simple, the cost would be the same, but there would be the conceptual cost of two simple layers instead of one just one slightly complicated layer. Another approach is maybe make them all addresses on new platforms and introduce the C layer only on new platforms. Again, about the only change in the Modula-3 code is extra alloc/cleanup calls. And again, some/all of the code already has the indirection/heap allocation unconditionally. And again, maybe not worth it. I show all the system-dependent code, attempting to portray in its worst light by showing all of it, but maybe it's really not a lot. For the attr type, we can do something specific to its use. There is just one use, and we can address it with the following function written in C.. eh..I'll send a diff later tonight/this week I think. pthread_t and pthread_key_t always happen to be address-sized or smaller. Maybe just declare them both to be address and assert their size in some C code. That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. For example, we have: TYPE Activation = UNTRACED REF RECORD (* global doubly-linked, circular list of all active threads *) next, prev: Activation := NIL; (* LL = activeMu *) (* thread handle *) handle: pthread_t; (* LL = activeMu *) (* base of thread stack for use by GC *) stackbase: ADDRESS := NIL; (* LL = activeMu *) so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. Leaving only cond and mutex. Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. rwlock is a useful type though. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 12:53:54 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I am very leery of this proposal -- the code will be inherently opaque > and unmaintainable. I don't see any advantage to it. > > On 4 Feb 2009, at 11:06, Jay wrote: > >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, >> but ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> > From jay.krell at cornell.edu Wed Feb 4 11:14:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 10:14:12 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers Message-ID: The following eliminates the only use of pthread_attr_t from the cloned headers, slightly reducing the work to port to new platforms. It introduces a "small" "portable" C wrapper to encompass the files lines of Modula-3 that use pthread_attr_t. ok? Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.89 diff -u -r1.89 ThreadPThread.m3 --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 @@ -11,11 +11,10 @@ Unix, Utime, Word, Upthread, Usched, Uerror, ThreadPThreadC, Uexec; FROM Upthread -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, pthread_mutex_t, +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; FROM Compiler IMPORT ThisFile, ThisLine; FROM Ctypes IMPORT int; -FROM Utypes IMPORT size_t; FROM ThreadPThreadC IMPORT SIG_SUSPEND; (*----------------------------------------------------- types and globals ---*) @@ -561,9 +560,7 @@ VAR act := NEW(Activation); t := CreateT(act); - attr: pthread_attr_t; size := defaultStackSize; - bytes: size_t; BEGIN (* determine the initial size of the stack for this thread *) TYPECASE closure OF @@ -576,17 +573,12 @@ t.id := nextId; INC(nextId); IF perfOn THEN PerfChanged(t.id, State.alive) END; - WITH r = Upthread.attr_init(attr) DO END; - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; - bytes := MAX(bytes, size * ADRSIZE(Word.T)); - EVAL Upthread.attr_setstacksize(attr, bytes); act.next := allThreads; act.prev := allThreads.prev; act.size := size; allThreads.prev.next := act; allThreads.prev := act; - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO - EVAL Upthread.attr_destroy(attr); + WITH r = ThreadPThreadC.thread_create(act.handle, size * ADRSIZE(Word.T), ThreadBase, act) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: Fork failed with error: ", r); Index: ThreadPThreadC.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.c,v retrieving revision 1.8 diff -u -r1.8 ThreadPThreadC.c --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 @@ -14,6 +14,7 @@ #include #include #endif +#include #ifdef __cplusplus extern "C" { @@ -145,6 +146,32 @@ #endif } +#define VAR(t) t* +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) +typedef void* (*start_routine_t)(void*); + +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t stackSize, start_routine_t start_routine, void* arg) +{ + int r; + size_t bytes; + pthread_attr_t attr; + + r = pthread_attr_init(&attr); + assert(r == 0); + + r = pthread_attr_getstacksize(&attr, &bytes); + assert(r == 0); + + bytes = MAX(bytes, stackSize); + pthread_attr_setstacksize(&attr, bytes); + + r = pthread_create(pthread, &attr, start_routine, arg); + + pthread_attr_destroy(&attr); + + return r; +} + #ifdef __cplusplus } /* extern "C" */ #endif Index: ThreadPThreadC.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.i3,v retrieving revision 1.5 diff -u -r1.5 ThreadPThreadC.i3 --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 @@ -7,6 +7,8 @@ UNSAFE INTERFACE ThreadPThreadC; FROM Ctypes IMPORT int; +FROM Cstddef IMPORT size_t; +FROM Upthread IMPORT pthread_t, start_routine_t; (*---------------------------------------------------------------------------*) @@ -38,4 +40,11 @@ (*---------------------------------------------------------------------------*) +(* pthread_create but replace attr with stackSize so that attr need not be known to Modula-3 *) + + +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; start_routine: start_routine_t; arg: ADDRESS): int; + +(*---------------------------------------------------------------------------*) + END ThreadPThreadC. The corrolary then, ignoring the "cloned headers" that I leave alone, is: Index: Common/Upthread.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v retrieving revision 1.3 diff -u -r1.3 Upthread.i3 --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 @@ -10,7 +10,6 @@ TYPE pthread_t = Usysdep.pthread_t; - pthread_attr_t = Usysdep.pthread_attr_t; pthread_mutex_t = Usysdep.pthread_mutex_t; pthread_cond_t = Usysdep.pthread_cond_t; pthread_key_t = Usysdep.pthread_key_t; @@ -21,14 +20,9 @@ VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; PROCEDURE detach (thread: pthread_t): int; PROCEDURE self (): pthread_t; PROCEDURE equal (t1, t2: pthread_t): int; - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR stacksize: size_t): int; - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: size_t): int; PROCEDURE yield (): int; PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := NIL): int; PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; Index: cygwin/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v retrieving revision 1.12 diff -u -r1.12 Usysdep.i3 --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -28,7 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *) - pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Index: darwin-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,v retrieving revision 1.2 diff -u -r1.2 Usysdep.i3 --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -20,7 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *) - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) Index: freebsd-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,v retrieving revision 1.5 diff -u -r1.5 Usysdep.i3 --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -22,7 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; Index: hpux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/Usysdep.i3,v retrieving revision 1.4 diff -u -r1.4 Usysdep.i3 --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -25,7 +25,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Index: linux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,v retrieving revision 1.10 diff -u -r1.10 Usysdep.i3 --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -21,7 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = Upthreadtypes.pthread_attr_t; pthread_mutex_t = Upthreadtypes.pthread_mutex_t; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Index: solaris-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,v retrieving revision 1.3 diff -u -r1.3 Usysdep.i3 --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -24,7 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) From hosking at cs.purdue.edu Wed Feb 4 11:24:19 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 21:24:19 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: Message-ID: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> ok On 4 Feb 2009, at 21:14, Jay wrote: > > The following eliminates the only use of pthread_attr_t from the > cloned headers, slightly reducing the work to port to new platforms. > It introduces a "small" "portable" C wrapper to encompass the files > lines of Modula-3 that use pthread_attr_t. ok? > > > Index: ThreadPThread.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThread.m3,v > retrieving revision 1.89 > diff -u -r1.89 ThreadPThread.m3 > --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 > +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 > @@ -11,11 +11,10 @@ > Unix, Utime, Word, Upthread, Usched, > Uerror, ThreadPThreadC, Uexec; > FROM Upthread > -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, > pthread_mutex_t, > +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, > PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; > FROM Compiler IMPORT ThisFile, ThisLine; > FROM Ctypes IMPORT int; > -FROM Utypes IMPORT size_t; > FROM ThreadPThreadC IMPORT SIG_SUSPEND; > > (*----------------------------------------------------- types and > globals ---*) > @@ -561,9 +560,7 @@ > VAR > act := NEW(Activation); > t := CreateT(act); > - attr: pthread_attr_t; > size := defaultStackSize; > - bytes: size_t; > BEGIN > (* determine the initial size of the stack for this thread *) > TYPECASE closure OF > @@ -576,17 +573,12 @@ > t.id := nextId; INC(nextId); > IF perfOn THEN PerfChanged(t.id, State.alive) END; > > - WITH r = Upthread.attr_init(attr) DO END; > - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; > - bytes := MAX(bytes, size * ADRSIZE(Word.T)); > - EVAL Upthread.attr_setstacksize(attr, bytes); > act.next := allThreads; > act.prev := allThreads.prev; > act.size := size; > allThreads.prev.next := act; > allThreads.prev := act; > - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO > - EVAL Upthread.attr_destroy(attr); > + WITH r = ThreadPThreadC.thread_create(act.handle, size * > ADRSIZE(Word.T), ThreadBase, act) DO > IF r # 0 THEN > RTError.MsgI(ThisFile(), ThisLine(), > "Thread client error: Fork failed with error: > ", r); > Index: ThreadPThreadC.c > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.c,v > retrieving revision 1.8 > diff -u -r1.8 ThreadPThreadC.c > --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 > +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 > @@ -14,6 +14,7 @@ > #include > #include > #endif > +#include > > #ifdef __cplusplus > extern "C" { > @@ -145,6 +146,32 @@ > #endif > } > > +#define VAR(t) t* > +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) > +typedef void* (*start_routine_t)(void*); > + > +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t > stackSize, start_routine_t start_routine, void* arg) > +{ > + int r; > + size_t bytes; > + pthread_attr_t attr; > + > + r = pthread_attr_init(&attr); > + assert(r == 0); > + > + r = pthread_attr_getstacksize(&attr, &bytes); > + assert(r == 0); > + > + bytes = MAX(bytes, stackSize); > + pthread_attr_setstacksize(&attr, bytes); > + > + r = pthread_create(pthread, &attr, start_routine, arg); > + > + pthread_attr_destroy(&attr); > + > + return r; > +} > + > #ifdef __cplusplus > } /* extern "C" */ > #endif > Index: ThreadPThreadC.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.i3,v > retrieving revision 1.5 > diff -u -r1.5 ThreadPThreadC.i3 > --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 > +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 > @@ -7,6 +7,8 @@ > UNSAFE INTERFACE ThreadPThreadC; > > FROM Ctypes IMPORT int; > +FROM Cstddef IMPORT size_t; > +FROM Upthread IMPORT pthread_t, start_routine_t; > > (*---------------------------------------------------------------------------*) > > @@ -38,4 +40,11 @@ > > (*---------------------------------------------------------------------------*) > > +(* pthread_create but replace attr with stackSize so that attr need > not be known to Modula-3 *) > + > + > +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; > start_routine: start_routine_t; arg: ADDRESS): int; > + > + > (*---------------------------------------------------------------------------*) > + > END ThreadPThreadC. > > > > > > The corrolary then, ignoring the "cloned headers" that I leave > alone, is: > > > Index: Common/Upthread.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v > retrieving revision 1.3 > diff -u -r1.3 Upthread.i3 > --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 > +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 > @@ -10,7 +10,6 @@ > > TYPE > pthread_t = Usysdep.pthread_t; > - pthread_attr_t = Usysdep.pthread_attr_t; > pthread_mutex_t = Usysdep.pthread_mutex_t; > pthread_cond_t = Usysdep.pthread_cond_t; > pthread_key_t = Usysdep.pthread_key_t; > @@ -21,14 +20,9 @@ > VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; > VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; > > - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: > pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; > PROCEDURE detach (thread: pthread_t): int; > PROCEDURE self (): pthread_t; > PROCEDURE equal (t1, t2: pthread_t): int; > - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR > stacksize: size_t): int; > - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: > size_t): int; > PROCEDURE yield (): int; > PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := > NIL): int; > PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; > Index: cygwin/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v > retrieving revision 1.12 > diff -u -r1.12 Usysdep.i3 > --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 > +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -28,7 +28,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; (* opaque *) > - pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > Index: darwin-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ > Usysdep.i3,v > retrieving revision 1.2 > diff -u -r1.2 Usysdep.i3 > --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 > +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -20,7 +20,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = INTEGER; (* opaque *) > - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > Index: freebsd-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ > Usysdep.i3,v > retrieving revision 1.5 > diff -u -r1.5 Usysdep.i3 > --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 > +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -22,7 +22,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > Index: hpux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ > Usysdep.i3,v > retrieving revision 1.4 > diff -u -r1.4 Usysdep.i3 > --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 > +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -25,7 +25,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] > OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF > INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > Index: linux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ > Usysdep.i3,v > retrieving revision 1.10 > diff -u -r1.10 Usysdep.i3 > --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 > +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -21,7 +21,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = Upthreadtypes.pthread_attr_t; > pthread_mutex_t = Upthreadtypes.pthread_mutex_t; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > Index: solaris-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ > Usysdep.i3,v > retrieving revision 1.3 > diff -u -r1.3 Usysdep.i3 > --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 > +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -24,7 +24,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; > (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* > 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) From wagner at elegosoft.com Wed Feb 4 17:38:11 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 17:38:11 +0100 Subject: [M3devel] opencm3 favicon In-Reply-To: <498910C5.6050902@bellsouth.net> References: <498910C5.6050902@bellsouth.net> Message-ID: <20090204173811.6g9osjhs4go8sokw@mail.elegosoft.com> Quoting Martin Bishop : > A little off-topic maybe, but I though opencm3.net needed a favicon. > > I made 2 different ones: > > http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue > square with a white 3, nice and simple. > > http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by > giving the Modula-3 logo to some online favicon generator. Same as the > first one really, only "zoomed in" looking. > > Feel free to use either one if you want. If there are no objections or strong feelings about this or one or the other icon, we can simply place one (the first?) onto our web server. I'd suggest to wait for replies one more day, and then Mike can install it. So speak up now, or be silent forever :-) Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 23:01:58 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:01:58 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html can fail for lack of memory. The use should probably be modified somewhat therefore. e.g. at least: C code: r = pthread_attr_init(...) if (r == ENOMEM) return r; assert(r == 0); Modula-3 code: r = ... IF r = Cerrno.ENOMEM raise out of memory or more generally probably: C: r = pthread_attr_init(...) if (r != 0) return r; Modula-3: r = ... IF r # 0 raise it as is done for errno, whatever or even C: void thread_create(...) { r = pthread_attr_init(...) if (r != 0) raise it as errno, whatever just that I'm a little leary of "certain Modula-3 constructs in C". I'll maybe review more code along these lines. I gather the general gist of things in Modula-3 though is that out of memory is fatal anyway. Raising an exception vs. failing an assertion probably not significantly different if the exception is not meant to be caught and isn't ever caught. (Strange though then the gymnastics I pointed out elsewhere converting one form of out of memory to another form..) The docs also point out that pthread_attr can be reused. It might be reasonable to try to do that somewhat, though of course there are the usual caveats: - how many reusable objects to keep around I suggest 1, for the common case of either using the default or repeatedly using the same non-default. - how to lookup, insert, delete in the cache, in an efficient and thread-safe manner cache size = 1 helps, but doesn't address all questions. I'll leave it alone, unless someone "vehemently agrees". Expect the original change fairly soon.. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 21:24:19 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers > > ok > > On 4 Feb 2009, at 21:14, Jay wrote: > >> >> The following eliminates the only use of pthread_attr_t from the >> cloned headers, slightly reducing the work to port to new platforms. >> It introduces a "small" "portable" C wrapper to encompass the files >> lines of Modula-3 that use pthread_attr_t. ok? >> >> >> Index: ThreadPThread.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThread.m3,v >> retrieving revision 1.89 >> diff -u -r1.89 ThreadPThread.m3 >> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >> @@ -11,11 +11,10 @@ >> Unix, Utime, Word, Upthread, Usched, >> Uerror, ThreadPThreadC, Uexec; >> FROM Upthread >> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >> pthread_mutex_t, >> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >> FROM Compiler IMPORT ThisFile, ThisLine; >> FROM Ctypes IMPORT int; >> -FROM Utypes IMPORT size_t; >> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >> >> (*----------------------------------------------------- types and >> globals ---*) >> @@ -561,9 +560,7 @@ >> VAR >> act := NEW(Activation); >> t := CreateT(act); >> - attr: pthread_attr_t; >> size := defaultStackSize; >> - bytes: size_t; >> BEGIN >> (* determine the initial size of the stack for this thread *) >> TYPECASE closure OF >> @@ -576,17 +573,12 @@ >> t.id := nextId; INC(nextId); >> IF perfOn THEN PerfChanged(t.id, State.alive) END; >> >> - WITH r = Upthread.attr_init(attr) DO END; >> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >> - EVAL Upthread.attr_setstacksize(attr, bytes); >> act.next := allThreads; >> act.prev := allThreads.prev; >> act.size := size; >> allThreads.prev.next := act; >> allThreads.prev := act; >> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >> - EVAL Upthread.attr_destroy(attr); >> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >> ADRSIZE(Word.T), ThreadBase, act) DO >> IF r # 0 THEN >> RTError.MsgI(ThisFile(), ThisLine(), >> "Thread client error: Fork failed with error: >> ", r); >> Index: ThreadPThreadC.c >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.c,v >> retrieving revision 1.8 >> diff -u -r1.8 ThreadPThreadC.c >> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >> @@ -14,6 +14,7 @@ >> #include >> #include >> #endif >> +#include >> >> #ifdef __cplusplus >> extern "C" { >> @@ -145,6 +146,32 @@ >> #endif >> } >> >> +#define VAR(t) t* >> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >> +typedef void* (*start_routine_t)(void*); >> + >> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >> stackSize, start_routine_t start_routine, void* arg) >> +{ >> + int r; >> + size_t bytes; >> + pthread_attr_t attr; >> + >> + r = pthread_attr_init(&attr); >> + assert(r == 0); >> + >> + r = pthread_attr_getstacksize(&attr, &bytes); >> + assert(r == 0); >> + >> + bytes = MAX(bytes, stackSize); >> + pthread_attr_setstacksize(&attr, bytes); >> + >> + r = pthread_create(pthread, &attr, start_routine, arg); >> + >> + pthread_attr_destroy(&attr); >> + >> + return r; >> +} >> + >> #ifdef __cplusplus >> } /* extern "C" */ >> #endif >> Index: ThreadPThreadC.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 ThreadPThreadC.i3 >> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >> @@ -7,6 +7,8 @@ >> UNSAFE INTERFACE ThreadPThreadC; >> >> FROM Ctypes IMPORT int; >> +FROM Cstddef IMPORT size_t; >> +FROM Upthread IMPORT pthread_t, start_routine_t; >> >> (*---------------------------------------------------------------------------*) >> >> @@ -38,4 +40,11 @@ >> >> (*---------------------------------------------------------------------------*) >> >> +(* pthread_create but replace attr with stackSize so that attr need >> not be known to Modula-3 *) >> + >> + >> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >> start_routine: start_routine_t; arg: ADDRESS): int; >> + >> + >> (*---------------------------------------------------------------------------*) >> + >> END ThreadPThreadC. >> >> >> >> >> >> The corrolary then, ignoring the "cloned headers" that I leave >> alone, is: >> >> >> Index: Common/Upthread.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Upthread.i3 >> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >> @@ -10,7 +10,6 @@ >> >> TYPE >> pthread_t = Usysdep.pthread_t; >> - pthread_attr_t = Usysdep.pthread_attr_t; >> pthread_mutex_t = Usysdep.pthread_mutex_t; >> pthread_cond_t = Usysdep.pthread_cond_t; >> pthread_key_t = Usysdep.pthread_key_t; >> @@ -21,14 +20,9 @@ >> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >> >> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >> PROCEDURE detach (thread: pthread_t): int; >> PROCEDURE self (): pthread_t; >> PROCEDURE equal (t1, t2: pthread_t): int; >> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >> stacksize: size_t): int; >> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >> size_t): int; >> PROCEDURE yield (): int; >> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >> NIL): int; >> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >> Index: cygwin/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >> retrieving revision 1.12 >> diff -u -r1.12 Usysdep.i3 >> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -28,7 +28,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; (* opaque *) >> - pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> Index: darwin-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >> Usysdep.i3,v >> retrieving revision 1.2 >> diff -u -r1.2 Usysdep.i3 >> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -20,7 +20,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = INTEGER; (* opaque *) >> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> Index: freebsd-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >> Usysdep.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 Usysdep.i3 >> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -22,7 +22,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> Index: hpux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >> Usysdep.i3,v >> retrieving revision 1.4 >> diff -u -r1.4 Usysdep.i3 >> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -25,7 +25,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> Index: linux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >> Usysdep.i3,v >> retrieving revision 1.10 >> diff -u -r1.10 Usysdep.i3 >> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -21,7 +21,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> Index: solaris-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >> Usysdep.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Usysdep.i3 >> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -24,7 +24,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >> (* 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >> 16 bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) > From jay.krell at cornell.edu Wed Feb 4 23:11:52 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:11:52 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. The entire proposal or the optimizations? The original unoptimized proposal seems like a small change mostly. I checked and the indirection/heap allocation is already there for cond and mutex, but not for pthread_t itself. Factoring out the size I think is a small change. On the other hand, we can also optimize it, pretty much locking in the platform-specificity. It's a tough decision to me. I don't mind the deoptimizations of const-to-var, or adding some function calls, but heap allocs imho are among the things to definitely avoid if not needed. These are untraced as well, so the argument that Modula-3 heap alloc is efficient doesn't apply. One caveat that bothers me though is, like with sem_t, I don't want to have types that are declared "incorrectly". I'd like types that you can only have references too. Probably in that case "give up", declare them as ADDRESS, losing the type safety -- pthread_cond_foo could take a mutex_t and no compilation error. The idea of making them all ADDRESS and adding C functions to alloc/cleanup is also good imho. That allows for one of the optimized forms -- not where the space is at the end of the Thread.T, but where the ADDRESS field is the data itself. I got hung up on pthread_attr_t here because it was efficiently stack allocated and this proposal would have really deoptimized that. The C code I showed avoids that though. Albeit only in the face of creating a thread -- an extra heap allocation per thread create probably not a big deal. Clearly I'm ambivalent. Later, - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 09:42:12 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > It gains something, but maybe it isn't enough > to be worthwhile. The issue is in the subjectivity. > > > It would remove e.g. the following system-dependent lines: > > > Linux: > pthread_t = ADDRESS; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > > > Linux/32: > pthread_attr_t = ARRAY[1..9] OF INTEGER; > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Linux/64: > pthread_attr_t = ARRAY[1..7] OF INTEGER; > pthread_mutex_t = ARRAY[1..5] OF INTEGER; > > > FreeBSD: > pthread_t = ADDRESS; > pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > > > HP-UX: > (* trick from darwin-generic/Upthread.i3 *) > X32 = ORD(BITSIZE(INTEGER) = 32); > X64 = ORD(BITSIZE(INTEGER) = 64); > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Cygwin: > pthread_t = ADDRESS; (* opaque *) > pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > > > Solaris: > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Darwin: (only ppc32 currently) > pthread_t = INTEGER; (* opaque *) > pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > > > (plus AIX, Irix, VMS, Tru64.) > > > Another approach would be make them all ADDRESS and introduce a portable > C layer of "varything thickness", using the same logic. > It would look just like the native pthreads, but there'd be extra allocate/cleanup > calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. > The two layers would be clear and simple, the cost would be the same, > but there would be the conceptual cost of two simple layers instead of one > just one slightly complicated layer. > > > Another approach is maybe make them all addresses on new platforms and introduce > the C layer only on new platforms. Again, about the only change in the Modula-3 > code is extra alloc/cleanup calls. > > > And again, some/all of the code already has the indirection/heap allocation unconditionally. > > > And again, maybe not worth it. I show all the system-dependent code, attempting > to portray in its worst light by showing all of it, but maybe it's really not a lot. > > > For the attr type, we can do something specific to its use. > There is just one use, and we can address it with the following function written in C.. > eh..I'll send a diff later tonight/this week I think. > > > pthread_t and pthread_key_t always happen to be address-sized or smaller. > Maybe just declare them both to be address and assert their size in some C code. > That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. > > For example, we have: > > > TYPE > Activation = UNTRACED REF RECORD > (* global doubly-linked, circular list of all active threads *) > next, prev: Activation := NIL; (* LL = activeMu *) > (* thread handle *) > handle: pthread_t; (* LL = activeMu *) > (* base of thread stack for use by GC *) > stackbase: ADDRESS := NIL; (* LL = activeMu *) > > > so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. > There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. > > > Leaving only cond and mutex. > Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. > rwlock is a useful type though. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 12:53:54 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. >> >> On 4 Feb 2009, at 11:06, Jay wrote: >> >>> >>> There are a few possibilities: >>> >>> >>> Roughly: >>> >>> Where there is >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = ... system specific ... >>> pthread_cond_t = ... system specific ... >>> pthread_mutex_t = ... system specific ... >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> MODULE PThread; >>> VAR >>> a: pthread_t; >>> b: pthread_cond_t; >>> c: pthread_mutex_t; >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> change to: >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = RECORD END; or whatever is correct for an opaque >>> preferably unique type >>> pthread_cond_t = RECORD END; ditto >>> pthread_mutex_t = RECORD END; ditto >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> >>> INTERFACE PThreadC.i3 >>> >>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>> >>> or possibly extern VAR >>> >>> PThreadC.c >>> >>> static pthread_t a = PTHREAD_INIT; >>> static pthread_cond_t b = PTHREAD_COND_INIT; >>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>> >>> pthread_t* GetA() { return &a; } >>> >>> pthread_cond_t* GetB() { return &b; } >>> >>> pthread_mutex_t* GetC() { return &c; } >>> >>> MODULE PThread; >>> VAR >>> a := PThreadC.GetA(); >>> b := PThreadC.GetB(); >>> c := PThreadC.GetA(); >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a^); >>> Upthread.pthread_cond_init_or_whatever(b^); >>> Upthread.pthread_mutex_init_or_whatever(c^); >>> END Foo; >>> >>> or, again, possibly they are variables and it goes a little smaller/ >>> quicker: >>> >>> FROM UPthreadC IMPORT a, b, c; >>> >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> I think that is pretty cut and dry, no controversy. >>> >>> What is less clear is what to do with non-statically allocated >>> variables. >>> >>> Let's say: >>> >>> MODULE PThread; >>> >>> TYPE T = RECORD >>> a:int; >>> b:pthread_t; >>> END; >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T) >>> BEGIN >>> Upthread.init_or_whatever(t.b); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b); >>> DISPOSE(t); >>> END; >>> >>> The desire is something that does not know the size of pthread_t, >>> something like: >>> >>> TYPE T = RECORD >>> a:int; >>> b:UNTRACED REF pthread_t; >>> END; >>> >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T); >>> BEGIN >>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>> CHAR, Upthread.pthread_t_size)); >>> (* Though I really wanted t.b := >>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b^); >>> DISPOSE(t.b); >>> DISPOSE(t); >>> END; >>> >>> >>> However that incurs an extra heap allocation, which is not great. >>> In at least one place, the pointer-indirection-and-heap-allocation >>> is already there >>> so this isn't a deoptimization. However "reoptimizing" it might be >>> nice. >>> >>> >>> What I would prefer a pattern I often use in C -- merging >>> allocations, something like, >>> /assuming/ t is untraced, which I grant it might not be. >>> >>> >>> And ensuring that BYTESIZE(T) is properly aligned: >>> >>> >>> PROCEDURE CreateT():UNTRACED REF T= >>> VAR >>> p : ADDRESS; >>> t : UNTRACED REF T; >>> BEGIN >>> (* Again I would prefer RTAllocator.MallocZeroed *) >>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>> BYTESIZE(T))); >>> t := LOOPHOLE(UNTRACED REF T, p); >>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> >>> That is -- opaque types, size not known at compile-time, but size >>> known at runtime, and >>> do not incur an extra heap allocation for lack of knowing sizes at >>> compile-time. >>> >>> >>> For the statically allocated variables I think there is no >>> controversy. >>> There might a tiny bit of overhead in the use, but it'd be very >>> small, and possibly >>> even removable in the future. I'd rather avoid the variables, as >>> all writable >>> data is to be avoided. Read only pages are better and all that, >>> but ok.. >>> >>> >>> However the value is mainly realized only if statically and >>> dynamically allocated variables are handled. >>> >>> The result of this would be further reduction in platform- >>> specificity when cloning >>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>> platforms. >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jay.krell at cornell.edu >>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>>> >>>> I suggest you come up with a proposal for us to look over before you >>>> change the code base for this. >>>> >>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>> >>>>> >>>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>> in C >>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>> alignment padding anyway so as to allow allocation using >>>>>> malloc(sizeof >>>>>> pthread_mutex_t)? So, it all should just work right? >>>>> >>>>> >>>>> I think "the other way around" and same conclusion. >>>>> malloc should return something "maximally aligned" so that >>>>> >>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>> malloc(sizeof(pthread_mutex_t)); >>>>> >>>>> >>>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>>> speak. >>>>> >>>>> >>>>> Just as long as we don't have >>>>> >>>>> >>>>> TYPE Foo = RECORD >>>>> a: pthread_mutex_t; >>>>> b: pthread_mutex_t; >>>>> c: pthread_t; >>>>> d: pthread_t; >>>>> e: pthread_cond_t; >>>>> f: pthread_cond_t; >>>>> END; >>>>> >>>>> >>>>> and such, ok. >>>>> >>>>> >>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>>> dealing with SSE stuff. >>>>> Something like that. >>>>> >>>>> >>>>> I didn't realize untraced allocations were basically just malloc but >>>>> indeed they are. >>>>> >>>>> >>>>> I'm still mulling over the possible deoptimizations here. >>>>> I'm reluctant to increase heap allocations. >>>>> >>>>> >>>>> >>>>> - Jay >>>> >> From hosking at cs.purdue.edu Thu Feb 5 00:12:18 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:12:18 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: I don't mind if low-level C calls abort rather than raising an exception. Especially, OutOfMemory, which it is unlikely one can recover from with an untraced allocation, unless perhaps a GC can be called to free up space. However, right now, the GC does not return pages to the OS, so the whole question is moot for now. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 5 Feb 2009, at 09:01, Jay wrote: > > http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html > > > can fail for lack of memory. > > > The use should probably be modified somewhat therefore. > > > e.g. at least: > > > C code: > > > r = pthread_attr_init(...) > if (r == ENOMEM) > return r; > assert(r == 0); > > > Modula-3 code: > r = ... > IF r = Cerrno.ENOMEM > raise out of memory > > > or more generally probably: > > > C: > > > r = pthread_attr_init(...) > if (r != 0) > return r; > > > Modula-3: > r = ... > IF r # 0 > raise it as is done for errno, whatever > > > or even C: > > > void thread_create(...) > { > r = pthread_attr_init(...) > if (r != 0) > raise it as errno, whatever > > > just that I'm a little leary of "certain Modula-3 constructs in C". > > > I'll maybe review more code along these lines. > I gather the general gist of things in Modula-3 though > is that out of memory is fatal anyway. Raising an exception > vs. failing an assertion probably not significantly different > if the exception is not meant to be caught and isn't ever caught. > (Strange though then the gymnastics I pointed out elsewhere > converting one form of out of memory to another form..) > > > The docs also point out that pthread_attr can be reused. > It might be reasonable to try to do that somewhat, though > of course there are the usual caveats: > > > - how many reusable objects to keep around > I suggest 1, for the common case of either using the default > or repeatedly using the same non-default. > - how to lookup, insert, delete in the cache, in an efficient > and thread-safe manner > cache size = 1 helps, but doesn't address all questions. > > > I'll leave it alone, unless someone "vehemently agrees". > > > Expect the original change fairly soon.. > > > - Jay > > > > > > > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 21:24:19 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers >> >> ok >> >> On 4 Feb 2009, at 21:14, Jay wrote: >> >>> >>> The following eliminates the only use of pthread_attr_t from the >>> cloned headers, slightly reducing the work to port to new platforms. >>> It introduces a "small" "portable" C wrapper to encompass the files >>> lines of Modula-3 that use pthread_attr_t. ok? >>> >>> >>> Index: ThreadPThread.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThread.m3,v >>> retrieving revision 1.89 >>> diff -u -r1.89 ThreadPThread.m3 >>> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >>> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >>> @@ -11,11 +11,10 @@ >>> Unix, Utime, Word, Upthread, Usched, >>> Uerror, ThreadPThreadC, Uexec; >>> FROM Upthread >>> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >>> pthread_mutex_t, >>> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >>> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >>> FROM Compiler IMPORT ThisFile, ThisLine; >>> FROM Ctypes IMPORT int; >>> -FROM Utypes IMPORT size_t; >>> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >>> >>> (*----------------------------------------------------- types and >>> globals ---*) >>> @@ -561,9 +560,7 @@ >>> VAR >>> act := NEW(Activation); >>> t := CreateT(act); >>> - attr: pthread_attr_t; >>> size := defaultStackSize; >>> - bytes: size_t; >>> BEGIN >>> (* determine the initial size of the stack for this thread *) >>> TYPECASE closure OF >>> @@ -576,17 +573,12 @@ >>> t.id := nextId; INC(nextId); >>> IF perfOn THEN PerfChanged(t.id, State.alive) END; >>> >>> - WITH r = Upthread.attr_init(attr) DO END; >>> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >>> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >>> - EVAL Upthread.attr_setstacksize(attr, bytes); >>> act.next := allThreads; >>> act.prev := allThreads.prev; >>> act.size := size; >>> allThreads.prev.next := act; >>> allThreads.prev := act; >>> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >>> - EVAL Upthread.attr_destroy(attr); >>> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >>> ADRSIZE(Word.T), ThreadBase, act) DO >>> IF r # 0 THEN >>> RTError.MsgI(ThisFile(), ThisLine(), >>> "Thread client error: Fork failed with error: >>> ", r); >>> Index: ThreadPThreadC.c >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.c,v >>> retrieving revision 1.8 >>> diff -u -r1.8 ThreadPThreadC.c >>> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >>> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >>> @@ -14,6 +14,7 @@ >>> #include >>> #include >>> #endif >>> +#include >>> >>> #ifdef __cplusplus >>> extern "C" { >>> @@ -145,6 +146,32 @@ >>> #endif >>> } >>> >>> +#define VAR(t) t* >>> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >>> +typedef void* (*start_routine_t)(void*); >>> + >>> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >>> stackSize, start_routine_t start_routine, void* arg) >>> +{ >>> + int r; >>> + size_t bytes; >>> + pthread_attr_t attr; >>> + >>> + r = pthread_attr_init(&attr); >>> + assert(r == 0); >>> + >>> + r = pthread_attr_getstacksize(&attr, &bytes); >>> + assert(r == 0); >>> + >>> + bytes = MAX(bytes, stackSize); >>> + pthread_attr_setstacksize(&attr, bytes); >>> + >>> + r = pthread_create(pthread, &attr, start_routine, arg); >>> + >>> + pthread_attr_destroy(&attr); >>> + >>> + return r; >>> +} >>> + >>> #ifdef __cplusplus >>> } /* extern "C" */ >>> #endif >>> Index: ThreadPThreadC.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 ThreadPThreadC.i3 >>> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >>> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >>> @@ -7,6 +7,8 @@ >>> UNSAFE INTERFACE ThreadPThreadC; >>> >>> FROM Ctypes IMPORT int; >>> +FROM Cstddef IMPORT size_t; >>> +FROM Upthread IMPORT pthread_t, start_routine_t; >>> >>> (*---------------------------------------------------------------------------*) >>> >>> @@ -38,4 +40,11 @@ >>> >>> (*---------------------------------------------------------------------------*) >>> >>> +(* pthread_create but replace attr with stackSize so that attr need >>> not be known to Modula-3 *) >>> + >>> + >>> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >>> start_routine: start_routine_t; arg: ADDRESS): int; >>> + >>> + >>> (*---------------------------------------------------------------------------*) >>> + >>> END ThreadPThreadC. >>> >>> >>> >>> >>> >>> The corrolary then, ignoring the "cloned headers" that I leave >>> alone, is: >>> >>> >>> Index: Common/Upthread.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Upthread.i3 >>> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >>> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -10,7 +10,6 @@ >>> >>> TYPE >>> pthread_t = Usysdep.pthread_t; >>> - pthread_attr_t = Usysdep.pthread_attr_t; >>> pthread_mutex_t = Usysdep.pthread_mutex_t; >>> pthread_cond_t = Usysdep.pthread_cond_t; >>> pthread_key_t = Usysdep.pthread_key_t; >>> @@ -21,14 +20,9 @@ >>> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >>> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >>> >>> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >>> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >>> PROCEDURE detach (thread: pthread_t): int; >>> PROCEDURE self (): pthread_t; >>> PROCEDURE equal (t1, t2: pthread_t): int; >>> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >>> stacksize: size_t): int; >>> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >>> size_t): int; >>> PROCEDURE yield (): int; >>> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >>> NIL): int; >>> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >>> Index: cygwin/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >>> retrieving revision 1.12 >>> diff -u -r1.12 Usysdep.i3 >>> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >>> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -28,7 +28,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; (* opaque *) >>> - pthread_attr_t = ADDRESS; (* opaque *) >>> pthread_mutex_t = ADDRESS; (* opaque *) >>> pthread_cond_t = ADDRESS; (* opaque *) >>> pthread_key_t = ADDRESS; (* opaque *) >>> Index: darwin-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >>> Usysdep.i3,v >>> retrieving revision 1.2 >>> diff -u -r1.2 Usysdep.i3 >>> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >>> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -20,7 +20,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = INTEGER; (* opaque *) >>> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >>> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >>> pthread_key_t = INTEGER; (* opaque *) >>> Index: freebsd-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >>> Usysdep.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 Usysdep.i3 >>> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >>> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -22,7 +22,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = ADDRESS; >>> pthread_mutex_t = ADDRESS; >>> pthread_cond_t = ADDRESS; >>> pthread_key_t = int; >>> Index: hpux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.4 >>> diff -u -r1.4 Usysdep.i3 >>> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >>> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -25,7 +25,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >>> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >>> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >>> pthread_key_t = int32_t; (* opaque *) >>> Index: linux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.10 >>> diff -u -r1.10 Usysdep.i3 >>> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >>> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -21,7 +21,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >>> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >>> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >>> pthread_key_t = uint32_t; >>> Index: solaris-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >>> Usysdep.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Usysdep.i3 >>> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >>> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -24,7 +24,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >>> (* 32 bytes with 64 bit alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >>> 16 bytes with 64 bit alignment *) >>> pthread_key_t = int32_t; (* opaque *) >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 02:19:58 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 01:19:58 +0000 Subject: [M3devel] cygwin jmp_buf size incorrect In-Reply-To: <495B901F.1E75.00D7.1@scires.com> References: <20081231105208.9CF4710D5DDE@birch.elegosoft.com> <495B4846.1E75.00D7.1@scires.com> <495B901F.1E75.00D7.1@scires.com> Message-ID: > Cygwin's setjmp.h incorrectly typedefs jmp_buf confirmed fyi/fwiw, unfortunate: http://cygwin.com/ml/cygwin/2009-01/msg00863.html - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: rcoleburn at scires.com; m3devel at elegosoft.com > Subject: RE: [M3devel] [M3commit] CVS Update: cm3 > Date: Thu, 29 Jan 2009 17:10:53 +0000 > > >> In reading your post, you state that you deoptimized the native implementation >> to make it match Cygwin. Now, I'm not sure how > > > I was wrong on this point. > Cygwin's setjmp.h incorrectly typedefs jmp_buf, indeed, to be much larger than "native", but the header is incorrect. Cygwin actually has a slightly smaller jmp_buf than native (13 ints vs. 16 ints), but we use the native size always, deoptimizing the Cygwin case. > > - Jay > > ________________________________ >> Date: Wed, 31 Dec 2008 15:30:40 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> >> >> >> >> >> >> Jay: >> >> >> >> First, I do want to say thanks for all you are doing for the cause of Modula-3. I don't think we say thanks enough for what others do for us. THANK YOU! >> >> >> >> I don't want to be perceived as "complaining", rather I am trying to voice my opinion in the hopes of influencing future direction. Of course, since I'm not doing the work, I can only make suggestions. >> >> >> >> In reading your post, you state that you deoptimized the native implementation to make it match Cygwin. Now, I'm not sure how much effect this deoptimization has (maybe little), but it is clear that in this case your implementation choice has favored the non-native implementation over the native one. IMO, tradeoffs of this type are not good. If one is trying to convince someone to use Modula-3, why would you want to give them a "deoptimized" version just to make it easier to support a non-native environment---indeed, one that they may not even want/use? If we have to make a trade-off, I say favor the native implementation always over the non-native one. >> >> >> >> What I'm trying to say here is that my experience as a software, systems, and program engineer is that I've always been forced to justify the cost/benefit of development tools for any project. Many times I've had to go head to head with folks higher up in my own organization or in the customer's organization whose preconceived opinions were based on rumor and what they've heard rather than actual factual hands-on experience. I want to pick the best tool for the job instead of being forced to pick an inferior tool because someone higher in the food chain demanded it based on faulty preconceived opinion. I like Modula-3. I've found that I am more productive using it. But, if the compiler doesn't produce efficient code, I lose ground in arguing with the higher-ups. >> >> >> >> As for Python, I've never ventured to learn it, so for me, it is something of a mystery. But you miss the point. I'm not arguing the merits of Python, I'm just saying that anything Modula-3 requires on top of what is provided by the standard host platform represents a potential obstacle or barrier to ease of use/implementation. It also sends the message that somehow Modula-3 is not complete on its own, we have get Python just to install and oh yes we need a C compiler and a linker and a ...? IMO, ultimately we need a turn-key download and install routine for Modula-3 that just works, out-of-the-box. If you give me an EXE, a CMD, or a BAT, for the install, I can run it on Windows, but if you give me an install routine that requires I first install something else, e.g. Python, then that becomes a barrier to the folks who don't know Python or already have it installed. >> >> >> >> Am I alone in this line of thought? If so, I'll just be quiet. >> >> >> >> BTW, I can certainly help in maintaining the CMD/BAT install routines or in making a better CMINSTALL. My problem is that right now, it is hard to understand all the dependencies for proper building of cm3 from scratch. Indeed, I've contributed some CMD/BAT install stuff in the past, but it is now out of date. Perhaps if there is a way we could better document the proper build order and dependencies, it would be easier for folks in the community to help in this area. I certainly would volunteer to do the CMD files as long as I had enough information to do it right. At one point, I thought we had a file that showed the package build order and dependencies. Not sure if the format of this file is well-documented or if the file is kept up-to-date. >> >> >> >> Regards, >> >> Randy >> >> >>>>> Jay 12/31/2008 1:34 PM>>> >>> you've made the CYGWIN implementation "appear" >>> be the same as the native Windows implementation. >>> But they are not the same. >> >> >> But they mostly are, from the front end's point of view. >> They are both little endian, x86, use the same jump_buf size (I grew it to match Cygwin's, which is a deoptimization of stack use on native NT386), the same type sizes and alignments..er..not sure about LONGINT. >> They might vary in newline and one uses the internal backend and one the external, however which backend they use is actually minor to the front end, though I think it affects if the front end "deals with" calling conventions, particularly left-to-right vs. right-to-left and struct returns. >> Object code produced by one can generally be linked with object code produced by the other. >> >> >> SOLgnu and SOLsun are a better example of this, though they do go ahead and duplicate tons of stuff that if I had implemented them, I would have avoided. >> They are truly identical in every respect in the front end and back end. >> They only vary in the config file. >> This is wasteful, because, "by default", if I'm put together a comprehensive cross build system without being a little smarter, I end up building two identical m3cgs. My config files are willing to "probe across" SOLsun and SOLgnu though, so I need only one m3cg for the two of them. >> >> >> Given that "NT386" can describe a combinatorial explosion of configurations, it makes some sense to keep it just one if possible. The compiler mostly doesn't care. >> >> >> >>> "- BUILD_DIR does not necessarily equal HOST or TARGET, >>> because of how I structured I386_CYGWIN to be a "configuration" >>> where TARGET is still NT386." >> >>> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". >> >> BUILD_DIR also does not equal HOST or TARGET when doing profiled builds, which admittedly I never have. >> Therefore, BUILD_DIR is arbitrary. >> I might be confusing something here though -- since I have never built a profiled build, I also haven't shipped one. It could be that "shipped BUILD_DIR" does equal TARGET, for profiled builds, in which case I did set a precedent. But the "override" code isn't using shipped files, so.. >> I have to check. >> >>> as long as it does not compromise the native Windows implementation >> >> Agreed and it basically doesn't. >> Show me where it does. >> The only thing I can think of is the jmpbuf size. >> >>> I don't want to have to install CYGWIN either in order to make >>> the native implementation work on Windows. >> >> Please don't complain about stuff that isn't true or without being more specific. >> I know of no dependency by the native implementation on Cygwin. >> >> In fact, installing Cygwin does tend to break the native implementation, depending on $PATH, because it has a link.exe that is a completely different program (ie: ln.exe). >> I tried experimenting with using cl to drive link.exe but couldn't quite get it to work, for stupid reasons related to response files, which surely is fixable by extending response file support in cm3... >> >> As it is, I usually delete \cygwin\bin\link.exe, or remove cygwin from $PATH. >> True, I don't ever uninstall Cygwin for testing, so the dependency could creep in by accident. >> >> >>> I also still prefer the CMINSTALL, CMD, or BAT files >>> for install as opposed to having to get Python or something else. Just my 2 cents. >> >> Once built and installed, there is no dependency on cmd, bat, cminstall, or python. >> cminstall is pretty worthless imho, as long as you set PATH, INCLUDE, and LIB. >> That is also a competing workaround for paths with spaces. >> And allows moving around among different versions of Visual C++, which is good and bad. >> Either you can have n installs of cm3, each configured tightly for one specific Visual C++, >> or you can have 1 install of cm3, that is flexibly configured, that you "reconfigure" by altering the environment. I do the second. >> >> If you want to build the system, in a well automated way, with cmd and bat, you are welcome to write them. >> Maybe the ones I left in the tree work, but i never use them any longer. >> I use the Python all the time. >> >> Or you can manually cd around (as I suspect Tony does). >> Personally I find cmd/bat among the worst programming languages ever and would rather not write it. >> jscript via cscript.exe would be a good alternative, it is always there at least as of Windows 2000 or perhaps with IE installed on older versions, but then you have to duplicate work across Unix and Windows. >> That is, for Windows-only no-cmd, no-install command line automation, JScript and VBScript are good choices, but Windows-only rules them out. The install is worth it. >> Python is a very decent programming language that is very portable across "all" systems. >> Perl would be the next best choice, though..I just don't like much. >> sh/bash requires an install on Windows, so its built-inness on Posix I claim isn't a conclusive win. >> I strongly encourage you to try out Python. >> >> Another avenue is to merge the sh/cmd/python into cm3 itself. >> It shouldn't be all that hard. >> >> Modula-3 still needs a C linker. >> And there is C code that I didn't put in -- hand.c and dtoa.c. >> If someone writes a linker in Modula-3, or gets the .obj loader working, I'll be more open to eliminating C. >> >> But using C is much less error prone and much more portable, in some parts of the system. >> >> You may label C as "evil", but the other "evil" I am battling is tedious error prone "header cloning". >> You pretty much must chose one. >> The header cloning can be reduced, and its error proned-ness and difficulty various per system, depending on how gnarled up the headers are with ifdefs, compatibility hacks, processor-specificty, "cleansing" (where the installed headers are processor specific, deriving from #ifdef'ed or somesuch other files, but now I argue both sides, #ifdef is hard to read, but removing them removes information unless you track further back), etc. For example the OpenBSD headers are much more readable. I suspect NetBSD are too but haven't looked yet. The Linux headers contain a lot of #ifdef and they are also processor-specific I think -- you know, my /usr/include/errno.h on one system I think didn't show that x86 and SPARC use different values. >> >> >> - Jay >> >> >> >> ________________________________ >> >> >> Date: Wed, 31 Dec 2008 10:28:37 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> Jay: >> >> >> >> Please explain what you mean by: >> >> >> >> "- BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386." >> >> >> >> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". Indeed, I have stuff that depends on the meaning of these things. Your statement seems to imply that "under the covers" you've made the CYGWIN implementation "appear" to be the same as the native Windows implementation. But they are not the same. >> >> >> >> On another note, All this CYGWIN stuff may be a nice way for die-hard Unix fans to run Modula-3 on Windows, and I have no objection to providing it, as long as it does not compromise the native Windows implementation. My main concern is the native implementation of Modula-3 on Windows. My preference would be to keep the NT386 implementation's dependencies on other stuff to a bare minimum, i.e., don't introduce anything that would require someone to have to acquire something besides what comes in the standard Windows OS in order to make Modula-3 run. As it is now, we already have to get a C compiler and linker. Fortunately, Microsoft has made the Visual Studio Express editions a free download, so this is not too bad. I don't want to have to install CYGWIN either in order to make the native implementation work on Windows. I also still prefer the CMINSTALL, CMD, or BAT files for install as opposed to having to get Python or something else. Just my 2 cents. >> >> >> >> Finally, I would go a step further and suggest that the Modula-3 implementation on every platform should strive to require minimal dependencies on anything not provided standard with that platform's operating system. >> >> >> >> Call me an idealist, but it just galls me that I have to have a C compiler/linker to build Modula-3. Modula-3 is a systems programming language. It should stand on its own. From a purely economical viewpoint, why should I have to buy something I don't want (C language development environment) in order to have the privilege of using what I do want (Modula-3 language development environment). >> >> >> >> Regards, >> >> Randy >> >>>>> Jay Krell 12/31/2008 11:52 AM>>> >> CVSROOT:/usr/cvs >> Changes by:jkrell at birch.08/12/31 11:52:08 >> >> Modified files: >> cm3/m3-comm/netobj/src/: netobj-ov.tmpl >> cm3/m3-comm/sharedobj/src/: sharedobj-ov.tmpl >> cm3/m3-libs/libm3/src/bundleintf/: bundle-ov.tmpl >> cm3/m3-ui/zeus/src/: m3zume-ov.tmpl >> cm3/m3-ui/juno-2/juno-app/src/: m3makefile >> >> Log message: >> Partly kinda sorta fix some cross build scenarios, without >> affecting native builds. >> >> It's a larger more general problem though. >> >> - BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386. >> >> - a cross build can run the shipped binary anyway, >> and probably should (I didn't have the unshipped binaries around) >> >> - There should probably be automation to ensure all the tools are build. >> ie: do-cm3-tools or do-cm3-crosstools. ie: build just the needed packages, >> for the sniffed native platform. >> >> Cross builds have other problems. >> >> I keep hitting the following annoyances: >> >> ignoring foo/bar override when foo\bar already overridden >> override paths should either be canonicalized to one slash type >> or at least when there is a duplicate, canonicalize then and only >> complain if canonicals vary >> This is due to mixing I386_NT and I386_CYGWIN. >> Similarly the problem demonstrated regarding m3unix.h in Uwaitpid.quake. >> >> Perhaps the change I made to allow forward slashes on Win32 was not good, esp. due to >> its apparent inadequacy. >> >> The "lib" directory, specifically \cm3\lib\hand.obj is target..er, configuration dependent >> the gcc hand.obj cannot be directly linked by Visual C++, for reasons to do with libgcc >> >> lib should probably have "target" or "build_dir" under it >> >> and/or hand.obj specifically should be merged into m3core.lib >> >> The mentor quake code generally fails in cross environments, probably due to slashes. >> >> host=NT386 (GNU?), target=LINUXLIBC6 m3zume is access violating >> >> I'm also highly suspicious of all this "override" stuff. >> It clearly causes too much duplication and distribution of information. >> I shouldn't have to know the directory structure of my dependencies, >> and even if I do, I should be able to share that knowledge with their many >> other dependents. The "scripts" directory also figures this sort of stuff out automatically.. >> Being able to have multiple package stores is well and good. >> I'm not sure they need to ever be used in an "unshipped" form, but instead just >> use alternate roots and create new empty roots as needed. ? >> >> From hosking at cs.purdue.edu Thu Feb 5 00:04:47 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:04:47 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: On 5 Feb 2009, at 09:11, Jay wrote: > >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. > > > The entire proposal or the optimizations? The C allocation of M3 objects, without going through NEW. There are a whole slew of reasons why I'd like to avoid that. > The original unoptimized proposal seems like a small change mostly. > I checked and the indirection/heap allocation is already there > for cond and mutex, but not for pthread_t itself. > Factoring out the size I think is a small change. Yes, possibly. Let me look at it. > On the other hand, we can also optimize it, pretty much > locking in the platform-specificity. It's a tough decision to me. > I don't mind the deoptimizations of const-to-var, or adding > some function calls, but heap allocs imho are among the things > to definitely avoid if not needed. These are untraced as well, > so the argument that Modula-3 heap alloc is efficient doesn't apply. Right, just that you lose some compiler knowledge of where allocations occur. I have some work I am doing where I analyse code for allocation sites. > One caveat that bothers me though is, like with sem_t, > I don't want to have types that are declared "incorrectly". > I'd like types that you can only have references too. > Probably in that case "give up", declare them as ADDRESS, > losing the type safety -- pthread_cond_foo could take a mutex_t > and no compilation error. Sure. > The idea of making them all ADDRESS and adding C functions to alloc/ > cleanup > is also good imho. That allows for one of the optimized forms -- > not where the space is at the end of the Thread.T, but where the > ADDRESS field is the data itself. Possibly. > I got hung up on pthread_attr_t here because it was efficiently > stack allocated and this proposal would have really deoptimized that. > The C code I showed avoids that though. > Albeit only in the face of creating a thread -- an extra heap > allocation > per thread create probably not a big deal. Hmm. > Clearly I'm ambivalent. OK, let me think on it. > Later, > > - Jay > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 09:42:12 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> It gains something, but maybe it isn't enough >> to be worthwhile. The issue is in the subjectivity. >> >> >> It would remove e.g. the following system-dependent lines: >> >> >> Linux: >> pthread_t = ADDRESS; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> >> >> Linux/32: >> pthread_attr_t = ARRAY[1..9] OF INTEGER; >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Linux/64: >> pthread_attr_t = ARRAY[1..7] OF INTEGER; >> pthread_mutex_t = ARRAY[1..5] OF INTEGER; >> >> >> FreeBSD: >> pthread_t = ADDRESS; >> pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> >> >> HP-UX: >> (* trick from darwin-generic/Upthread.i3 *) >> X32 = ORD(BITSIZE(INTEGER) = 32); >> X64 = ORD(BITSIZE(INTEGER) = 64); >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF >> INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Cygwin: >> pthread_t = ADDRESS; (* opaque *) >> pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> >> >> Solaris: >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* >> 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 >> bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Darwin: (only ppc32 currently) >> pthread_t = INTEGER; (* opaque *) >> pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> >> >> (plus AIX, Irix, VMS, Tru64.) >> >> >> Another approach would be make them all ADDRESS and introduce a >> portable >> C layer of "varything thickness", using the same logic. >> It would look just like the native pthreads, but there'd be extra >> allocate/cleanup >> calls -- to do the heap alloc/cleanup when the underlying types are >> larger than addresses. >> The two layers would be clear and simple, the cost would be the same, >> but there would be the conceptual cost of two simple layers instead >> of one >> just one slightly complicated layer. >> >> >> Another approach is maybe make them all addresses on new platforms >> and introduce >> the C layer only on new platforms. Again, about the only change in >> the Modula-3 >> code is extra alloc/cleanup calls. >> >> >> And again, some/all of the code already has the indirection/heap >> allocation unconditionally. >> >> >> And again, maybe not worth it. I show all the system-dependent >> code, attempting >> to portray in its worst light by showing all of it, but maybe it's >> really not a lot. >> >> >> For the attr type, we can do something specific to its use. >> There is just one use, and we can address it with the following >> function written in C.. >> eh..I'll send a diff later tonight/this week I think. >> >> >> pthread_t and pthread_key_t always happen to be address-sized or >> smaller. >> Maybe just declare them both to be address and assert their size in >> some C code. >> That might waste a few bytes esp. on 64 bit platforms, or it might >> merely fill in the padding-for-alignment. >> >> For example, we have: >> >> >> TYPE >> Activation = UNTRACED REF RECORD >> (* global doubly-linked, circular list of all active threads *) >> next, prev: Activation := NIL; (* LL = activeMu *) >> (* thread handle *) >> handle: pthread_t; (* LL = activeMu *) >> (* base of thread stack for use by GC *) >> stackbase: ADDRESS := NIL; (* LL = activeMu *) >> >> >> so on 64 bit platforms where pthread_t is a 32bit integer, it is >> taking up 64 bits anyway. >> There are two static pthread_key_ts, so making them address would >> waste 8 bytes on some/many 64bit platforms. >> >> >> Leaving only cond and mutex. >> Some of the platforms declare more types such as rwlock, >> rwlockattr, but they are never used. >> rwlock is a useful type though. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 12:53:54 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. >>> >>> On 4 Feb 2009, at 11:06, Jay wrote: >>> >>>> >>>> There are a few possibilities: >>>> >>>> >>>> Roughly: >>>> >>>> Where there is >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = ... system specific ... >>>> pthread_cond_t = ... system specific ... >>>> pthread_mutex_t = ... system specific ... >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> MODULE PThread; >>>> VAR >>>> a: pthread_t; >>>> b: pthread_cond_t; >>>> c: pthread_mutex_t; >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> change to: >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = RECORD END; or whatever is correct for an opaque >>>> preferably unique type >>>> pthread_cond_t = RECORD END; ditto >>>> pthread_mutex_t = RECORD END; ditto >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> >>>> INTERFACE PThreadC.i3 >>>> >>>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>>> >>>> or possibly extern VAR >>>> >>>> PThreadC.c >>>> >>>> static pthread_t a = PTHREAD_INIT; >>>> static pthread_cond_t b = PTHREAD_COND_INIT; >>>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>>> >>>> pthread_t* GetA() { return &a; } >>>> >>>> pthread_cond_t* GetB() { return &b; } >>>> >>>> pthread_mutex_t* GetC() { return &c; } >>>> >>>> MODULE PThread; >>>> VAR >>>> a := PThreadC.GetA(); >>>> b := PThreadC.GetB(); >>>> c := PThreadC.GetA(); >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a^); >>>> Upthread.pthread_cond_init_or_whatever(b^); >>>> Upthread.pthread_mutex_init_or_whatever(c^); >>>> END Foo; >>>> >>>> or, again, possibly they are variables and it goes a little >>>> smaller/ >>>> quicker: >>>> >>>> FROM UPthreadC IMPORT a, b, c; >>>> >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> I think that is pretty cut and dry, no controversy. >>>> >>>> What is less clear is what to do with non-statically allocated >>>> variables. >>>> >>>> Let's say: >>>> >>>> MODULE PThread; >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:pthread_t; >>>> END; >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T) >>>> BEGIN >>>> Upthread.init_or_whatever(t.b); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> The desire is something that does not know the size of pthread_t, >>>> something like: >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:UNTRACED REF pthread_t; >>>> END; >>>> >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T); >>>> BEGIN >>>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>>> CHAR, Upthread.pthread_t_size)); >>>> (* Though I really wanted t.b := >>>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b^); >>>> DISPOSE(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> >>>> However that incurs an extra heap allocation, which is not great. >>>> In at least one place, the pointer-indirection-and-heap-allocation >>>> is already there >>>> so this isn't a deoptimization. However "reoptimizing" it might be >>>> nice. >>>> >>>> >>>> What I would prefer a pattern I often use in C -- merging >>>> allocations, something like, >>>> /assuming/ t is untraced, which I grant it might not be. >>>> >>>> >>>> And ensuring that BYTESIZE(T) is properly aligned: >>>> >>>> >>>> PROCEDURE CreateT():UNTRACED REF T= >>>> VAR >>>> p : ADDRESS; >>>> t : UNTRACED REF T; >>>> BEGIN >>>> (* Again I would prefer RTAllocator.MallocZeroed *) >>>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>>> BYTESIZE(T))); >>>> t := LOOPHOLE(UNTRACED REF T, p); >>>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> >>>> That is -- opaque types, size not known at compile-time, but size >>>> known at runtime, and >>>> do not incur an extra heap allocation for lack of knowing sizes at >>>> compile-time. >>>> >>>> >>>> For the statically allocated variables I think there is no >>>> controversy. >>>> There might a tiny bit of overhead in the use, but it'd be very >>>> small, and possibly >>>> even removable in the future. I'd rather avoid the variables, as >>>> all writable >>>> data is to be avoided. Read only pages are better and all that, >>>> but ok.. >>>> >>>> >>>> However the value is mainly realized only if statically and >>>> dynamically allocated variables are handled. >>>> >>>> The result of this would be further reduction in platform- >>>> specificity when cloning >>>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>>> platforms. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> From: hosking at cs.purdue.edu >>>>> To: jay.krell at cornell.edu >>>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>>> CC: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] further reducing cloned headers wrt >>>>> pthread? >>>>> >>>>> I suggest you come up with a proposal for us to look over before >>>>> you >>>>> change the code base for this. >>>>> >>>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>>> >>>>>> >>>>>>> Hmm, yes, you are right that there is a possible alignment >>>>>>> issue. I >>>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>>> in C >>>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>>> alignment padding anyway so as to allow allocation using >>>>>>> malloc(sizeof >>>>>>> pthread_mutex_t)? So, it all should just work right? >>>>>> >>>>>> >>>>>> I think "the other way around" and same conclusion. >>>>>> malloc should return something "maximally aligned" so that >>>>>> >>>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>>> malloc(sizeof(pthread_mutex_t)); >>>>>> >>>>>> >>>>>> works. pthread_mutex_t doesn't need the padding, malloc does, >>>>>> so to >>>>>> speak. >>>>>> >>>>>> >>>>>> Just as long as we don't have >>>>>> >>>>>> >>>>>> TYPE Foo = RECORD >>>>>> a: pthread_mutex_t; >>>>>> b: pthread_mutex_t; >>>>>> c: pthread_t; >>>>>> d: pthread_t; >>>>>> e: pthread_cond_t; >>>>>> f: pthread_cond_t; >>>>>> END; >>>>>> >>>>>> >>>>>> and such, ok. >>>>>> >>>>>> >>>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>>> I think on Win9x only 4 alignment, thus there is >>>>>> _malloc_aligned for >>>>>> dealing with SSE stuff. >>>>>> Something like that. >>>>>> >>>>>> >>>>>> I didn't realize untraced allocations were basically just >>>>>> malloc but >>>>>> indeed they are. >>>>>> >>>>>> >>>>>> I'm still mulling over the possible deoptimizations here. >>>>>> I'm reluctant to increase heap allocations. >>>>>> >>>>>> >>>>>> >>>>>> - Jay >>>>> >>> From mika at async.caltech.edu Thu Feb 5 05:33:09 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Wed, 04 Feb 2009 20:33:09 -0800 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: Your message of "Wed, 04 Feb 2009 22:01:58 GMT." Message-ID: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Jay writes: ... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) ... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika From hosking at cs.purdue.edu Thu Feb 5 05:45:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 15:45:46 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. On that count, does anyone know what happened to the CM Java VM? Is it available anywhere? On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > Jay writes: > ... >> I'll maybe review more code along these lines. >> I gather the general gist of things in Modula-3 though >> is that out of memory is fatal anyway. Raising an exception >> vs. failing an assertion probably not significantly different >> if the exception is not meant to be caught and isn't ever caught. >> (Strange though then the gymnastics I pointed out elsewhere >> converting one form of out of memory to another form..) > ... > > Back in SRC days I remember there was a discussion at some length > about what to do in case of running out of memory. I think the > project was abandoned as people realized it was quite a tricky > problem... > > I don't believe PM3 has out of memory exceptions, nor did SRC > M3...? It's a wild guess but maybe this has something to do with > the Critical Mass modifications for their JVM? > > Mika From dabenavidesd at yahoo.es Thu Feb 5 18:56:06 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Thu, 5 Feb 2009 09:56:06 -0800 (PST) Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <519119.97354.qm@web24711.mail.ird.yahoo.com> Hi all; I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at: ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/ Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps. Thanks --- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headers Para: "Jay" CC: m3devel at elegosoft.com Fecha: mi?rcoles, 4 febrero, 2009 11:33 Jay writes: .... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) .... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:11:37 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:11:37 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Does this make sense? It is pushing my Modula-3 knowledge. I didn't yet check the number of bytes requested by malloc/calloc. All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 7.txt URL: From jay.krell at cornell.edu Thu Feb 5 19:29:59 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:29:59 +0000 Subject: [M3devel] out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: Here are some ideas that contribute to handling out of memory being useful/good: "stress" Stress a system.Things start going slow and failing, ok. You can't succeed against all odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion" A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources. Assuming that important state is managed well, like in a transactional database. And that most state is expendable. As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/ "malicious", as well as insulating "important" server processes (daemons) from run away/malicious clients. Guard against "denial of service attacks". Some people like to put hard limits on things. "I will reject any strings longer than 2gig". However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it. Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:39:09 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:39:09 +0000 Subject: [M3devel] FW: out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: (truncated..) From: jay.krell at cornell.eduTo: dabenavidesd at yahoo.es; m3devel at elegosoft.comSubject: RE: out of memory philosophyDate: Thu, 5 Feb 2009 18:29:59 +0000 Here are some ideas that contribute to handling out of memory being useful/good: "stress"Stress a system.Things start going slow and failing, ok. You can't succeed againstall odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion"A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources.Assuming that important state is managed well, like in a transactional database.And that most state is expendable.As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/"malicious", as well as insulating "important" server processes (daemons)from run away/malicious clients. Guard against "denial of service attacks".Some people like to put hard limits on things. "I will reject any strings longer than 2gig".However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it.Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:57:17 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:57:17 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Hm, nevermind that. More later. I think either wrapping it up more in C would be cleaner or even Modula-3 ("Upthread.m3"), than this sort of "split", or at least changing it to ADDRESS and if size <= BYTESIZE(ADDRESS), just use that space and save the heap alloc. On systems that already have either a small object or an indirection, save the heap alloc. Later, - Jay From: jay.krell at cornell.eduTo: m3devel at elegosoft.comSubject: reducing system-dependence in Upthread.i3?Date: Thu, 5 Feb 2009 18:11:37 +0000 Does this make sense?It is pushing my Modula-3 knowledge.I didn't yet check the number of bytes requested by malloc/calloc.All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Fri Feb 6 16:12:00 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Fri, 06 Feb 2009 16:12:00 +0100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Message-ID: <20090206161200.em81i2uh44sg8koo@mail.elegosoft.com> Quoting Tony Hosking : > Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. > > On that count, does anyone know what happened to the CM Java VM? Is it > available anywhere? AFAIK it is not. I think I asked Farshad Nayeri some years ago, but got no answer. Maybe it's still in commercial use, or there are some other legal problems with the code (as Sun was probably involved). Nonetheless, it cannot harm to ask again... Olaf > On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > >> Jay writes: >> ... >>> I'll maybe review more code along these lines. >>> I gather the general gist of things in Modula-3 though >>> is that out of memory is fatal anyway. Raising an exception >>> vs. failing an assertion probably not significantly different >>> if the exception is not meant to be caught and isn't ever caught. >>> (Strange though then the gymnastics I pointed out elsewhere >>> converting one form of out of memory to another form..) >> ... >> >> Back in SRC days I remember there was a discussion at some length >> about what to do in case of running out of memory. I think the >> project was abandoned as people realized it was quite a tricky >> problem... >> >> I don't believe PM3 has out of memory exceptions, nor did SRC >> M3...? It's a wild guess but maybe this has something to do with >> the Critical Mass modifications for their JVM? >> >> Mika -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From martinbishop at bellsouth.net Wed Feb 11 05:01:38 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 10 Feb 2009 22:01:38 -0600 Subject: [M3devel] modula3.org updated links Message-ID: <49924DA2.6090607@bellsouth.net> A while back I said it would be nice if modula3.org could get it's links updated, as quite a few of them were dead. Well I went through the links on the front page of modula3.org (as well as the separate "Links" page) and updated them. I only removed one link, and replaced all the dead ones with either mirrors or just better links. (NOTE: They look bad because they aren't using the CSS, but I'm just putting these up so someone (Olaf?) can save the source and push to the modula3.org CVS.) http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html (Main page) http://mbishop.esoteriq.org/modula3.org/index.html (Links page) From jay.krell at cornell.edu Wed Feb 11 07:07:20 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 06:07:20 +0000 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: I must say, I find the design of the various web sites terrible. The stuff i want is far buried, not just deep, but sometimes under odd sounding links. The offenders include: "www service" is one of the worst named but most useful links, it is a link to one of the main Modula-3 pages. Given that this is already on a web page, "www service" adds no meaning. It is slightly a pain to find the CVS browsing page, the tinderbox status, and something else I forget. And it is annoying how the CVS pages opens doubly nested. Gotta run, - Jay> Date: Tue, 10 Feb 2009 22:01:38 -0600> From: martinbishop at bellsouth.net> To: m3devel at elegosoft.com> Subject: [M3devel] modula3.org updated links> > A while back I said it would be nice if modula3.org could get it's links> updated, as quite a few of them were dead. Well I went through the> links on the front page of modula3.org (as well as the separate "Links"> page) and updated them.> > I only removed one link, and replaced all the dead ones with either> mirrors or just better links.> > (NOTE: They look bad because they aren't using the CSS, but I'm just> putting these up so someone (Olaf?) can save the source and push to the> modula3.org CVS.)> > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html> (Main page)> > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 11 09:28:06 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 08:28:06 +0000 Subject: [M3devel] apsl? (Apple source license?) Message-ID: Can we add Apple APSL-licensed code into the Modula-3 libraries? In particular, like, _setjmp.h? Or maybe even the get/set/make/swapcontext code? It looks me like ASPL is: "not viral" -- it does not impact the code it is linked to, mostly It carries with it an "advertising clause", which is somewhat viral. That is, you have to state you are using APSL code, and you might have to reveal that specific code (unknown) but there are no additional restrictions on code it is linked with. Upon further reading.. The license discusses "original code" and "modified code". If code is modified, it must be clearly marked as such. Reasonable, but annoying. If you modify the code, you do have to distribute it with binaries. Mildly viral. If you don't modify the code, you don't have to distribute any source. Good. http://www.opensource.apple.com/apsl/ http://www.gnu.org/philosophy/apsl.html (I wish everyone would just use the BSD license...but oh well..) - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Fri Feb 13 19:22:33 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:22:33 -0600 Subject: [M3devel] More on new Text package Message-ID: <4995BA69.6080705@wichita.edu> I neglected to mention that the new package, by default, uses the old algorithms, although there will be constant-time slowdown, because it decides dynamically on every call to do this. Also, there is a lot of instrumentation being executed. To get the new algorithms, set TextClass.Old to FALSE. You can change this between any two calls into the package. Rodney Bates From rodney.bates at wichita.edu Fri Feb 13 19:05:30 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:05:30 -0600 Subject: [M3devel] New experimental Text module Message-ID: <4995B66A.8000906@wichita.edu> There is an experimental replacement for the various library code involving the type TEXT, now checked in the CVS repository, in cm3/m3-libs/m3core/src/text, under branch devel_m3core_text_newtext_branch. There is a test program for it in cm3/m3-libs/m3core/tests/newtext. Approach: I tried to see how much I could improve the performance of CM3 TEXT operations by changing the algorithms only, leaving the data structure, both declarations and invariants, unchanged. This presents minimum disruption elsewhere. Both the pickle code and existing pickle files will be unaffected, along with other things that use pickles. Changes: I eliminated as much recursion as possible, converting some instances of recursion to tail-recursions, and then converting all tail-recursion instances to iteration. Recursion remains when: 1) There is true nonlinear recursion. This happens in only one place in concatenation. Here, I did the recursion on the shorter (and thus hopefully shallower) side of the tree. 2) Where necessary to avoid the chance of creating an identical copy of a known, already existing TextCat.T node. 3) The recursion needs to go through a method dispatch. In concatenations, I "flattened" concatenation results that do not exceed a length cutoff. By "flattening", I mean copying into a single node of type Text8.T, Text8Short.T, Text16, or Text16Short.T. I experimentally tuned the length cutoff to 32 bytes, for best compromise among speed and time and in various use cases. In concatenations, I did some heuristic rebalancing. I used the relative lengths of strings as a crude approximation for the relative depths of trees. Actual depths are not cached in the nodes, and computing them would have been O(n) for each concatenation operation. I postponed rebalancing flat strings into a tree, keeping them at the top, where they are available for further flattening, until there is no chance of this happening. Most of the existing operations were sometimes unnecessarily converting strings from CHAR to WIDECHAR arrays, involving character-at-a-time conversion. This was a likely very common case, and I eliminated it when easily detectable. Bugs: I fixed (I hope!) a few bugs I discovered in the existing code. Find[Wide]CharR had an off-by-one bug in the where the search started. String[8|16].FindCharR was doing an address computation too early, in a local variable declaration, before a needed NIL check, making the check fail to work. HasWideChars was only computing whether the representation had the capability to hold wide characters, not whether any were actually there. This was not a useful meaning for the result. TextCat.MultiCat (and NewMulti, which calls it) were not checking for NILs. Assuming the result was ever used, these would eventually cause runtime errors, but not until it was more difficult to diagnose them. Testing: The modified code can be dynamically switched between the old and new algorithms. It is also loaded with instrumentation. All of this will slow it down, but the old/new comparisons should not have significant bias. TextClass.i3 has a lot of new stuff to allow clients to control the algorithms and collect results from the instrumentation. If people decide they like this package, I will produce a version with all this extra stuff stripped out. I wrote an elaborate test driver, both for bug-testing and for experimenting and gathering performance comparisons with the old code. It runs large numbers of randomly-generated test cases, typically 50000 flat strings, 100000 string-producing operations, heavily biased to concatenations (substring is the only other one), and 100000 text querying operations, roughly equally distributed. Concatenations can be built randomly from previous strings or "linearly", i.e., strictly left-to-right, or strictly right-to-left. The latter two cases are symmetrical, and once the symmetry bugs were gone, they give virtually identical performance. In the linear construction cases, there are no substring operations done. The old and new algorithms can be run side-by-side on pairs of strings that have identical abstract values (but often different internal representations). The results can be mechanically compared this way, for correctness testing. Performance summary: In a number of different situations, the new algorithms give improvements in total time spent in the operations, ranging from 17% to 60%, the latter for linear concatenations, which are much slower than random, using both the old and new algorithms. Tree balance improves dramatically in the linear cases (the random case is well-balanced even by the old algorithms) and recursion depth decreases even more dramatically. The new algorithms allocate 27% (random) to 79% (linear) more heap memory, but a lot is garbage. After collection, the new algorithms retain 20% more (random) to 2% less (linear). Total space runs somewhat larger in the linear case, for both algorithms. The old algorithms toss no garbage. In the special case of linear concatentations with all leaf strings having length one, the new algorithms allocate over twice as much heap storage but retain 63% less. Rodney M. Bates From mika at async.caltech.edu Sat Feb 14 19:10:51 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sat, 14 Feb 2009 10:10:51 -0800 Subject: [M3devel] Question about PM3 Message-ID: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika From rodney.bates at wichita.edu Sat Feb 14 21:30:23 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sat, 14 Feb 2009 14:30:23 -0600 Subject: [M3devel] Question about PM3 In-Reply-To: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Message-ID: <499729DF.3000800@wichita.edu> I have no immediate ideas, but a few questions and thoughts. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. How recent is your m3gdb? For a long time, it has been putting out much better demangled names that what you are getting. You can use the m3gdb in the CM3 distribution and build just it with 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically adapts to PM3-compiled code (unless there is a bug :-). Which code generator did you use, the integrated i386 backend or the gcc-derived one? (If you aren't sure, the latest m3gdb will tell you this and other things about what language implementation it uses with the 'info m3' command, entered after the M3 runtime has initialized.) If there is a code generation problem, it could also go away after just changing backends. However, I'm not sure if there would be trouble without rebuilding all the libraries with the same backend as your application. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. Mika Nystrom wrote: > Dear Modula-3-ers: > > I'm going to ask a question about an old, obsolete piece of software, and > don't expect anybody knows the answer, but would be grateful for any > insight: > > I have a Modula-3 program compiled with one of the last releases of PM3 > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code > that looks like this: > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = > VAR seq : FIXFieldSeq.T; > BEGIN > LOOP > (* update seq *) > seq := i.t.data[i.part]; > > (* first see if we are at end or pointing to an uninteresting part *) > (* seq can be NIL on certain error conditions *) > IF seq # NIL THEN > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN > IF i.part = LAST(Part) THEN (* at bitter end *) > RETURN FALSE > ELSE > INC(i.part); i.nextI := 0 > END > ELSE (* not at end, but in the middle of an interesting Part *) > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO > TRY > IF cur.type() IN i.fields THEN (* nteresting field? *) > f := cur; RETURN TRUE > END > FINALLY > INC(i.nextI) (* in any case, advance to next *) > END > END > END > END > END > END UINext; > > What I am seeing is the following > > Program received signal SIGSEGV, Segmentation fault. > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > 893 INC(i.nextI) (* in any case, advance to next *) > (m3gdb) list > 888 TRY > 889 IF cur.type() IN i.fields THEN (* nteresting field? *) > 890 f := cur; RETURN TRUE > 891 END > 892 FINALLY > 893 INC(i.nextI) (* in any case, advance to next *) > 894 END > 895 END > 896 END > 897 END > > The crash makes no sense, because "i" has already been dereferenced > several times before this, without problem. > > (m3gdb) where > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 > > We're in some sort of "fake" stack frame, and... > > (m3gdb) up > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > 890 f := cur; RETURN TRUE > (m3gdb) print i > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > nextI = 0; END > (m3gdb) > > everything looks OK with i. > > Is it possible there is some sort of problem with TRY .. FINALLY under > PM3? And of course, if so, might it go away with CM3? > > Mika > > From wagner at elegosoft.com Sat Feb 14 23:55:19 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sat, 14 Feb 2009 23:55:19 +0100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4995B9A8.5020403@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> Message-ID: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Quoting "Rodney M. Bates" : > Well, I can work on compilers, debuggers, and functional text packages, but > I can never operate CVS correctly. > > As far as I can tell, I think I got these checkins done in the trunk, rather > than the branch I created for them. I created a tag on the trunk, > "devel_m3core_text_2009_02_13", then created a branch with tag > "devel_m3core_text_newtext_branch". Apparently I got that much right. > > But I am not sure whether the changed files went into the branch. My > CVS book reads as if just a cvs tag -b ..., followed by a cvs commit > will do the commits in the branch, but the commit message doesn't look > like that happened. > > Can anybody help me with: > 1) What really happened? > 2) How should I have done this? You probably forgot to update your workspace to the branch: cvs up -r devel_m3core_text_newtext_branch After that, the branch tag will be `sticky' in your workspace, until you use cvs up -A, which clears it again (and transports you to the trunk). > 3) How can I fix the damage? Well, you can easily revert the changes on the main trunk by checking out the latest version and using -j old-version -j current version, and then commit it. This should put the old-version at the head of the trunk again. Before you do that, you should probably commit everything to the branch, thus you don't need to checkout your version again. I think the version before yours was tagged devel_m3core_d2_4_0. But perhaps it is not necessary to do this? Have tou had feedback from others about the new sources? If nothing breaks and performance gets better, I won't complain ;-) Thanks for all the work, Olaf > PS: I believe that if you use the new files with no additional action, > that you > will get the same behavior as before, except that there will be considerable > constant-time slowdown due to lots of instrumentation and dynamic deciding to > use the original algorithms. But I have not tested this. So probably some improvements are needed before a release. -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Sun Feb 15 00:04:12 2009 From: jay.krell at cornell.edu (Jay) Date: Sat, 14 Feb 2009 23:04:12 +0000 Subject: [M3devel] Question about PM3 In-Reply-To: <499729DF.3000800@wichita.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> <499729DF.3000800@wichita.edu> Message-ID: I agree with Rodney's sentiment to double check whatever you can. If you can rebuild the compiler/runtime, try growing the jmpbuf. Or see what size is being used and write one line of C to see what it should be. (#include #include int main() { printf("%u\n", (unsigned) sizeof(jmpbuf)); }) If you are using user threads, try kernel threads and/or DisableSwitching/EnableSwitching around the crashing code. Read the generated code to try to confirm correctness. If you are optimizing the code, try not. If the loop only runs "a few" times, print out the address as it is dereferenced. See if the failing address is the same as one of the successful ones. Nag me and I'll set up FreeBSD/x86/5.5, send me instructions to build pm3 and send me your code. :) Try any other configuration. pm3 on Linux. cm3 on FreeBSD. cm3 on Linux. etc. - Jay> Date: Sat, 14 Feb 2009 14:30:23 -0600> From: rodney.bates at wichita.edu> To: mika at async.caltech.edu> CC: m3devel at elegosoft.com> Subject: Re: [M3devel] Question about PM3> > I have no immediate ideas, but a few questions and thoughts.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > How recent is your m3gdb? For a long time, it has been putting out> much better demangled names that what you are getting. You can use> the m3gdb in the CM3 distribution and build just it with> 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable> will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically> adapts to PM3-compiled code (unless there is a bug :-).> > Which code generator did you use, the integrated i386 backend or> the gcc-derived one? (If you aren't sure, the latest m3gdb will> tell you this and other things about what language implementation> it uses with the 'info m3' command, entered after the M3 runtime> has initialized.)> > If there is a code generation problem, it could also go away after> just changing backends. However, I'm not sure if there would be> trouble without rebuilding all the libraries with the same backend> as your application.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> > Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > Mika Nystrom wrote:> > Dear Modula-3-ers:> > > > I'm going to ask a question about an old, obsolete piece of software, and> > don't expect anybody knows the answer, but would be grateful for any> > insight:> > > > I have a Modula-3 program compiled with one of the last releases of PM3> > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code> > that looks like this:> > > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN => > VAR seq : FIXFieldSeq.T;> > BEGIN> > LOOP> > (* update seq *)> > seq := i.t.data[i.part];> > > > (* first see if we are at end or pointing to an uninteresting part *)> > (* seq can be NIL on certain error conditions *)> > IF seq # NIL THEN> > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN> > IF i.part = LAST(Part) THEN (* at bitter end *)> > RETURN FALSE> > ELSE> > INC(i.part); i.nextI := 0> > END> > ELSE (* not at end, but in the middle of an interesting Part *)> > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO> > TRY> > IF cur.type() IN i.fields THEN (* nteresting field? *)> > f := cur; RETURN TRUE> > END> > FINALLY> > INC(i.nextI) (* in any case, advance to next *)> > END> > END> > END> > END> > END> > END UINext;> > > > What I am seeing is the following> > > > Program received signal SIGSEGV, Segmentation fault.> > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > 893 INC(i.nextI) (* in any case, advance to next *)> > (m3gdb) list> > 888 TRY> > 889 IF cur.type() IN i.fields THEN (* nteresting field? *)> > 890 f := cur; RETURN TRUE> > 891 END> > 892 FINALLY> > 893 INC(i.nextI) (* in any case, advance to next *)> > 894 END> > 895 END> > 896 END> > 897 END> > > > The crash makes no sense, because "i" has already been dereferenced> > several times before this, without problem.> > > > (m3gdb) where> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846> > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411> > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321> > > > We're in some sort of "fake" stack frame, and...> > > > (m3gdb) up> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > 890 f := cur; RETURN TRUE> > (m3gdb) print i> > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > > nextI = 0; END> > (m3gdb) > > > > everything looks OK with i.> > > > Is it possible there is some sort of problem with TRY .. FINALLY under> > PM3? And of course, if so, might it go away with CM3?> > > > Mika> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sun Feb 15 06:27:38 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 14 Feb 2009 21:27:38 -0800 (PST) Subject: [M3devel] Question about PM3 Message-ID: <954132.49377.qm@web24715.mail.ird.yahoo.com> Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible that the assignment statement in line 890 is failing and because of the TRY-FINALLY you don't get a Runtime Error (which would be the ideal behaviour if the MODULE is safe and correspondent IMPORT Modules aren't? ill behaved ). 890 f := cur; RETURN TRUEYou could make a sanity check before that line with ?ISTYPE(cur, FIXField.T) (*is cur a member of f's type, FIXField.T *)? Please feel free to ask further questions. Hope this helps. Thanks. --- El s?b, 14/2/09, Mika Nystrom wrote: De: Mika Nystrom Asunto: [M3devel] Question about PM3 Para: m3devel at elegosoft.com Fecha: s?bado, 14 febrero, 2009 1:10 Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Sun Feb 15 12:51:49 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sun, 15 Feb 2009 12:51:49 +0100 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: <20090215125149.rgbaxncveok4okw4@mail.elegosoft.com> Quoting Martin Bishop : > A while back I said it would be nice if modula3.org could get it's links > updated, as quite a few of them were dead. Well I went through the > links on the front page of modula3.org (as well as the separate "Links" > page) and updated them. > > I only removed one link, and replaced all the dead ones with either > mirrors or just better links. > > (NOTE: They look bad because they aren't using the CSS, but I'm just > putting these up so someone (Olaf?) can save the source and push to the > modula3.org CVS.) > > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html > (Main page) > > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) I've downloaded the pages, but I'm not able to get a meaningful diff listing, as there are so many arbitrary changes, even ignoring all blanks, newlines, and case, that I don't have the time to check them. I don't want to put them up without testing, as images seem to be broken, for example, and changes in the case of tags don't improve maintainability. There also seem to be some strange changes in the location of pages, like s/images/Modula-3%20Resource%20Page_files/, which simply don't look right. Couldn't you send a minimal diff with just the substitutions needed, without any unnecessary changes? Or simply a list like an sed script with s/old link/new link/? That would make it considerably easier to integrate them for me. Don't misunderstand me, I think it's great that you've checked and updated all the links, and would like to put the new information on the server, but I cannot spend too much time on it. As a general rule, changes in layout and style which don't affect the funtionality of a page should be separated from content changes, which need to be checked in a different way. Thanks in advance for your understanding and help, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 16 00:31:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 16 Feb 2009 10:31:54 +1100 Subject: [M3devel] Tinderbox failures Message-ID: Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 02:42:25 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 01:42:25 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 03:15:02 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 02:15:02 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: I think it depends on what cm3 you start with. I noticed the Tinderbox has "last-ok" runs and "last-release" runs. last-ok appears to be working. last-release has the error. Updating my current cygwin build seemed to work. Starting with 5.4 (which is what last release appears to be) on Linux/x86 gave me a cm3 that just seg faults. I'll try to dig more. - Jay From: jay.krell at cornell.eduTo: hosking at cs.purdue.edu; m3devel at elegosoft.com; m3commit at elegosoft.comSubject: RE: [M3devel] Tinderbox failuresDate: Mon, 16 Feb 2009 01:42:25 +0000 Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Mon Feb 16 04:16:27 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sun, 15 Feb 2009 21:16:27 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Message-ID: <4998DA8B.7000605@wichita.edu> I managed to get the trunk back to the original code, as I intended. The Tinderbox failure is undoubtedly a bug in the new stuff. But it leaves me with more CVS questions, see below. Olaf Wagner wrote: > Quoting "Rodney M. Bates" : > >> Well, I can work on compilers, debuggers, and functional text >> packages, but >> I can never operate CVS correctly. >> >> As far as I can tell, I think I got these checkins done in the trunk, >> rather >> than the branch I created for them. I created a tag on the trunk, >> "devel_m3core_text_2009_02_13", then created a branch with tag >> "devel_m3core_text_newtext_branch". Apparently I got that much right. >> >> But I am not sure whether the changed files went into the branch. My >> CVS book reads as if just a cvs tag -b ..., followed by a cvs commit >> will do the commits in the branch, but the commit message doesn't look >> like that happened. >> >> Can anybody help me with: >> 1) What really happened? >> 2) How should I have done this? > > You probably forgot to update your workspace to the branch: > > cvs up -r devel_m3core_text_newtext_branch This command is in the recipe in my book, but my book assumes you make a branch first, get a copy of the trunk code, edit that, then commit. I had done the coding first, naively thinking I could just create a branch when ready to commit it. So I deliberately left this step out, thinking (rightly, as it turned out) that it would overlay my work with the unmodified code. So today, I made safe copies in other directories of both versions and started trying to unravel things. Sure enough, the update -r promptly replaced my new code with the old. I used a different machine to do updates, and quickly found I now had the new code in the trunk and the old code in the branch. And of course, update -A first overlaid the old code I had now put in my text directory with what is in the repository trunk (the modified code), before clearing the sticky tag. By going through procedures doing CVS commands, interspersed with copying versions of the code from my backup directories to the text directory, I managed to get the trunk straightened out, (I think.) But it was convoluted. To do any of this reasonably, I need a command that changes the sticky tag CVS considers me to be working on (like the -r and -A options of update), but without the undesired side effect of also overlaying my local directory with what was in old tagged version, before changing the sticky tag. Is there such a command? I will worry about the getting the new code into the branch tomorrow. > > After that, the branch tag will be `sticky' in your workspace, until > you use cvs up -A, which clears it again (and transports you to the trunk). > >> 3) How can I fix the damage? > > Well, you can easily revert the changes on the main trunk by checking > out the latest version and using -j old-version -j current version, > and then commit it. This should put the old-version at the head of > the trunk again. Before you do that, you should probably commit everything > to the branch, thus you don't need to checkout your version again. > > I think the version before yours was tagged devel_m3core_d2_4_0. > > But perhaps it is not necessary to do this? Have tou had feedback > from others about the new sources? If nothing breaks and performance > gets better, I won't complain ;-) > > Thanks for all the work, > > Olaf > >> PS: I believe that if you use the new files with no additional action, >> that you >> will get the same behavior as before, except that there will be >> considerable >> constant-time slowdown due to lots of instrumentation and dynamic >> deciding to >> use the original algorithms. But I have not tested this. > > So probably some improvements are needed before a release. From dabenavidesd at yahoo.es Mon Feb 16 05:25:53 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 15 Feb 2009 20:25:53 -0800 (PST) Subject: [M3devel] Question about PM3 In-Reply-To: <954132.49377.qm@web24715.mail.ird.yahoo.com> Message-ID: <793526.97016.qm@web24715.mail.ird.yahoo.com> Hi all, Better more accurately to the language definition check before the mentioned line 890: ISTYPE(cur, FIXField.T) OR ISTYPE(f, ProtocolFields.T) (*is cur a member of f's type, FIXField.T or is f? a member of cur's type, ProtocolFields.T, that is ProtocolFields.T <: FIXField? OR FIXField.T <: ProtocolFields.T *)? Thanks and sorry about the forgot detail. --- El dom, 15/2/09, Daniel Alejandro Benavides D. escribi?: De: Daniel Alejandro Benavides D. Asunto: Re: [M3devel] Question about PM3 Para: "Mika Nystrom" CC: m3devel at elegosoft.com Fecha: domingo, 15 febrero, 2009 12:27 Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible that the assignment statement in line 890 is failing and because of the TRY-FINALLY you don't get a Runtime Error (which would be the ideal behaviour if the MODULE is safe and correspondent IMPORT Modules aren't? ill behaved ). 890 f := cur; RETURN TRUEYou could make a sanity check before that line with ?ISTYPE(cur, FIXField.T) (*is cur a member of f's type, FIXField.T *)? Please feel free to ask further questions. Hope this helps. Thanks. --- El s?b, 14/2/09, Mika Nystrom wrote: De: Mika Nystrom Asunto: [M3devel] Question about PM3 Para: m3devel at elegosoft.com Fecha: s?bado, 14 febrero, 2009 1:10 Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Feb 16 06:47:03 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 16 Feb 2009 16:47:03 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4998DA8B.7000605@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> Message-ID: <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> Does the trunk still contain your bug-fixes? On 16 Feb 2009, at 14:16, Rodney M. Bates wrote: > I managed to get the trunk back to the original code, as I intended. > The Tinderbox failure is undoubtedly a bug in the new stuff. But it > leaves me with more CVS questions, see below. > > Olaf Wagner wrote: >> Quoting "Rodney M. Bates" : >>> Well, I can work on compilers, debuggers, and functional text >>> packages, but >>> I can never operate CVS correctly. >>> >>> As far as I can tell, I think I got these checkins done in the >>> trunk, rather >>> than the branch I created for them. I created a tag on the trunk, >>> "devel_m3core_text_2009_02_13", then created a branch with tag >>> "devel_m3core_text_newtext_branch". Apparently I got that much >>> right. >>> >>> But I am not sure whether the changed files went into the branch. >>> My >>> CVS book reads as if just a cvs tag -b ..., followed by a cvs commit >>> will do the commits in the branch, but the commit message doesn't >>> look >>> like that happened. >>> >>> Can anybody help me with: >>> 1) What really happened? >>> 2) How should I have done this? >> You probably forgot to update your workspace to the branch: >> cvs up -r devel_m3core_text_newtext_branch > > This command is in the recipe in my book, but my book assumes you make > a branch first, get a copy of the trunk code, edit that, then commit. > I had done the coding first, naively thinking I could just create a > branch > when ready to commit it. So I deliberately left this step out, > thinking > (rightly, as it turned out) that it would overlay my work with the > unmodified code. > > So today, I made safe copies in other directories of both versions and > started trying to unravel things. Sure enough, the update -r > promptly > replaced my new code with the old. I used a different machine to do > updates, and quickly found I now had the new code in the trunk and the > old code in the branch. > > And of course, update -A first overlaid the old code I had now put in > my text directory with what is in the repository trunk (the modified > code), before clearing the sticky tag. > > By going through procedures doing CVS commands, interspersed with > copying > versions of the code from my backup directories to the text > directory, I > managed to get the trunk straightened out, (I think.) > > But it was convoluted. To do any of this reasonably, I need a command > that changes the sticky tag CVS considers me to be working on (like > the -r and > -A options of update), but without the undesired side effect of also > overlaying my local directory with what was in old tagged version, > before changing the sticky tag. Is there such a command? > > I will worry about the getting the new code into the branch tomorrow. > >> After that, the branch tag will be `sticky' in your workspace, until >> you use cvs up -A, which clears it again (and transports you to the >> trunk). >>> 3) How can I fix the damage? >> Well, you can easily revert the changes on the main trunk by checking >> out the latest version and using -j old-version -j current version, >> and then commit it. This should put the old-version at the head of >> the trunk again. Before you do that, you should probably commit >> everything >> to the branch, thus you don't need to checkout your version again. >> I think the version before yours was tagged devel_m3core_d2_4_0. >> But perhaps it is not necessary to do this? Have tou had feedback >> from others about the new sources? If nothing breaks and performance >> gets better, I won't complain ;-) >> Thanks for all the work, >> Olaf >>> PS: I believe that if you use the new files with no additional >>> action, >>> that you >>> will get the same behavior as before, except that there will be >>> considerable >>> constant-time slowdown due to lots of instrumentation and dynamic >>> deciding to >>> use the original algorithms. But I have not tested this. >> So probably some improvements are needed before a release. From wagner at elegosoft.com Mon Feb 16 11:36:16 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 16 Feb 2009 11:36:16 +0100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4998DA8B.7000605@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> Message-ID: <20090216113616.blncsdl9q88kwkcg@mail.elegosoft.com> Quoting "Rodney M. Bates" : > I managed to get the trunk back to the original code, as I intended. > The Tinderbox failure is undoubtedly a bug in the new stuff. But it > leaves me with more CVS questions, see below. [...] >> cvs up -r devel_m3core_text_newtext_branch > > This command is in the recipe in my book, but my book assumes you make > a branch first, get a copy of the trunk code, edit that, then commit. > I had done the coding first, naively thinking I could just create a branch > when ready to commit it. So I deliberately left this step out, thinking > (rightly, as it turned out) that it would overlay my work with the > unmodified code. > > So today, I made safe copies in other directories of both versions and > started trying to unravel things. Sure enough, the update -r promptly > replaced my new code with the old. I used a different machine to do > updates, and quickly found I now had the new code in the trunk and the > old code in the branch. > > And of course, update -A first overlaid the old code I had now put in > my text directory with what is in the repository trunk (the modified > code), before clearing the sticky tag. > > By going through procedures doing CVS commands, interspersed with copying > versions of the code from my backup directories to the text directory, I > managed to get the trunk straightened out, (I think.) > > But it was convoluted. To do any of this reasonably, I need a command > that changes the sticky tag CVS considers me to be working on (like > the -r and > -A options of update), but without the undesired side effect of also > overlaying my local directory with what was in old tagged version, > before changing the sticky tag. Is there such a command? > > I will worry about the getting the new code into the branch tomorrow. You should have switched your workspace to the branch before changing the code or before the first commit. Then it would have been straight forward. The general way to fix things like this is a three-point merge. You use two -j options to specify the diff to be applied to your workspace and then commit it (after validating the consistency, of course). So yo get the changes from trunk to branch you (1) update your workspace to the branch top (cvs up -r devel_m3core_text_newtext_branch) (2) merge from the branch point to the tag containing you changes on the trunk, for example by cvs up -j devel_m3core_text_newtext_branch_bp \ -j erroneously_committed_version_on_trunk (I don't know what tag applies here offhand) AFAIK there is no command to change the workspace sticky tag without changing the sources. Regards, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From rodney.bates at wichita.edu Mon Feb 16 18:57:04 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Mon, 16 Feb 2009 11:57:04 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> Message-ID: <4999A8F0.50801@wichita.edu> No, the trunk right now is as it was before I started working on it, which, I believe, has been unchanged for years. I guess it's confusing, as my way of putting it back probably gives recent dates and new version numbers on everything. I guess I could backport the bug fixes into the trunk. Tony Hosking wrote: > Does the trunk still contain your bug-fixes? > From jay.krell at cornell.edu Tue Feb 17 01:00:01 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 00:00:01 +0000 Subject: [M3devel] suggestion for "atomic ops" In-Reply-To: References: Message-ID: [replaced m3commit with m3devel..] Let a code generator advertise that it doesn't support them. And if so, instead generate a call to some set of functions. I realize this fallback could be implemented in the code generators themselves. Windows has various "interlocked" functions that should make this easy. Thanks, - Jay From hosking at cs.purdue.edu Tue Feb 17 01:24:04 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 17 Feb 2009 11:24:04 +1100 Subject: [M3devel] suggestion for "atomic ops" In-Reply-To: References: Message-ID: <901A0F1B-84F1-4182-BD14-2BAFF3D848B6@cs.purdue.edu> With the gcc-based backend we get exactly that behavior. On 17 Feb 2009, at 11:00, Jay wrote: > > [replaced m3commit with m3devel..] > > Let a code generator advertise that it doesn't support them. > And if so, instead generate a call to some set of functions. > I realize this fallback could be implemented in the code generators > themselves. > Windows has various "interlocked" functions that should make this > easy. > > Thanks, > - Jay From hosking at cs.purdue.edu Tue Feb 17 03:57:17 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 17 Feb 2009 13:57:17 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4999A8F0.50801@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> Message-ID: <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Yes, it would be good to get the bugfixes in separately from your current new TEXT development branch. On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: > No, the trunk right now is as it was before I started working on it, > which, I believe, has been unchanged for years. I guess it's > confusing, > as my way of putting it back probably gives recent dates and new > version > numbers on everything. > > I guess I could backport the bug fixes into the trunk. > > Tony Hosking wrote: >> Does the trunk still contain your bug-fixes? From jay.krell at cornell.edu Tue Feb 17 04:33:46 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 03:33:46 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Message-ID: Rodney, "it seems obvious" the problem was related to: PROCEDURE Bar(start: INTEGER); PROCEDURE Foo(start := LAST(INTEGER)) = BEGIN Bar(start + 1); END Foo; LAST(INTEGER) + 1 => error Though I grant, that is about all I looked at, couldn't be much shallower of an analysis. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: rodney.bates at wichita.edu > Date: Tue, 17 Feb 2009 13:57:17 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Yes, it would be good to get the bugfixes in separately from your > current new TEXT development branch. > > On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: > >> No, the trunk right now is as it was before I started working on it, >> which, I believe, has been unchanged for years. I guess it's >> confusing, >> as my way of putting it back probably gives recent dates and new >> version >> numbers on everything. >> >> I guess I could backport the bug fixes into the trunk. >> >> Tony Hosking wrote: >>> Does the trunk still contain your bug-fixes? > From wagner at elegosoft.com Tue Feb 17 08:01:35 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Tue, 17 Feb 2009 08:01:35 +0100 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: <90251234839259@webmail63.yandex.ru> References: <90251234839259@webmail63.yandex.ru> Message-ID: <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Quoting ??????? ????? : > Hello! At first, excuse me, but my english is very-very bad! > > 1. I try to build CM3 on Windows XP with MinGW toolset. But when I > build m3core and libm3, there are many errors appears. I use > cm3-min-WIN32-NT386GNU-d5.5.1 and > cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how > to build m3core and libm3? All other libraries and packages I'll > build manually. This may be best answered on the m3devel list, but you'll probably have to provide some more details as to the many errors. There should be a binary installation archive for CM3 based on Cygwin in the upload area of www.opencm3.net. > 2. Tell me please, may I put binary package of CM3 for Win32 on my > own site for public downloads? That should be no problem. You can also upload new packages you want to publish to www.opencm3.net. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Tue Feb 17 08:20:13 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 07:20:13 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: NT386GNU corresponds to cygwin. It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. NT386MINGNU corresponds to mingwin. It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. NT386MINGNU was working, at least for command line apps. I can spin another build, make sure it still works, and maybe get around to fixing gui apps. (I think I'll just put in a small workaround for the gui issue.) In the meantime, can try cygwin? Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? - Jay ---------------------------------------- > Date: Tue, 17 Feb 2009 08:01:35 +0100 > From: wagner at elegosoft.com > To: rv82 at ya.ru > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > Quoting ??????? ????? : > >> Hello! At first, excuse me, but my english is very-very bad! >> >> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I >> build m3core and libm3, there are many errors appears. I use >> cm3-min-WIN32-NT386GNU-d5.5.1 and >> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how >> to build m3core and libm3? All other libraries and packages I'll >> build manually. > > This may be best answered on the m3devel list, but you'll probably have > to provide some more details as to the many errors. > There should be a binary installation archive for CM3 based on > Cygwin in the upload area of www.opencm3.net. > >> 2. Tell me please, may I put binary package of CM3 for Win32 on my >> own site for public downloads? > > That should be no problem. You can also upload new packages you > want to publish to www.opencm3.net. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > From jay.krell at cornell.edu Tue Feb 17 08:35:43 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 07:35:43 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: (ps: more complete list: NT386GNU: gcc backend gcc for C compiler gcc/GNU ld for linker cygwin C runtime X windows pthreads forward slashes on paths debuggable with gdb ("stabs" debug format) or printf.. NT386MINGNU gcc backend gcc for C compiler gcc/GNU ld for linker MS C runtime (provided by mingw's gcc) I think debuggable with gdb. ("stabs" debug format) or printf.. Win32 windows Win32 threads backwards slashes on paths, or forward NT386: integrated backend -- very fast no 64 bit LONGINT Visual C++ compiler/linker/runtime Win32 thread/windows backwards slashes on paths, or forward debugable with Visual Studio/cdb/ntsd/windbg ("CodeView" debug format), not gdb or printf.. ) The various factors are mixable/matchable to SOME extent, but they aren't tested, they might be confusing, and they don't all work necessarily. These are "friendly" names to encompass a set of underlying factors. I think I386_NT or I386_MSWIN, I386_CYGWIN, I386_MINGWIN might be better names. (I would avoid saying "WIN32" anywhere, due to Windows also running on IA64 and AMD64). - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: wagner at elegosoft.com; rv82 at ya.ru > Date: Tue, 17 Feb 2009 07:20:13 +0000 > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > > NT386GNU corresponds to cygwin. > It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. > > > NT386MINGNU corresponds to mingwin. > It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. > > > NT386MINGNU was working, at least for command line apps. > > I can spin another build, make sure it still works, and maybe get around to fixing gui apps. > (I think I'll just put in a small workaround for the gui issue.) > > > In the meantime, can try cygwin? > > > Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? > > > - Jay > > > > ---------------------------------------- >> Date: Tue, 17 Feb 2009 08:01:35 +0100 >> From: wagner at elegosoft.com >> To: rv82 at ya.ru >> CC: m3devel at elegosoft.com; m3-support at elego.de >> Subject: Re: [M3devel] CM3 on Win32 (MinGW) >> >> Quoting ??????? ????? : >> >>> Hello! At first, excuse me, but my english is very-very bad! >>> >>> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I >>> build m3core and libm3, there are many errors appears. I use >>> cm3-min-WIN32-NT386GNU-d5.5.1 and >>> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how >>> to build m3core and libm3? All other libraries and packages I'll >>> build manually. >> >> This may be best answered on the m3devel list, but you'll probably have >> to provide some more details as to the many errors. >> There should be a binary installation archive for CM3 based on >> Cygwin in the upload area of www.opencm3.net. >> >>> 2. Tell me please, may I put binary package of CM3 for Win32 on my >>> own site for public downloads? >> >> That should be no problem. You can also upload new packages you >> want to publish to www.opencm3.net. >> >> Olaf >> -- >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 >> From jay.krell at cornell.edu Wed Feb 18 12:27:23 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 11:27:23 +0000 Subject: [M3devel] FW: winRes.tmpl/mingw/rc/windres/etc. In-Reply-To: <20090218105139.4860F10D4261@birch.elegosoft.com> References: <20090218105139.4860F10D4261@birch.elegosoft.com> Message-ID: I think this code should be moved into the config files. ? All non-Windows config files would just say: readonly proc WindowsResource (file) isendand then NT386.common would have the current content of winRes.tmpl. Thoughts? More so, cm3.exe should just implement proc WindowsResource (file) isend without readonly, and then NT386.common can replace it. The others can leave it alone. Thoughts? I'm not really sure what should be "core" vs. what should be "an extension". It is nice to have such an extensible system, but it can also be bad. Besides that, Windows has a nice feature called "version resources". If nothing else, every .dll/.exe should have one. cm3 should give everyone some default. imho. - Jay> Date: Wed, 18 Feb 2009 11:51:39 +0000> To: m3commit at elegosoft.com> From: jkrell at elego.de> Subject: [M3commit] CVS Update: cm3> > CVSROOT: /usr/cvs> Changes by: jkrell at birch. 09/02/18 11:51:39> > Modified files:> cm3/m3-sys/windowsResources/src/: winRes.tmpl > > Log message:> adapt to MinGW which has windres instead of rc with different command line usage; detect MinGW by checking if backend mode is integrated backend or not, not great..it should really be informed by a variable in the toplevel configuration -- CONFIG_HAS_RC and CONFIG_HAS_WINDRES?> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 18 12:40:54 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 11:40:54 +0000 Subject: [M3devel] FW: winRes.tmpl/mingw/rc/windres/etc. In-Reply-To: <20090218105139.4860F10D4261@birch.elegosoft.com> References: <20090218105139.4860F10D4261@birch.elegosoft.com> Message-ID: [truncated..] From: jay.krell at cornell.eduTo: m3devel at elegosoft.comSubject: FW: winRes.tmpl/mingw/rc/windres/etc.Date: Wed, 18 Feb 2009 11:27:23 +0000 I think this code should be moved into the config files. ?All non-Windows config files would just say: readonly proc WindowsResource (file) isendand then NT386.common would have the current content of winRes.tmpl. Thoughts? More so, cm3.exe should just implementproc WindowsResource (file) isendwithout readonly, and then NT386.common can replace it.The others can leave it alone. Thoughts? I'm not really sure what should be "core" vs. what should be "an extension".It is nice to have such an extensible system, but it can also be bad. Besides that, Windows has a nice feature called "version resources".If nothing else, every .dll/.exe should have one.cm3 should give everyone some default.imho. - Jay> Date: Wed, 18 Feb 2009 11:51:39 +0000> To: m3commit at elegosoft.com> From: jkrell at elego.de> Subject: [M3commit] CVS Update: cm3> > CVSROOT: /usr/cvs> Changes by: jkrell at birch. 09/02/18 11:51:39> > Modified files:> cm3/m3-sys/windowsResources/src/: winRes.tmpl > > Log message:> adapt to MinGW which has windres instead of rc with different command line usage; detect MinGW by checking if backend mode is integrated backend or not, not great..it should really be informed by a variable in the toplevel configuration -- CONFIG_HAS_RC and CONFIG_HAS_WINDRES?> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 18 18:58:04 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 17:58:04 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: Please try: http://modula3.elegosoft.com/cm3/uploaded-archives/cm3-min-NT386MINGNU-d5.7.1.tar.gz or: http://modula3.elegosoft.com/cm3/uploaded-archives/cm3-std-NT386MINGNU-d5.7.1.tar.gz I know many of the gui apps crash pretty early, in ways that don't look gui-app-specific. - Jay > From: jay.krell at cornell.edu > To: wagner at elegosoft.com; rv82 at ya.ru > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: RE: [M3devel] CM3 on Win32 (MinGW) > Date: Tue, 17 Feb 2009 07:35:43 +0000 > > > (ps: more complete list: > > > NT386GNU: > gcc backend > gcc for C compiler > gcc/GNU ld for linker > cygwin C runtime > X windows > pthreads > forward slashes on paths > debuggable with gdb ("stabs" debug format) > or printf.. > > > NT386MINGNU > gcc backend > gcc for C compiler > gcc/GNU ld for linker > MS C runtime (provided by mingw's gcc) > I think debuggable with gdb. ("stabs" debug format) > or printf.. > Win32 windows > Win32 threads > backwards slashes on paths, or forward > > > NT386: > integrated backend -- very fast > no 64 bit LONGINT > Visual C++ compiler/linker/runtime > Win32 thread/windows > backwards slashes on paths, or forward > debugable with Visual Studio/cdb/ntsd/windbg ("CodeView" debug format), not gdb > or printf.. > ) > > > The various factors are mixable/matchable to SOME extent, but they aren't tested, they might be confusing, and they don't all work necessarily. > These are "friendly" names to encompass a set of underlying factors. > I think I386_NT or I386_MSWIN, I386_CYGWIN, I386_MINGWIN might be better names. > (I would avoid saying "WIN32" anywhere, due to Windows also running on IA64 and AMD64). > > > - Jay > > > > ---------------------------------------- > > From: jay.krell at cornell.edu > > To: wagner at elegosoft.com; rv82 at ya.ru > > Date: Tue, 17 Feb 2009 07:20:13 +0000 > > CC: m3devel at elegosoft.com; m3-support at elego.de > > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > > > > > NT386GNU corresponds to cygwin. > > It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. > > > > > > NT386MINGNU corresponds to mingwin. > > It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. > > > > > > NT386MINGNU was working, at least for command line apps. > > > > I can spin another build, make sure it still works, and maybe get around to fixing gui apps. > > (I think I'll just put in a small workaround for the gui issue.) > > > > > > In the meantime, can try cygwin? > > > > > > Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? > > > > > > - Jay > > > > > > > > ---------------------------------------- > >> Date: Tue, 17 Feb 2009 08:01:35 +0100 > >> From: wagner at elegosoft.com > >> To: rv82 at ya.ru > >> CC: m3devel at elegosoft.com; m3-support at elego.de > >> Subject: Re: [M3devel] CM3 on Win32 (MinGW) > >> > >> Quoting ??????? ????? : > >> > >>> Hello! At first, excuse me, but my english is very-very bad! > >>> > >>> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I > >>> build m3core and libm3, there are many errors appears. I use > >>> cm3-min-WIN32-NT386GNU-d5.5.1 and > >>> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how > >>> to build m3core and libm3? All other libraries and packages I'll > >>> build manually. > >> > >> This may be best answered on the m3devel list, but you'll probably have > >> to provide some more details as to the many errors. > >> There should be a binary installation archive for CM3 based on > >> Cygwin in the upload area of www.opencm3.net. > >> > >>> 2. Tell me please, may I put binary package of CM3 for Win32 on my > >>> own site for public downloads? > >> > >> That should be no problem. You can also upload new packages you > >> want to publish to www.opencm3.net. > >> > >> Olaf > >> -- > >> Olaf Wagner -- elego Software Solutions GmbH > >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Thu Feb 19 03:02:55 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Wed, 18 Feb 2009 20:02:55 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Message-ID: <499CBDCF.6080001@wichita.edu> Yes. This is a wonderful example of a half bugfix. Original code was String8.FindCharR (i.start, MIN (i.length, start), c); start is off by one here and needs to be increased by one, so I changed it to String8.FindCharR (i.start, MIN (i.length, start+1), c); This is correct for every case except start=LAST(INTEGER), (which is likely to happen because it is the defaulted value of parameter start). Even so, I thought the MIN function should take care of this, but the intermediate value of start+1 overflows silently, wraps around to FIRST(INTEGER), and becomes the minimum. So now its: String8.FindCharR (i.start, MIN (i.length-1, start)+1, c); which can have the same problem on the low end, i.e., it can go temporarily negative by one, but that is OK because the intermediate arithmetic is done in INTEGER, and the final result will always end up at least zero, within the needed range of CARDINAL. This would make a good textbook example. Jay wrote: > Rodney, "it seems obvious" the problem was related to: > > PROCEDURE Bar(start: INTEGER); > > PROCEDURE Foo(start := LAST(INTEGER)) = > BEGIN > Bar(start + 1); > END Foo; > > LAST(INTEGER) + 1 => error > Though I grant, that is about all I looked at, > couldn't be much shallower of an analysis. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: rodney.bates at wichita.edu >> Date: Tue, 17 Feb 2009 13:57:17 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Yes, it would be good to get the bugfixes in separately from your >> current new TEXT development branch. >> >> On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: >> >>> No, the trunk right now is as it was before I started working on it, >>> which, I believe, has been unchanged for years. I guess it's >>> confusing, >>> as my way of putting it back probably gives recent dates and new >>> version >>> numbers on everything. >>> >>> I guess I could backport the bug fixes into the trunk. >>> >>> Tony Hosking wrote: >>>> Does the trunk still contain your bug-fixes? >> From rodney.bates at wichita.edu Sat Feb 21 00:36:07 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 20 Feb 2009 17:36:07 -0600 Subject: [M3devel] Assert failure in ThreadPThread.m3 Message-ID: <499F3E67.9080605@wichita.edu> I got an assertion failure in ThreadPThread.m3. Here is a transcript. Below that is a more helpful backtrace I got by manually stopping it as quickly as I could after the assertion failure messages. I think the second backtrace is not on the relevant thread however, because commenting out the Thread.Pause does not make the failure go away, just makes it harder to catch. Note: I have a lot of weakref cleanups registered. Executing RTCollector.Disable ( ) early in the program and leaving it disabled makes the problem go away. --------------------------------------------------------------------------------------------------------------------- rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/newtext/src$ m3gdb test GNU gdb plus Modula-3 6.4 Copyright 2005 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (m3gdb) run -nos Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/newtext/src/test -nos Signal Stop Print Pass to program Description SIG64 No No Yes Real-time event 64 [Thread debugging using libthread_db enabled] [New LWP 32595] Estimating overhead of timing. Generating initial leaf strings. Generating initial leaf strings. 0\ Garbage collection disabled for better timing. 62[New Thread -1220703344 (LWP 32598)] [New Thread -1220429104 (LWP 32595)] ....+....1....+....2....+....3....+....4....+....| 5000....+....6....+....7....+....8....+....9....+....| 10000....+....1....+....2....+....3....+....4....+....| 15000....+....6....+....7....+....8....+....9....+....| 20000....+....1....+....2....+....3....+....4....+....| 25000....+....6....+....7....+....8....+....9....+....| 30000....+....1....+....2....+....3....+....4....+....| 35000....+....6....+....7....+....8....+....9....+....| 40000....+....1....+....2....+....3....+....4....+....| 45000....+....6....+....7....+....8....+....9....+....| 50000 Garbage collection enabled and triggered ... *** *** runtime error: *** <*ASSERT*> failed. *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 *** Garbage collection completed. Program received signal SIGINT, Interrupt. [Switching to Thread -1220429104 (LWP 32595)] 0xb7f7d410 in __kernel_vsyscall () (m3gdb) bt #0 0xb7f7d410 in __kernel_vsyscall () #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/libpthread.so.0 ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI encountered. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) y ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI encountered. A problem internal to GDB has been detected, further debugging may prove unreliable. Create a core file of GDB? (y or n) y Aborted (core dumped) --------------------------------------------------------------------------------------------------------------------- Garbage collection enabled and triggered ... *** *** runtime error: *** <*ASSERT*> failed. *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 *** Program received signal SIGINT, Interrupt. [Switching to Thread -1220732208 (LWP 32623)] 0xb7f33410 in __kernel_vsyscall () (m3gdb) bt #0 0xb7f33410 in __kernel_vsyscall () #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 Can't find child block 1, at level 1, of parent procedure "Test__GetParams", for nested procedure "Test__GetParams__1__1__NumArg.778" #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol table. ) at ../src/Test.m3:1628 #6 0x0805b764 in Work () at ../src/Test.m3:2536 #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol table. ) at ../src/Test.m3:2658 #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in symbol table. ) at ../src/runtime/common/RTLinker.m3:399 #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol table. ) at ../src/runtime/common/RTLinker.m3:113 #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol table. ) at ../src/runtime/common/RTLinker.m3:122 #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at _m3main.mc:4 #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #13 0x08049ed1 in _start () (m3gdb) frame 4 #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 1354 ; Thread . Pause ( 2.0D0 ) Current language: auto; currently Modula-3 (m3gdb) down #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 668 XPause(self, n, alertable := FALSE); (m3gdb) down #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 651 WITH r = Utime.nanosleep(amount, remaining) DO (m3gdb) down #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/libpthread.so.0 (m3gdb) down #0 0xb7f33410 in __kernel_vsyscall () (m3gdb) --------------------------------------------------------------------------------------------------------------------- From hosking at cs.purdue.edu Sat Feb 21 01:52:44 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 21 Feb 2009 11:52:44 +1100 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: <499F3E67.9080605@wichita.edu> References: <499F3E67.9080605@wichita.edu> Message-ID: <234E7866-DDEC-478D-A620-EF697873AF1A@cs.purdue.edu> Looks like a spurious wakeup. Let me look in to it. Perhaps broken by my recent changes. On 21 Feb 2009, at 10:36, Rodney M. Bates wrote: > I got an assertion failure in ThreadPThread.m3. > > Here is a transcript. Below that is a more helpful backtrace I got by > manually stopping it as quickly as I could after the assertion failure > messages. I think the second backtrace is not on the relevant thread > however, because commenting out the Thread.Pause does not make the > failure > go away, just makes it harder to catch. > > Note: I have a lot of weakref cleanups registered. Executing > RTCollector.Disable ( ) early in the program and leaving it > disabled makes the problem go away. > > > --------------------------------------------------------------------------------------------------------------------- > > rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/ > newtext/src$ m3gdb test > GNU gdb plus Modula-3 6.4 > Copyright 2005 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and > you are > welcome to change it and/or distribute copies of it under certain > conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for > details. > This GDB was configured as "i686-pc-linux-gnu"...Using host > libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". > > (m3gdb) run -nos > Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/ > tests/newtext/src/test -nos > Signal Stop Print Pass to program Description > SIG64 No No Yes Real-time event 64 > [Thread debugging using libthread_db enabled] > [New LWP 32595] > Estimating overhead of timing. > Generating initial leaf strings. > Generating initial leaf strings. > > 0\ > Garbage collection disabled for better timing. > > 62[New Thread -1220703344 (LWP 32598)] > [New Thread -1220429104 (LWP 32595)] > ....+....1....+....2....+....3....+....4....+....| > 5000....+....6....+....7....+....8....+....9....+....| > 10000....+....1....+....2....+....3....+....4....+....| > 15000....+....6....+....7....+....8....+....9....+....| > 20000....+....1....+....2....+....3....+....4....+....| > 25000....+....6....+....7....+....8....+....9....+....| > 30000....+....1....+....2....+....3....+....4....+....| > 35000....+....6....+....7....+....8....+....9....+....| > 40000....+....1....+....2....+....3....+....4....+....| > 45000....+....6....+....7....+....8....+....9....+....| > 50000 > > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > Garbage collection completed. > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220429104 (LWP 32595)] > 0xb7f7d410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f7d410 in __kernel_vsyscall () > #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/ > libpthread.so.0 > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Quit this debugging session? (y or n) y > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Create a core file of GDB? (y or n) y > Aborted (core dumped) > --------------------------------------------------------------------------------------------------------------------- > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220732208 (LWP 32623)] > 0xb7f33410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f33410 in __kernel_vsyscall () > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol > table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > Can't find child block 1, at level 1, of parent procedure > "Test__GetParams", for nested procedure > "Test__GetParams__1__1__NumArg.778" > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol > table. > ) at ../src/Test.m3:1628 > #6 0x0805b764 in Work () at ../src/Test.m3:2536 > #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol > table. > ) at ../src/Test.m3:2658 > #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in > symbol table. > ) at ../src/runtime/common/RTLinker.m3:399 > #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:113 > #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:122 > #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at > _m3main.mc:4 > #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/ > libc.so.6 > #13 0x08049ed1 in _start () > (m3gdb) frame 4 > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > 1354 ; Thread . Pause ( 2.0D0 ) > Current language: auto; currently Modula-3 > (m3gdb) down > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > 668 XPause(self, n, alertable := FALSE); > (m3gdb) down > #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type > code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > 651 WITH r = Utime.nanosleep(amount, remaining) DO > (m3gdb) down > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > (m3gdb) down > #0 0xb7f33410 in __kernel_vsyscall () > (m3gdb) > > > --------------------------------------------------------------------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Feb 21 02:29:05 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 21 Feb 2009 12:29:05 +1100 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: <499F3E67.9080605@wichita.edu> References: <499F3E67.9080605@wichita.edu> Message-ID: Rodney, I see what the problem is. Please try with the latest version of ThreadPThread.m3. -- Tony On 21 Feb 2009, at 10:36, Rodney M. Bates wrote: > I got an assertion failure in ThreadPThread.m3. > > Here is a transcript. Below that is a more helpful backtrace I got by > manually stopping it as quickly as I could after the assertion failure > messages. I think the second backtrace is not on the relevant thread > however, because commenting out the Thread.Pause does not make the > failure > go away, just makes it harder to catch. > > Note: I have a lot of weakref cleanups registered. Executing > RTCollector.Disable ( ) early in the program and leaving it > disabled makes the problem go away. > > > --------------------------------------------------------------------------------------------------------------------- > > rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/ > newtext/src$ m3gdb test > GNU gdb plus Modula-3 6.4 > Copyright 2005 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and > you are > welcome to change it and/or distribute copies of it under certain > conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for > details. > This GDB was configured as "i686-pc-linux-gnu"...Using host > libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". > > (m3gdb) run -nos > Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/ > tests/newtext/src/test -nos > Signal Stop Print Pass to program Description > SIG64 No No Yes Real-time event 64 > [Thread debugging using libthread_db enabled] > [New LWP 32595] > Estimating overhead of timing. > Generating initial leaf strings. > Generating initial leaf strings. > > 0\ > Garbage collection disabled for better timing. > > 62[New Thread -1220703344 (LWP 32598)] > [New Thread -1220429104 (LWP 32595)] > ....+....1....+....2....+....3....+....4....+....| > 5000....+....6....+....7....+....8....+....9....+....| > 10000....+....1....+....2....+....3....+....4....+....| > 15000....+....6....+....7....+....8....+....9....+....| > 20000....+....1....+....2....+....3....+....4....+....| > 25000....+....6....+....7....+....8....+....9....+....| > 30000....+....1....+....2....+....3....+....4....+....| > 35000....+....6....+....7....+....8....+....9....+....| > 40000....+....1....+....2....+....3....+....4....+....| > 45000....+....6....+....7....+....8....+....9....+....| > 50000 > > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > Garbage collection completed. > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220429104 (LWP 32595)] > 0xb7f7d410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f7d410 in __kernel_vsyscall () > #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/ > libpthread.so.0 > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Quit this debugging session? (y or n) y > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Create a core file of GDB? (y or n) y > Aborted (core dumped) > --------------------------------------------------------------------------------------------------------------------- > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220732208 (LWP 32623)] > 0xb7f33410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f33410 in __kernel_vsyscall () > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol > table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > Can't find child block 1, at level 1, of parent procedure > "Test__GetParams", for nested procedure > "Test__GetParams__1__1__NumArg.778" > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol > table. > ) at ../src/Test.m3:1628 > #6 0x0805b764 in Work () at ../src/Test.m3:2536 > #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol > table. > ) at ../src/Test.m3:2658 > #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in > symbol table. > ) at ../src/runtime/common/RTLinker.m3:399 > #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:113 > #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:122 > #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at > _m3main.mc:4 > #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/ > libc.so.6 > #13 0x08049ed1 in _start () > (m3gdb) frame 4 > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > 1354 ; Thread . Pause ( 2.0D0 ) > Current language: auto; currently Modula-3 > (m3gdb) down > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > 668 XPause(self, n, alertable := FALSE); > (m3gdb) down > #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type > code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > 651 WITH r = Utime.nanosleep(amount, remaining) DO > (m3gdb) down > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > (m3gdb) down > #0 0xb7f33410 in __kernel_vsyscall () > (m3gdb) > > > --------------------------------------------------------------------------------------------------------------------- From rodney.bates at wichita.edu Sat Feb 21 03:51:04 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 20 Feb 2009 20:51:04 -0600 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: References: <499F3E67.9080605@wichita.edu> Message-ID: <499F6C18.2070101@wichita.edu> Thanks, that fixed it. Tony Hosking wrote: > Rodney, > > I see what the problem is. Please try with the latest version of > ThreadPThread.m3. > > -- Tony > From rodney.bates at wichita.edu Mon Feb 23 02:53:26 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sun, 22 Feb 2009 19:53:26 -0600 Subject: [M3devel] New Text branch introduces no build failures on LINUXLIBC6 Message-ID: <49A20196.3050101@wichita.edu> A second generation compiler using the new Text branch now builds everything in so-cm3-all.sh, on LINUXLIBC6, with no failures that are not already present when building using the trunk Text code. Rodney Bates. From wagner at elegosoft.com Wed Feb 25 08:05:03 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 25 Feb 2009 08:05:03 +0100 Subject: [M3devel] cm3 builds broken Message-ID: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> I noticed that all recent tinderbox builds failed: http://tinderbox.elegosoft.com/tinderbox/cm3/status.html Rodney and Jay, please have a look (you were the last to commit). Thanks, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 25 08:43:37 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 25 Feb 2009 07:43:37 +0000 Subject: [M3devel] cm3 builds broken In-Reply-To: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> References: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> Message-ID: I wish the Tinderbox could send some mail for failures, not too many, but some. 4487 "../src/text/TextCat.m3", line 56: unknown qualification ?.? (NoteIter) 4488 "../src/text/TextCat.m3", line 56: unknown qualification ?.? (Op) Rodney? >From my read a week+ ago, this is just debug/perf tracing from the new branch and can be removed in the mainline if the mainline only has the small bug fixes. - Jay > Date: Wed, 25 Feb 2009 08:05:03 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: [M3devel] cm3 builds broken > > I noticed that all recent tinderbox builds failed: > > http://tinderbox.elegosoft.com/tinderbox/cm3/status.html > > Rodney and Jay, please have a look (you were the last to commit). > > Thanks, > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 25 18:30:36 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 25 Feb 2009 17:30:36 +0000 Subject: [M3devel] scan_float Message-ID: Hm, scan_float is probably wrong, when crossing that changes endianness. PA is big endian. Crossing from little endian Cygwin, in TimePosix.ms I have: L$C0003: .word 0 .word 1093567616 TimePosix__FromUtime .PROC .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 .ENTRY copy %r3,%r1 copy %r30,%r3 stwm %r1,64(%r30) stw %r3,-4(%r30) stw %r19,-32(%r30) stw %r26,-36(%r3) L$M0009: ldw -36(%r3),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr24 ldw -36(%r3),%r28 ldo 4(%r28),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr23 addil LT'L$C0003,%r19 ldw RT'L$C0003(%r1),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr23,%fr22,%fr22 fadd,dbl %fr24,%fr22,%fr22 and Utime_M3 hangs. Yet it I write the equivalent C code on the target system I get: L$C0000: .word 1093567616 .word 0 .SPACE $TEXT$ .NSUBSPA $CODE$ .align 4 .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU FromUtime: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY fldws 4(%r26),%fr22L fcnvxf,sgl,dbl %fr22L,%fr4 ldil LR'L$C0000,%r28 fldws 0(%r26),%fr23L ldo RR'L$C0000(%r28),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr4,%fr22,%fr4 fcnvxf,sgl,dbl %fr23L,%fr24 bv %r0(%r2) fadd,dbl %fr24,%fr4,%fr4 I'll dig into it more later.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Feb 26 00:07:35 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 26 Feb 2009 10:07:35 +1100 Subject: [M3devel] scan_float In-Reply-To: References: Message-ID: I think you wrote the most recent version of that code. Can you take a look? On 26 Feb 2009, at 04:30, Jay wrote: > Hm, scan_float is probably wrong, when crossing that changes > endianness. > PA is big endian. > Crossing from little endian Cygwin, in TimePosix.ms I have: > > L$C0003: > .word 0 > .word 1093567616 > > TimePosix__FromUtime > .PROC > .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 > .ENTRY > copy %r3,%r1 > copy %r30,%r3 > stwm %r1,64(%r30) > stw %r3,-4(%r30) > stw %r19,-32(%r30) > stw %r26,-36(%r3) > L$M0009: > ldw -36(%r3),%r28 > fldws 0(%r28),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr24 > ldw -36(%r3),%r28 > ldo 4(%r28),%r28 > fldws 0(%r28),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr23 > addil LT'L$C0003,%r19 > ldw RT'L$C0003(%r1),%r28 > fldds 0(%r28),%fr22 > fdiv,dbl %fr23,%fr22,%fr22 > fadd,dbl %fr24,%fr22,%fr22 > > > and Utime_M3 hangs. > > > Yet it I write the equivalent C code on the target system I get: > > > L$C0000: > .word 1093567616 > .word 0 > .SPACE $TEXT$ > .NSUBSPA $CODE$ > .align 4 > .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU > FromUtime: > .PROC > .CALLINFO FRAME=0,NO_CALLS > .ENTRY > fldws 4(%r26),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr4 > ldil LR'L$C0000,%r28 > fldws 0(%r26),%fr23L > ldo RR'L$C0000(%r28),%r28 > fldds 0(%r28),%fr22 > fdiv,dbl %fr4,%fr22,%fr4 > fcnvxf,sgl,dbl %fr23L,%fr24 > bv %r0(%r2) > fadd,dbl %fr24,%fr4,%fr4 > > > I'll dig into it more later.. > > > - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 26 01:07:24 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 26 Feb 2009 00:07:24 +0000 Subject: [M3devel] scan_float In-Reply-To: References: Message-ID: Yes. From: hosking at cs.purdue.edu To: jay.krell at cornell.edu Date: Thu, 26 Feb 2009 10:07:35 +1100 CC: m3devel at elegosoft.com Subject: Re: [M3devel] scan_float I think you wrote the most recent version of that code. Can you take a look? On 26 Feb 2009, at 04:30, Jay wrote: Hm, scan_float is probably wrong, when crossing that changes endianness. PA is big endian. Crossing from little endian Cygwin, in TimePosix.ms I have: L$C0003: .word 0 .word 1093567616 TimePosix__FromUtime .PROC .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 .ENTRY copy %r3,%r1 copy %r30,%r3 stwm %r1,64(%r30) stw %r3,-4(%r30) stw %r19,-32(%r30) stw %r26,-36(%r3) L$M0009: ldw -36(%r3),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr24 ldw -36(%r3),%r28 ldo 4(%r28),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr23 addil LT'L$C0003,%r19 ldw RT'L$C0003(%r1),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr23,%fr22,%fr22 fadd,dbl %fr24,%fr22,%fr22 and Utime_M3 hangs. Yet it I write the equivalent C code on the target system I get: L$C0000: .word 1093567616 .word 0 .SPACE $TEXT$ .NSUBSPA $CODE$ .align 4 .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU FromUtime: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY fldws 4(%r26),%fr22L fcnvxf,sgl,dbl %fr22L,%fr4 ldil LR'L$C0000,%r28 fldws 0(%r26),%fr23L ldo RR'L$C0000(%r28),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr4,%fr22,%fr4 fcnvxf,sgl,dbl %fr23L,%fr24 bv %r0(%r2) fadd,dbl %fr24,%fr4,%fr4 I'll dig into it more later.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinbishop at bellsouth.net Thu Feb 26 04:35:46 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Wed, 25 Feb 2009 21:35:46 -0600 Subject: [M3devel] Dynamic open array question Message-ID: <49A60E12.9090703@bellsouth.net> I have this code: MODULE Callback EXPORTS Main; IMPORT IO, Fmt; TYPE CallBack = PROCEDURE (a: CARDINAL; b: INTEGER); Values = ARRAY [1..5] OF INTEGER; VAR sample := Values{5, 4, 3, 2, 1}; callback := Display; PROCEDURE Display(loc: CARDINAL; val: INTEGER) = BEGIN IO.Put("array[" & Fmt.Int(loc) & "] = " & Fmt.Int(val * val) & "\n"); END Display; PROCEDURE Map(values: Values; worker: CallBack) = BEGIN FOR i := FIRST(values) TO LAST(values) DO worker(i, values[i]); END; END Map; BEGIN Map(sample, callback); END Callback. This code works just fine, but I was thinking of making the array a dynamic open array, but I couldn't figure out what I needed to change. I tried making Values have the type REF ARRAY OF INTEGER and then calling NEW inside of Map(), but I couldn't figure out how to use an array constructor (since Values{5, 4, 3, 2, 1} would complain when Values was a reference type). From hosking at cs.purdue.edu Thu Feb 26 04:54:59 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 26 Feb 2009 14:54:59 +1100 Subject: [M3devel] Dynamic open array question In-Reply-To: <49A60E12.9090703@bellsouth.net> References: <49A60E12.9090703@bellsouth.net> Message-ID: The only constructor for a dynamic array is NEW. To initialize the elements you need to copy them in, something like: a := NEW(REF ARRAY OF INTEGER, n); SUBARRAY(a^, 0, LENGTH(sample)-1) := sample; From jay.krell at cornell.edu Thu Feb 26 17:23:49 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 26 Feb 2009 16:23:49 +0000 Subject: [M3devel] FW: "CheckFloatsAndTypes"? In-Reply-To: <20090226161605.75D9B10D65F2@birch.elegosoft.com> References: <20090226161605.75D9B10D65F2@birch.elegosoft.com> Message-ID: I assume wedging this tiny bit of code into RTLinker would not be welcome? I think it'd have by far the most value there -- get it to run and fail clearly before any other harder to debug problems. void Test__CheckFloatsAndTypes(const T* t2, size_t size, size_t jbsize) { if (size != sizeof(t1)) { printf("%x vs. %x\n", (U)size, (U)sizeof(t1)); assert(size == sizeof(t1)); } if (memcmp(&t1, t2, sizeof(t1)) != 0) { U i = 0; U8* a = (U8*)&t1; U8* b = (U8*)t2; printf("FD_SETSIZE 0x%x\n", (U)FD_SETSIZE); /*printf("offset of max_fdset 0x%x\n", (U)offsetof(T, max_fdset));*/ for (i = 0; i != sizeof(t1); ++i) { if (a[i] != b[i]) { printf("different at offset 0x%x\n", i); } } assert(memcmp(&t1, t2, sizeof(t1)) == 0); } #ifdef __CYGWIN__ assert(jbsize >= (sizeof(jmp_buf) / 4)); #else assert(jbsize == sizeof(jmp_buf)); #endif } - Jay > Date: Thu, 26 Feb 2009 17:16:05 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 09/02/26 17:16:05 > > Modified files: > cm3/m3-sys/m3tests/src/: Test.i3 m3makefile > cm3/m3-sys/m3tests/src/p0/p001/: Main.m3 m3makefile > Added files: > cm3/m3-sys/m3tests/src/: TestC.c > > Log message: > nice little test case to verify compilation of floating point constants > and correctness of Usysdep > I would really like to have this "run" in RTLinker but suspect that would be rejected. > Anywhere else, e.g. here, is kind of too late to be valuable, unless we manage > to get this into boot1.py, and very early in the list of modules that RTLinker > initializes. > > This reveals some existing possible problems. > - arrays of odd number of float and/or double don't > match up between C and Modula-3; probably related to -mno-aligned-floats > - there are other mismatches here masked by inserting size_t padding > in particular I think cywin linger_t has 16 bit integers and there is > disagreement there. But I didn't look into it. > > Luckily the interactions between C and Modula-3 are relatively rare /and/ > relatively conservative and not very likely to hit these issues. > They do merit further attention though. > > "Running this test case" is merely evaluation three efficient assertions > plus dedicating the constant static space to two structs (Modula-3 > might run initialization code for its "const static" though?) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Feb 1 14:55:59 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 13:55:59 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: How about thread/posix/x86? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jkrell at elego.de > Date: Fri, 30 Jan 2009 14:43:24 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Probably the wrong place for this. If it is x86-dependent it should > go somewhere in the x86 hierarchy, not in a top-level directory like > "context". > > On 30 Jan 2009, at 04:25, Jay Krell wrote: > >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/01/30 04:25:37 >> >> Added files: >> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >> >> Log message: >> highly non-portable working version of set/get/make/swapcontext for >> NT386; >> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >> non-x86, >> though again, it is highly system specific, and inline assembly >> syntax >> is very different between Visual C++ and gcc From jay.krell at cornell.edu Sun Feb 1 15:05:30 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:05:30 +0000 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? Message-ID: Does anyone think the division between m3core/runtime/RTThread and m3core/thread/posix makes sense, is correct, is important, is at all "good", etc.? thread/posix is the only user of RTThread. RTThread was forked into platform-specific variants, but they are all nearly identical. I think this code belongs in m3core/thread/posix/ThreadPosix.m3 or m3core/thread/posix/ThreadPosixC.c and have begun making it so. It is not much code, but it is multiplied out per-platform. There is already RTThreadC.c for many platforms, and introducing ThreadPosixC.c gives me a place to park related C code, in a less disruptive way (ie: ThreadPosixC.c and RTThreadC.c could be merged at some point, probably by deleting RTThreadC.c, once ThreadPosixC.c is complete). My /real/ agenda here is to move to "my rewritten drastically reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), which reduce porting effort, but I feel I can't do that unless user thread support is there, so I am "cleaning up" user thread support along a few lines (make it work on LINUXLIBC6, make it more portable). - Jay From jay.krell at cornell.edu Sun Feb 1 15:11:07 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:11:07 +0000 Subject: [M3devel] solaris RTThread__Transfer? Message-ID: SOLgnu/SOLsun have this: void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { if (getcontext(from) == 0) { to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp return */ setcontext(to); /* fire it up */ } } Two questions: The longjmp emulation is unnecessary, right? (and platform specific) getcontext + setcontext could just be swapcontext, right? Specifically, the "entire function" could "just" be: (yeah yeah, only a slight reduction). void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { swapcontext(from, to); } or even RTThread.i3 PROCEDURE Transfer(...); Yes, I notice the error checking, but a) why would it ever fail b) is that really complete anyway? Just silently ignore the error? ? - Jay From jay.krell at cornell.edu Sun Feb 1 15:44:20 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:44:20 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? Message-ID: I'd like to consider further reducing "system dependent cloned headers". Upthread.i3 in particular. We have for example: pthread_mutex_t = ARRAY[1..6] OF INTEGER; Now, pthread_mutex_t is used in two ways. Some statically allocated variables: VAR activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *) slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *) initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *) Some untraced heap allocated variables: PROCEDURE InitMutex (m: Mutex) = VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO END; IF m.mutex # NIL THEN RETURN END; mutex := NEW(UNTRACED REF pthread_mutex_t); WITH r = Upthread.mutex_init(mutex^, NIL) DO END; m.mutex := mutex; FINALLY WITH r = Upthread.mutex_unlock(initMu) DO END; END; RTHeapRep.RegisterFinalCleanup (m, CleanMutex); END InitMutex; The statically allocated variables can just be moved to C, trivial. And their initialization then kept efficient. What is the right way to translate the untraced allocation? OR, here is kind of the opposite question: Why is the mutex heap allocated anyway? Why not embed it "by value"? Granted, that makes it more difficult to smush out platform-specificity. And then to address that: I would kind of like the idea of an "extern type". An extern type is a type whose instances may only be embedded within heap allocated objects, possibly only at the end, possibly with an implied alignment=maximum, their size would be exposed via constant C variable, probably they would have a designated initialization function, or be zeroed. They could also be "standalone" heap allocated objects. Specifically, something like this: TYPE pthread_t; TYPE Thread.T = RECORD (* Modula-3 stuff *) pthread: pthread_t; END; Thread := NEW(Thread.T); roughly equiv to Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); pthread.c: extern const size_t pthread_t_size = sizeof(pthread_t); You know -- so that they can be implemented "portably". Given that they are already opaque and all the Modula-3 code knows is their size, alignment, and what functions they can be passed to. - Jay From hosking at cs.purdue.edu Sun Feb 1 23:31:44 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:31:44 +1100 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? In-Reply-To: References: Message-ID: These divisions are largely historical, and so long as we preserve the required interfaces (see the language report) I don't see a problem with this plan. On 2 Feb 2009, at 01:05, Jay wrote: > > Does anyone think the division between > m3core/runtime/RTThread and m3core/thread/posix makes sense, > is correct, is important, is at all "good", etc.? > > > thread/posix is the only user of RTThread. > RTThread was forked into platform-specific variants, > but they are all nearly identical. > > > I think this code belongs in m3core/thread/posix/ThreadPosix.m3 > or m3core/thread/posix/ThreadPosixC.c and have begun making it so. > > > It is not much code, but it is multiplied out per-platform. > > > There is already RTThreadC.c for many platforms, and > introducing ThreadPosixC.c gives me a place to park related C > code, in a less disruptive way (ie: ThreadPosixC.c and > RTThreadC.c could be merged at some point, probably by deleting > RTThreadC.c, once ThreadPosixC.c is complete). > > > My /real/ agenda here is to move to "my rewritten drastically > reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), > which reduce porting effort, but I feel > I can't do that unless user thread support is there, > so I am "cleaning up" user thread support along a few lines > (make it work on LINUXLIBC6, make it more portable). > > > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:32:56 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:32:56 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> What is the purpose of this code? On 2 Feb 2009, at 00:55, Jay wrote: > > How about thread/posix/x86? > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jkrell at elego.de >> Date: Fri, 30 Jan 2009 14:43:24 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Probably the wrong place for this. If it is x86-dependent it should >> go somewhere in the x86 hierarchy, not in a top-level directory like >> "context". >> >> On 30 Jan 2009, at 04:25, Jay Krell wrote: >> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>> >>> Added files: >>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>> >>> Log message: >>> highly non-portable working version of set/get/make/swapcontext for >>> NT386; >>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>> non-x86, >>> though again, it is highly system specific, and inline assembly >>> syntax >>> is very different between Visual C++ and gcc From hosking at cs.purdue.edu Sun Feb 1 23:41:29 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:41:29 +1100 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: References: Message-ID: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Sorry, I had mis-remembered that code as using swapcontext, which it clearly does not. I seem to recall that the longjmp emulation was necessary for some reason, but I forget why right now. Was Transfer being called from some place as if it was a longjmp? Hmm... It's been 10 years since I wrote that code for the Solaris port... ;-) On 2 Feb 2009, at 01:11, Jay wrote: > > SOLgnu/SOLsun have this: > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > if (getcontext(from) == 0) { > to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp > return */ > setcontext(to); /* fire it up */ > } > } > > Two questions: > The longjmp emulation is unnecessary, right? (and platform specific) > getcontext + setcontext could just be swapcontext, right? > > > Specifically, the "entire function" could "just" be: (yeah yeah, > only a slight reduction). > > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > swapcontext(from, to); > } > > > or even > > > RTThread.i3 > PROCEDURE Transfer(...); > > > Yes, I notice the error checking, but a) why would it ever fail b) > is that really complete anyway? > Just silently ignore the error? > > > ? > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:54:27 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:54:27 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: Message-ID: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> On 2 Feb 2009, at 01:44, Jay wrote: > I'd like to consider further reducing "system dependent cloned > headers". > Upthread.i3 in particular. > > > We have for example: > > > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Now, pthread_mutex_t is used in two ways. > > > Some statically allocated variables: > > > VAR > activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of > active threads *) > slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread > slot table *) > initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for > initializers *) > > > Some untraced heap allocated variables: > > > PROCEDURE InitMutex (m: Mutex) = > VAR mutex: UNTRACED REF pthread_mutex_t; > BEGIN > TRY > WITH r = Upthread.mutex_lock(initMu) DO END; > IF m.mutex # NIL THEN RETURN END; > mutex := NEW(UNTRACED REF pthread_mutex_t); > WITH r = Upthread.mutex_init(mutex^, NIL) DO END; > m.mutex := mutex; > FINALLY > WITH r = Upthread.mutex_unlock(initMu) DO END; > END; > RTHeapRep.RegisterFinalCleanup (m, CleanMutex); > END InitMutex; > > > The statically allocated variables can just be moved to C, trivial. > And their initialization then kept efficient. Sure, except that now you smear code across the C and Modula-3 universes. Lack of clarity... > What is the right way to translate the untraced allocation? Not sure what you mean by "translate". We are writing Modula-3 in Modula-3 here, so why translate it? I suppose you could invoke some C code to allocate the mutex and return it, but then you have a call to malloc that might not play nice with the Modula-3 code. In the old days this was certainly the case (on user-level thread systems we need malloc to be atomic with respect to thread transfer). Thus, NEW(UNTRACED REF ...) does bottom out at malloc, but RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching around the call to malloc (these disable switching on user-thread platforms, but are no-ops on system threading platforms where malloc should already be thread-safe). How about simply having some C variable that records sizeof(pthread_mutex_t) and use that in a call to new: array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) mutex := ADR(array[0]) > OR, here is kind of the opposite question: > > > Why is the mutex heap allocated anyway? > > Why not embed it "by value"? Because it is difficult to embed by value when the type is opaque. > Granted, that makes it more difficult to smush out platform- > specificity. Indeed. And the rest of what you say here is a pretty disgusting hack. Modula-3 has pretty clean type semantics and you are compromising that in a rather gross way. > > And then to address that: > > > I would kind of like the idea of an "extern type". > An extern type is a type whose instances may only be embedded within > heap allocated objects, > possibly only at the end, possibly with an implied > alignment=maximum, their size > would be exposed via constant C variable, probably they would have a > designated initialization > function, or be zeroed. They could also be "standalone" heap > allocated objects. > > > Specifically, something like this: > > > TYPE pthread_t; > > > TYPE Thread.T = RECORD > (* Modula-3 stuff *) > pthread: pthread_t; > END; > Thread := NEW(Thread.T); > > > roughly equiv to > Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); > > > pthread.c: > > > extern const size_t pthread_t_size = sizeof(pthread_t); > > > You know -- so that they can be implemented "portably". > Given that they are already opaque and all the Modula-3 code knows > is their size, alignment, and what functions they can be passed to. > > > - Jay From jay.krell at cornell.edu Sun Feb 1 23:59:27 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 22:59:27 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > What is the purpose of this code? OpenBSD does not have the *context functions. This provides them for OpenBSD/x86. I /assume/ their only user will be ThreadPosix.m3. That there will be unix/common/ucontext.i3 that declares them. Even if that is a little bit "dishonest" on platforms that lack them. Eh, I guess that begs for the answer, they belong in unix/common/x86? (forking for x86-thisos, x86-thatos, if/as needed) A reason not to put in unix/common/x86 however is if there are compromises that make them not meet the general spec, but adequate for ThreadPosix.m3. I don't have any in mind currently. Restricting makecontext to have argc=1 is tempting, but so far avoided. Perhaps I will see about getting these into OpenBSD. I also anticipate trying to implement them for other systems e.g. PPC_DARWIN. (again, current 10.5 Darwin has them, older 10.4 does not). Possibly in both cases I can just use the "real" versions, I should have thought of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, copy them. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:32:56 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > What is the purpose of this code? > > On 2 Feb 2009, at 00:55, Jay wrote: > >> >> How about thread/posix/x86? >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jkrell at elego.de >>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Probably the wrong place for this. If it is x86-dependent it should >>> go somewhere in the x86 hierarchy, not in a top-level directory like >>> "context". >>> >>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>> >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>> >>>> Added files: >>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>> >>>> Log message: >>>> highly non-portable working version of set/get/make/swapcontext for >>>> NT386; >>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>> non-x86, >>>> though again, it is highly system specific, and inline assembly >>>> syntax >>>> is very different between Visual C++ and gcc > From jay.krell at cornell.edu Mon Feb 2 00:10:17 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:10:17 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: I meant translate Modula-3 to C -- C because it knows size and alignment. I didn't presume I could just call malloc. Even if untraced, I thought calling "the allocator" might have some positive interaction with the garbage collector. Maybe not? (I should look at the code....could be untraced really does just call malloc and no gc interaction. Oops.) > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) That is good. I must have had some hangup about it. NEW is guaranteed to be "very aligned" so there is no alignment issue here? > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... I agree. I'm conflicted here. Look at for example at the dealings with "ackSem". It is a "simple transform" but "transform" is the suspicious word there, not wholly exonerated by "simple". The static variables may also have an issue on Darwin -- can't have non-static variables in a shared object or somesuch. So I'll hold off. (no access to Darwin past few days) Solution could be wrapping the variables up in functions, or every operation on them, like for ackSem. Both kind of not ideal though. On the other hand, the RTThread / RTThreadStk / ThreadPosix split is also a bit smearing/unclear -- you know, FreeStack vs. DisposeStack. But two wrongs don't make a right, I understand. I do consider the user thread code to be a second class citizen. >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. Why? I understand issues of "binary compatibility + dynamic linking". "Pointers are good because they never change size." "Pointers are good for opaque types because they never change size. Better than an int because int often can't store a pointer." But I think we ignore these issues in Modula-3. I know I have been. > hack Seemed a good way to generalize what I'm thinking about for pthread/mutex/etc. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:54:27 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > On 2 Feb 2009, at 01:44, Jay wrote: > >> I'd like to consider further reducing "system dependent cloned >> headers". >> Upthread.i3 in particular. >> >> >> We have for example: >> >> >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Now, pthread_mutex_t is used in two ways. >> >> >> Some statically allocated variables: >> >> >> VAR >> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >> active threads *) >> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >> slot table *) >> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >> initializers *) >> >> >> Some untraced heap allocated variables: >> >> >> PROCEDURE InitMutex (m: Mutex) = >> VAR mutex: UNTRACED REF pthread_mutex_t; >> BEGIN >> TRY >> WITH r = Upthread.mutex_lock(initMu) DO END; >> IF m.mutex # NIL THEN RETURN END; >> mutex := NEW(UNTRACED REF pthread_mutex_t); >> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >> m.mutex := mutex; >> FINALLY >> WITH r = Upthread.mutex_unlock(initMu) DO END; >> END; >> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >> END InitMutex; >> >> >> The statically allocated variables can just be moved to C, trivial. >> And their initialization then kept efficient. > > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... > >> What is the right way to translate the untraced allocation? > > Not sure what you mean by "translate". We are writing Modula-3 in > Modula-3 here, so why translate it? I suppose you could invoke some C > code to allocate the mutex and return it, but then you have a call to > malloc that might not play nice with the Modula-3 code. In the old > days this was certainly the case (on user-level thread systems we need > malloc to be atomic with respect to thread transfer). Thus, > NEW(UNTRACED REF ...) does bottom out at malloc, but > RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching > around the call to malloc (these disable switching on user-thread > platforms, but are no-ops on system threading platforms where malloc > should already be thread-safe). How about simply having some C > variable that records sizeof(pthread_mutex_t) and use that in a call > to new: > > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > mutex := ADR(array[0]) > >> OR, here is kind of the opposite question: >> >> >> Why is the mutex heap allocated anyway? >> >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. > >> Granted, that makes it more difficult to smush out platform- >> specificity. > > Indeed. > > And the rest of what you say here is a pretty disgusting hack. > Modula-3 has pretty clean type semantics and you are compromising that > in a rather gross way. > >> >> And then to address that: >> >> >> I would kind of like the idea of an "extern type". >> An extern type is a type whose instances may only be embedded within >> heap allocated objects, >> possibly only at the end, possibly with an implied >> alignment=maximum, their size >> would be exposed via constant C variable, probably they would have a >> designated initialization >> function, or be zeroed. They could also be "standalone" heap >> allocated objects. >> >> >> Specifically, something like this: >> >> >> TYPE pthread_t; >> >> >> TYPE Thread.T = RECORD >> (* Modula-3 stuff *) >> pthread: pthread_t; >> END; >> Thread := NEW(Thread.T); >> >> >> roughly equiv to >> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >> >> >> pthread.c: >> >> >> extern const size_t pthread_t_size = sizeof(pthread_t); >> >> >> You know -- so that they can be implemented "portably". >> Given that they are already opaque and all the Modula-3 code knows >> is their size, alignment, and what functions they can be passed to. >> >> >> - Jay > From jay.krell at cornell.edu Mon Feb 2 00:14:32 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:14:32 +0000 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> References: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Message-ID: > sorry No problem. I just want to understand, if possible, for when I handle other platforms. > Was Transfer being called from some place as if it was a longjmp? I don't think so but I'll double check. The primary use of it I think ignores the return value. Thanks, - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:41:29 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] solaris RTThread__Transfer? > > Sorry, I had mis-remembered that code as using swapcontext, which it > clearly does not. > > I seem to recall that the longjmp emulation was necessary for some > reason, but I forget why right now. Was Transfer being called from > some place as if it was a longjmp? > > Hmm... > > It's been 10 years since I wrote that code for the Solaris port... ;-) > > On 2 Feb 2009, at 01:11, Jay wrote: > >> >> SOLgnu/SOLsun have this: >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> if (getcontext(from) == 0) { >> to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp >> return */ >> setcontext(to); /* fire it up */ >> } >> } >> >> Two questions: >> The longjmp emulation is unnecessary, right? (and platform specific) >> getcontext + setcontext could just be swapcontext, right? >> >> >> Specifically, the "entire function" could "just" be: (yeah yeah, >> only a slight reduction). >> >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> swapcontext(from, to); >> } >> >> >> or even >> >> >> RTThread.i3 >> PROCEDURE Transfer(...); >> >> >> Yes, I notice the error checking, but a) why would it ever fail b) >> is that really complete anyway? >> Just silently ignore the error? >> >> >> ? >> - Jay > From wagner at elegosoft.com Mon Feb 2 00:12:43 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 02 Feb 2009 00:12:43 +0100 Subject: [M3devel] ssh outage on birch.elegosoft.com, was: Re: ssh down? In-Reply-To: References: Message-ID: <20090202001243.csodfhd1scg4o8ws@mail.elegosoft.com> Currently all ssh services on birch are out of order. We don't have direct access to this machine; we'll be able to get access again tomorrow morning at 9 CET (without further costs). I expect that Michael will be able to get everything working again soon after, if there is no unrecoverable hardware failure. Restoring from backup would take some hours, I'd expect... Sorry for the inconveniences, Olaf Quoting Jay : > > C:\Documents and Settings\jay>ssh -v -v -v -v jkrell at birch.elegosoft.com > OpenSSH_5.1p1, OpenSSL 0.9.8i 15 Sep 2008 > debug2: ssh_connect: needpriv 0 > debug1: Connecting to birch.elegosoft.com [88.198.39.217] port 22. > debug1: connect to address 88.198.39.217 port 22: Connection refused > ssh: connect to host birch.elegosoft.com port 22: Connection refused > > > C:\Documents and Settings\jay>ping birch.elegosoft.com > PING birch.elegosoft.com (88.198.39.217): 56 data bytes > 64 bytes from 88.198.39.217: icmp_seq=0 ttl=59 time=206 ms > 64 bytes from 88.198.39.217: icmp_seq=1 ttl=59 time=217 ms > ----birch.elegosoft.com PING Statistics---- > 2 packets transmitted, 2 packets received, 0.0% packet loss > round-trip (ms) min/avg/max/med = 206/212/217/212 > > - Jay -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 2 00:27:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:27:46 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> On 2 Feb 2009, at 10:10, Jay wrote: > > I meant translate Modula-3 to C -- C because it knows size and > alignment. > I didn't presume I could just call malloc. > Even if untraced, I thought calling "the allocator" might > have some positive interaction with the garbage collector. > Maybe not? > (I should look at the code....could be untraced really > does just call malloc and no gc interaction. Oops.) No GC interaction at all. Just user-level thread interaction to make malloc atomic w.r. to thread switches. >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > > > That is good. I must have had some hangup about it. > NEW is guaranteed to be "very aligned" so there is no alignment > issue here? Hmm, yes, you are right that there is a possible alignment issue. I am used to pthread_mutext_t being a simple reference. But surely in C the type of the pthread_mutex_t struct would have appropriate alignment padding anyway so as to allow allocation using malloc(sizeof pthread_mutex_t)? So, it all should just work right? >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... > > > I agree. I'm conflicted here. > Look at for example at the dealings with "ackSem". > It is a "simple transform" but "transform" is the suspicious > word there, not wholly exonerated by "simple". I don't have your code in front of me at the moment, but I am leery. > The static variables may also have an issue on Darwin -- can't have > non-static variables in a shared object or somesuch. So I'll hold off. > (no access to Darwin past few days) > Solution could be wrapping the variables up in functions, or every > operation on them, like for ackSem. Both kind of not ideal though. Function call would be fine. You could cache the value in a module variable as needed. > On the other hand, the RTThread / RTThreadStk / ThreadPosix > split is also a bit smearing/unclear -- you know, FreeStack vs. > DisposeStack. > But two wrongs don't make a right, I understand. Indeed, but they originally encapsulated unrelated things. > I do consider the user thread code to be a second class citizen. That's still no reason to muddy it's implementation... :-) >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. > > Why? > I understand issues of "binary compatibility + dynamic linking". > "Pointers are good because they never change size." > "Pointers are good for opaque types because they never change size. > Better than an int because int often can't store a pointer." > > But I think we ignore these issues in Modula-3. I know I have been. I would like to think that we don't ignore these issues and as a result we get a cleaner system. Err on the side of promoting elegance rather than lowering ourselves to the standards of legacy code. >> hack > > Seemed a good way to generalize what I'm thinking about for pthread/ > mutex/etc. > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:54:27 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> On 2 Feb 2009, at 01:44, Jay wrote: >> >>> I'd like to consider further reducing "system dependent cloned >>> headers". >>> Upthread.i3 in particular. >>> >>> >>> We have for example: >>> >>> >>> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >>> >>> >>> Now, pthread_mutex_t is used in two ways. >>> >>> >>> Some statically allocated variables: >>> >>> >>> VAR >>> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >>> active threads *) >>> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >>> slot table *) >>> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >>> initializers *) >>> >>> >>> Some untraced heap allocated variables: >>> >>> >>> PROCEDURE InitMutex (m: Mutex) = >>> VAR mutex: UNTRACED REF pthread_mutex_t; >>> BEGIN >>> TRY >>> WITH r = Upthread.mutex_lock(initMu) DO END; >>> IF m.mutex # NIL THEN RETURN END; >>> mutex := NEW(UNTRACED REF pthread_mutex_t); >>> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >>> m.mutex := mutex; >>> FINALLY >>> WITH r = Upthread.mutex_unlock(initMu) DO END; >>> END; >>> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >>> END InitMutex; >>> >>> >>> The statically allocated variables can just be moved to C, trivial. >>> And their initialization then kept efficient. >> >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... >> >>> What is the right way to translate the untraced allocation? >> >> Not sure what you mean by "translate". We are writing Modula-3 in >> Modula-3 here, so why translate it? I suppose you could invoke some C >> code to allocate the mutex and return it, but then you have a call to >> malloc that might not play nice with the Modula-3 code. In the old >> days this was certainly the case (on user-level thread systems we >> need >> malloc to be atomic with respect to thread transfer). Thus, >> NEW(UNTRACED REF ...) does bottom out at malloc, but >> RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching >> around the call to malloc (these disable switching on user-thread >> platforms, but are no-ops on system threading platforms where malloc >> should already be thread-safe). How about simply having some C >> variable that records sizeof(pthread_mutex_t) and use that in a call >> to new: >> >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) >> mutex := ADR(array[0]) >> >>> OR, here is kind of the opposite question: >>> >>> >>> Why is the mutex heap allocated anyway? >>> >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. >> >>> Granted, that makes it more difficult to smush out platform- >>> specificity. >> >> Indeed. >> >> And the rest of what you say here is a pretty disgusting hack. >> Modula-3 has pretty clean type semantics and you are compromising >> that >> in a rather gross way. >> >>> >>> And then to address that: >>> >>> >>> I would kind of like the idea of an "extern type". >>> An extern type is a type whose instances may only be embedded within >>> heap allocated objects, >>> possibly only at the end, possibly with an implied >>> alignment=maximum, their size >>> would be exposed via constant C variable, probably they would have a >>> designated initialization >>> function, or be zeroed. They could also be "standalone" heap >>> allocated objects. >>> >>> >>> Specifically, something like this: >>> >>> >>> TYPE pthread_t; >>> >>> >>> TYPE Thread.T = RECORD >>> (* Modula-3 stuff *) >>> pthread: pthread_t; >>> END; >>> Thread := NEW(Thread.T); >>> >>> >>> roughly equiv to >>> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >>> >>> >>> pthread.c: >>> >>> >>> extern const size_t pthread_t_size = sizeof(pthread_t); >>> >>> >>> You know -- so that they can be implemented "portably". >>> Given that they are already opaque and all the Modula-3 code knows >>> is their size, alignment, and what functions they can be passed to. >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Mon Feb 2 00:30:22 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:30:22 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: On 2 Feb 2009, at 09:59, Jay wrote: >> What is the purpose of this code? > > > OpenBSD does not have the *context functions. > This provides them for OpenBSD/x86. Are they correct w.r. to signals and floating point state? > I /assume/ their only user will be ThreadPosix.m3. > That there will be unix/common/ucontext.i3 that declares them. > Even if that is a little bit "dishonest" on platforms that lack them. > Eh, I guess that begs for the answer, they belong in > unix/common/x86? Yeah, that's where I thought they might go. > (forking for x86-thisos, x86-thatos, if/as needed) > > > A reason not to put in unix/common/x86 however is if there are > compromises that make them not meet the general spec, but adequate > for ThreadPosix.m3. I don't have any in mind currently. > Restricting makecontext to have argc=1 is tempting, but so far > avoided. > > > Perhaps I will see about getting these into OpenBSD. > I also anticipate trying to implement them for other systems e.g. > PPC_DARWIN. > (again, current 10.5 Darwin has them, older 10.4 does not). > Possibly in both cases I can just use the "real" versions, I should > have thought > of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, > copy them. Why do we care about older Darwin versions? The support on Darwin has become much more stable since I first did the port to 10.3, as the base platform has become more reliable. As far as I can tell, prior to 10.5 Darwin still showed signs of being a work in progress (at least w.r. to POSIX compatibility). > > > > - Jay > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:32:56 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> What is the purpose of this code? >> >> On 2 Feb 2009, at 00:55, Jay wrote: >> >>> >>> How about thread/posix/x86? >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jkrell at elego.de >>>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Probably the wrong place for this. If it is x86-dependent it should >>>> go somewhere in the x86 hierarchy, not in a top-level directory >>>> like >>>> "context". >>>> >>>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>>> >>>>> Added files: >>>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>>> >>>>> Log message: >>>>> highly non-portable working version of set/get/make/swapcontext >>>>> for >>>>> NT386; >>>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>>> non-x86, >>>>> though again, it is highly system specific, and inline assembly >>>>> syntax >>>>> is very different between Visual C++ and gcc >> From jay.krell at cornell.edu Mon Feb 2 01:13:04 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 00:13:04 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > Tony > > Are they correct w.r. to signals and floating point state? > >> Jay Eh, I guess that begs for the answer, they belong in >> unix/common/x86? > > Yeah, that's where I thought they might go. > > Why do we care about older Darwin versions? The support on Darwin has > become much more stable since I first did the port to 10.3, as the > Floating point state and signal mask Not sure. NetBSD getcontext: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/arch/i386/sys/getcontext.S?rev=1.3&content-type=text/x-cvsweb-markup&only_with_tag=MAIN doesn't do anything here...oh..but that clearly isn't the entire implementation.. I'll have to dig around. I will have to write a test case with a bunch of threads and floating point and signal mask changes..and compare to setjmp/longjmp.. You really think 10.5 is so much better than previous? As a user I never noticed much change since 10.2. Anyone else here using prior to 10.5 or care to support them? (I suspect nobody is using any Darwin version but...) But again, IF their get/make/swap/setcontext in 10.5 is all usermode, and presumably BSD-licensed, we can just copy it into m3core. (I suspect the bit I haven't found in NetBSD is in the kernel. Should only take a few minutes to find, but I have to run..) I'll move to unix/src/common/x86 as we both thought of, if it works. Or maybe just work on a system that provides *context. - Jay From mika at async.caltech.edu Mon Feb 2 01:42:32 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sun, 01 Feb 2009 16:42:32 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." Message-ID: <200902020042.n120gXij073476@camembert.async.caltech.edu> I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin (10.3 -> 10.4), all Hell broke loose, too... Mika >> >> Why do we care about older Darwin versions? The support on Darwin has >> become much more stable since I first did the port to 10.3, as the > From jay.krell at cornell.edu Mon Feb 2 02:00:40 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 01:00:40 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: Ok, I forgot to qualify the question -- do you care about user threads? - Jay ---------------------------------------- > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > Date: Sun, 1 Feb 2009 16:42:32 -0800 > From: mika at async.caltech.edu > > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:36:30 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:36:30 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <306B482E-57C1-4711-8760-C5C53C8DED7F@cs.purdue.edu> The CM3 transition 10.2-10.3 was much more difficult than 10.4-10.5. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:37:02 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:37:02 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <17D3AB18-01A2-49B8-8D4F-3EB349401E76@cs.purdue.edu> Sorry, meant 10.4-10.5 much easier than previous. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From mika at async.caltech.edu Tue Feb 3 07:21:53 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Mon, 02 Feb 2009 22:21:53 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> Message-ID: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Jay Krell writes: >CVSROOT: /usr/cvs >Changes by: jkrell at birch. 09/02/03 06:17:25 > >Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 > RTAllocator.m3 > >Log message: > expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely you can't have Free in a non-UNSAFE interface... Mika > introduce internal RTAlloc.MallocUninitialized > > These include Disable/EnableSwitching, and > raising exceptions upon failure. > (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 07:50:21 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 17:50:21 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <931183AC-9652-4F06-8EEB-A5D077669667@cs.purdue.edu> Indeed! I just repaired this. On 3 Feb 2009, at 17:21, Mika Nystrom wrote: > Jay Krell writes: >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/02/03 06:17:25 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >> Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:07:55 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:07:55 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: Sorry, fair enough. I don't think about safety much. Can I put these in a new unsafe RTAllocateUnsafe.i3 or RTUnsafeAllocator.i3? And then the function names I had come up with MallocUninitialized, MallocZeroed. Using array of char seems non-ideal to me somehow. It seems like a "workaround". It doesn't seem really any safer than not having a type at all. I understand, the array, the type, does imply a size, and so I would get some bounds checking against it, except I never access these things anyway, I just pass them on to unsafe C code. Related but tangential question, something I also didn't pay close enough attention to: What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise OutOfMemory directly? - Jay ---------------------------------------- > To: jkrell at elego.de > Date: Mon, 2 Feb 2009 22:21:53 -0800 > From: mika at async.caltech.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Jay Krell writes: >>CVSROOT: /usr/cvs >>Changes by: jkrell at birch. 09/02/03 06:17:25 >> >>Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >>Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 09:35:38 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 19:35:38 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> On 3 Feb 2009, at 19:07, Jay wrote: > > Sorry, fair enough. I don't think about safety much. > > > Can I put these in a new unsafe RTAllocateUnsafe.i3 or > RTUnsafeAllocator.i3? > And then the function names I had come up with MallocUninitialized, > MallocZeroed. What do you need them for? RTAllocator is there so one can allocate by typecode. I don't see the point of Malloc/Free. > Using array of char seems non-ideal to me somehow. > It seems like a "workaround". > It doesn't seem really any safer than not having a type at all. > I understand, the array, the type, does imply a size, and so I would > get some bounds checking against it, except I never access these > things anyway, I just pass them on to unsafe C code. > > > Related but tangential question, something I also didn't pay close > enough attention to: > What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? The first is an explicit exception while the latter is implicit. > Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise > OutOfMemory directly? Because the exception is implicit. Any procedure can raise a RuntimeError. > > > > - Jay > > > ---------------------------------------- >> To: jkrell at elego.de >> Date: Mon, 2 Feb 2009 22:21:53 -0800 >> From: mika at async.caltech.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Jay Krell writes: >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>> RTAllocator.m3 >>> >>> Log message: >>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >> >> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >> you can't have Free in a non-UNSAFE interface... >> >> Mika >> >>> introduce internal RTAlloc.MallocUninitialized >>> >>> These include Disable/EnableSwitching, and >>> raising exceptions upon failure. >>> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:58:53 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:58:53 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: > What do you need them for? RTAllocator is there so one can allocate How do I get a typecode in C? Perhaps the attached is unnecessarily elaborate? Or the new/dispose functions should be moved to Modula-3? Or eliminated and the small number of callers can say NEW(ARRAY OF CHAR, Uucontext.Size)? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Tue, 3 Feb 2009 19:35:38 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) > > On 3 Feb 2009, at 19:07, Jay wrote: > >> >> Sorry, fair enough. I don't think about safety much. >> >> >> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >> RTUnsafeAllocator.i3? >> And then the function names I had come up with MallocUninitialized, >> MallocZeroed. > > What do you need them for? RTAllocator is there so one can allocate > by typecode. I don't see the point of Malloc/Free. > >> Using array of char seems non-ideal to me somehow. >> It seems like a "workaround". >> It doesn't seem really any safer than not having a type at all. >> I understand, the array, the type, does imply a size, and so I would >> get some bounds checking against it, except I never access these >> things anyway, I just pass them on to unsafe C code. >> >> >> Related but tangential question, something I also didn't pay close >> enough attention to: >> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? > > The first is an explicit exception while the latter is implicit. > >> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >> OutOfMemory directly? > > Because the exception is implicit. Any procedure can raise a > RuntimeError. > >> >> >> >> - Jay >> >> >> ---------------------------------------- >>> To: jkrell at elego.de >>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>> From: mika at async.caltech.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Jay Krell writes: >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>> >>>> Modified files: >>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>> RTAllocator.m3 >>>> >>>> Log message: >>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>> >>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >>> you can't have Free in a non-UNSAFE interface... >>> >>> Mika >>> >>>> introduce internal RTAlloc.MallocUninitialized >>>> >>>> These include Disable/EnableSwitching, and >>>> raising exceptions upon failure. >>>> (Disable/Enable only do something for user threads). > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.c URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.i3 URL: From hosking at cs.purdue.edu Tue Feb 3 11:42:00 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 21:42:00 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: This will highly likely break. Let me take a look and see if there's an alternative. On 3 Feb 2009, at 19:58, Jay wrote: > >> What do you need them for? RTAllocator is there so one can allocate > > How do I get a typecode in C? > > Perhaps the attached is unnecessarily elaborate? > Or the new/dispose functions should be moved to Modula-3? > Or eliminated and the small number of callers can say NEW(ARRAY OF > CHAR, Uucontext.Size)? > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Tue, 3 Feb 2009 19:35:38 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) >> >> On 3 Feb 2009, at 19:07, Jay wrote: >> >>> >>> Sorry, fair enough. I don't think about safety much. >>> >>> al >>> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >>> RTUnsafeAllocator.i3? >>> And then the function names I had come up with MallocUninitialized, >>> MallocZeroed. >> >> What do you need them for? RTAllocator is there so one can allocate >> by typecode. I don't see the point of Malloc/Free. >> >>> Using array of char seems non-ideal to me somehow. >>> It seems like a "workaround". >>> It doesn't seem really any safer than not having a type at all. >>> I understand, the array, the type, does imply a size, and so I would >>> get some bounds checking against it, except I never access these >>> things anyway, I just pass them on to unsafe C code. >>> >>> >>> Related but tangential question, something I also didn't pay close >>> enough attention to: >>> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? >> >> The first is an explicit exception while the latter is implicit. >> >>> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >>> OutOfMemory directly? >> >> Because the exception is implicit. Any procedure can raise a >> RuntimeError. >> >>> >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> To: jkrell at elego.de >>>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>>> From: mika at async.caltech.edu >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Jay Krell writes: >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>>> RTAllocator.m3 >>>>> >>>>> Log message: >>>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>>> >>>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? >>>> Surely >>>> you can't have Free in a non-UNSAFE interface... >>>> >>>> Mika >>>> >>>>> introduce internal RTAlloc.MallocUninitialized >>>>> >>>>> These include Disable/EnableSwitching, and >>>>> raising exceptions upon failure. >>>>> (Disable/Enable only do something for user threads). > From martinbishop at bellsouth.net Tue Feb 3 20:22:06 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:22:06 -0600 Subject: [M3devel] Initialize array to zero? Message-ID: <4988995E.4040605@bellsouth.net> Quick question, is it possible to initialize an array to all zeros? I tried: VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; but I get errors...I also tried just {0} but that errors too. From martinbishop at bellsouth.net Tue Feb 3 20:45:12 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:45:12 -0600 Subject: [M3devel] Initialize array to zero? In-Reply-To: <4988995E.4040605@bellsouth.net> References: <4988995E.4040605@bellsouth.net> Message-ID: <49889EC8.8060103@bellsouth.net> Martin Bishop wrote: > Quick question, is it possible to initialize an array to all zeros? > > I tried: > > VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; > > but I get errors...I also tried just {0} but that errors too. > Never mind, I figured it out, it's {0, ..} :) From jay.krell at cornell.edu Tue Feb 3 23:05:51 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 22:05:51 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: > Hmm, yes, you are right that there is a possible alignment issue. I > am used to pthread_mutext_t being a simple reference. But surely in C > the type of the pthread_mutex_t struct would have appropriate > alignment padding anyway so as to allow allocation using malloc(sizeof > pthread_mutex_t)? So, it all should just work right? I think "the other way around" and same conclusion. malloc should return something "maximally aligned" so that pthread_mutex_t* x = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); works. pthread_mutex_t doesn't need the padding, malloc does, so to speak. Just as long as we don't have TYPE Foo = RECORD a: pthread_mutex_t; b: pthread_mutex_t; c: pthread_t; d: pthread_t; e: pthread_cond_t; f: pthread_cond_t; END; and such, ok. malloc on NT returns something with 2 * sizeof(void*) alignment. I think on Win9x only 4 alignment, thus there is _malloc_aligned for dealing with SSE stuff. Something like that. I didn't realize untraced allocations were basically just malloc but indeed they are. I'm still mulling over the possible deoptimizations here. I'm reluctant to increase heap allocations. - Jay From hosking at cs.purdue.edu Tue Feb 3 23:54:01 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 09:54:01 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> I suggest you come up with a proposal for us to look over before you change the code base for this. On 4 Feb 2009, at 09:05, Jay wrote: > >> Hmm, yes, you are right that there is a possible alignment issue. I >> am used to pthread_mutext_t being a simple reference. But surely in C >> the type of the pthread_mutex_t struct would have appropriate >> alignment padding anyway so as to allow allocation using >> malloc(sizeof >> pthread_mutex_t)? So, it all should just work right? > > > I think "the other way around" and same conclusion. > malloc should return something "maximally aligned" so that > > pthread_mutex_t* x = (pthread_mutex_t*) > malloc(sizeof(pthread_mutex_t)); > > > works. pthread_mutex_t doesn't need the padding, malloc does, so to > speak. > > > Just as long as we don't have > > > TYPE Foo = RECORD > a: pthread_mutex_t; > b: pthread_mutex_t; > c: pthread_t; > d: pthread_t; > e: pthread_cond_t; > f: pthread_cond_t; > END; > > > and such, ok. > > > malloc on NT returns something with 2 * sizeof(void*) alignment. > I think on Win9x only 4 alignment, thus there is _malloc_aligned for > dealing with SSE stuff. > Something like that. > > > I didn't realize untraced allocations were basically just malloc but > indeed they are. > > > I'm still mulling over the possible deoptimizations here. > I'm reluctant to increase heap allocations. > > > > - Jay From jay.krell at cornell.edu Wed Feb 4 01:06:24 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:06:24 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: There are a few possibilities: Roughly: Where there is INTERFACE Upthread; TYPE pthread_t = ... system specific ... pthread_cond_t = ... system specific ... pthread_mutex_t = ... system specific ... PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); MODULE PThread; VAR a: pthread_t; b: pthread_cond_t; c: pthread_mutex_t; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; change to: INTERFACE Upthread; TYPE pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type pthread_cond_t = RECORD END; ditto pthread_mutex_t = RECORD END; ditto PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); INTERFACE PThreadC.i3 PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; or possibly extern VAR PThreadC.c static pthread_t a = PTHREAD_INIT; static pthread_cond_t b = PTHREAD_COND_INIT; static pthread_mutex_t c = PTHREAD_MUTEX_INIT; pthread_t* GetA() { return &a; } pthread_cond_t* GetB() { return &b; } pthread_mutex_t* GetC() { return &c; } MODULE PThread; VAR a := PThreadC.GetA(); b := PThreadC.GetB(); c := PThreadC.GetA(); PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a^); Upthread.pthread_cond_init_or_whatever(b^); Upthread.pthread_mutex_init_or_whatever(c^); END Foo; or, again, possibly they are variables and it goes a little smaller/quicker: FROM UPthreadC IMPORT a, b, c; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; I think that is pretty cut and dry, no controversy. What is less clear is what to do with non-statically allocated variables. Let's say: MODULE PThread; TYPE T = RECORD a:int; b:pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T) BEGIN Upthread.init_or_whatever(t.b); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b); DISPOSE(t); END; The desire is something that does not know the size of pthread_t, something like: TYPE T = RECORD a:int; b:UNTRACED REF pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T); BEGIN t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) Upthread.init_or_whatever(t.b^); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b^); DISPOSE(t.b); DISPOSE(t); END; However that incurs an extra heap allocation, which is not great. In at least one place, the pointer-indirection-and-heap-allocation is already there so this isn't a deoptimization. However "reoptimizing" it might be nice. What I would prefer a pattern I often use in C -- merging allocations, something like, /assuming/ t is untraced, which I grant it might not be. And ensuring that BYTESIZE(T) is properly aligned: PROCEDURE CreateT():UNTRACED REF T= VAR p : ADDRESS; t : UNTRACED REF T; BEGIN (* Again I would prefer RTAllocator.MallocZeroed *) p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); t := LOOPHOLE(UNTRACED REF T, p); t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); Upthread.init_or_whatever(t.b^); RETURN t; END; That is -- opaque types, size not known at compile-time, but size known at runtime, and do not incur an extra heap allocation for lack of knowing sizes at compile-time. For the statically allocated variables I think there is no controversy. There might a tiny bit of overhead in the use, but it'd be very small, and possibly even removable in the future. I'd rather avoid the variables, as all writable data is to be avoided. Read only pages are better and all that, but ok.. However the value is mainly realized only if statically and dynamically allocated variables are handled. The result of this would be further reduction in platform-specificity when cloning C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 09:54:01 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I suggest you come up with a proposal for us to look over before you > change the code base for this. > > On 4 Feb 2009, at 09:05, Jay wrote: > >> >>> Hmm, yes, you are right that there is a possible alignment issue. I >>> am used to pthread_mutext_t being a simple reference. But surely in C >>> the type of the pthread_mutex_t struct would have appropriate >>> alignment padding anyway so as to allow allocation using >>> malloc(sizeof >>> pthread_mutex_t)? So, it all should just work right? >> >> >> I think "the other way around" and same conclusion. >> malloc should return something "maximally aligned" so that >> >> pthread_mutex_t* x = (pthread_mutex_t*) >> malloc(sizeof(pthread_mutex_t)); >> >> >> works. pthread_mutex_t doesn't need the padding, malloc does, so to >> speak. >> >> >> Just as long as we don't have >> >> >> TYPE Foo = RECORD >> a: pthread_mutex_t; >> b: pthread_mutex_t; >> c: pthread_t; >> d: pthread_t; >> e: pthread_cond_t; >> f: pthread_cond_t; >> END; >> >> >> and such, ok. >> >> >> malloc on NT returns something with 2 * sizeof(void*) alignment. >> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >> dealing with SSE stuff. >> Something like that. >> >> >> I didn't realize untraced allocations were basically just malloc but >> indeed they are. >> >> >> I'm still mulling over the possible deoptimizations here. >> I'm reluctant to increase heap allocations. >> >> >> >> - Jay > From jay.krell at cornell.edu Wed Feb 4 01:35:04 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:35:04 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: Addendum: if size <= BYTESIZE(ADDRESS), which is common, it is desirable to avoid the extra heap allocation and just use the space for the pointer. You end up with like: TYPE T = RECORD ... pthread: UNTRACED REF pthread_t END; PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t BEGIN IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); ELSE RETURN t.pthread; END GetPThread; - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 00:06:24 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation is already there > so this isn't a deoptimization. However "reoptimizing" it might be nice. > > > What I would prefer a pattern I often use in C -- merging allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at compile-time. > > > For the statically allocated variables I think there is no controversy. > There might a tiny bit of overhead in the use, but it'd be very small, and possibly > even removable in the future. I'd rather avoid the variables, as all writable > data is to be avoided. Read only pages are better and all that, but ok.. > > > However the value is mainly realized only if statically and dynamically allocated variables are handled. > > The result of this would be further reduction in platform-specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Wed Feb 4 02:50:41 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:50:41 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: You need to be careful here w.r. to traced heap allocation, since objects can move. It is not safe to return the address of any field of a traced object. On 4 Feb 2009, at 11:35, Jay wrote: > > Addendum: > if size <= BYTESIZE(ADDRESS), which is common, it is desirable to > avoid the extra heap allocation and just use the space for the > pointer. > > You end up with like: > > TYPE T = RECORD > ... > pthread: UNTRACED REF pthread_t > END; > > > PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t > BEGIN > IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) > RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); > ELSE > RETURN t.pthread; > END GetPThread; > > > - Jay > > > > > > > > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 00:06:24 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, but >> ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment >>>>> issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned >>>> for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc >>>> but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> From hosking at cs.purdue.edu Wed Feb 4 02:53:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:53:54 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: I am very leery of this proposal -- the code will be inherently opaque and unmaintainable. I don't see any advantage to it. On 4 Feb 2009, at 11:06, Jay wrote: > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque > preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/ > quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated > variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, > something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF > CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := > RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation > is already there > so this isn't a deoptimization. However "reoptimizing" it might be > nice. > > > What I would prefer a pattern I often use in C -- merging > allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + > BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size > known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at > compile-time. > > > For the statically allocated variables I think there is no > controversy. > There might a tiny bit of overhead in the use, but it'd be very > small, and possibly > even removable in the future. I'd rather avoid the variables, as > all writable > data is to be avoided. Read only pages are better and all that, > but ok.. > > > However the value is mainly realized only if statically and > dynamically allocated variables are handled. > > The result of this would be further reduction in platform- > specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new > platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely >>>> in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From martinbishop at bellsouth.net Wed Feb 4 04:51:33 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 21:51:33 -0600 Subject: [M3devel] opencm3 favicon Message-ID: <498910C5.6050902@bellsouth.net> A little off-topic maybe, but I though opencm3.net needed a favicon. I made 2 different ones: http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue square with a white 3, nice and simple. http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by giving the Modula-3 logo to some online favicon generator. Same as the first one really, only "zoomed in" looking. Feel free to use either one if you want. From wagner at elegosoft.com Wed Feb 4 08:05:07 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 08:05:07 +0100 Subject: [M3devel] tinderbox regression Message-ID: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> The build on LINUXLIBC6 fails: /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command not found ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory Fatal Error: incomplete program *** execution of cm3 -build -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? failed *** Mike, anything changed on birch since yesterday? Or a real M3 problem? One more test fails since yesterday: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 e020 e026 +e029 >>> 13 in test_m3tests 2009-02-03-02-31-01 today: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 r004 e020 e026 e029 >>> 14 in test_m3tests 2009-02-04-02-31-17 /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 It seems to be a runtest checking an error: r_test ("r0", "r004", "negative size for an open array") It's just the diff that fails because the line has changed: --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 @@ -3,6 +3,6 @@ *** *** runtime error: *** An enumeration or subrange value was out of range. -*** file "../src/runtime/common/RTAllocator.m3", line 309 +*** file "../src/runtime/common/RTAllocator.m3", line 307 *** Can anybody have a look? Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From michael.anderson at elego.de Wed Feb 4 09:33:56 2009 From: michael.anderson at elego.de (Michael Anderson) Date: Wed, 04 Feb 2009 09:33:56 +0100 Subject: [M3devel] tinderbox regression In-Reply-To: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> References: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> Message-ID: <20090204093356.r1r472b21sgkw4so@mail.elegosoft.com> Quoting Olaf Wagner : > The build on LINUXLIBC6 fails: > > /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command > not > found > ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory > Fatal Error: incomplete program > *** execution of cm3 -build > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? failed *** > > Mike, anything changed on birch since yesterday? Or a real M3 problem? Nothing that I'm aware of, except an apache redirect for the Subversion 1.6 news article, which just redirects a google link to the english page... I'll have a look around. > > One more test fails since yesterday: > > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > e020 e026 +e029 > >>> 13 in test_m3tests 2009-02-03-02-31-01 > > today: > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > r004 e020 e026 e029 > >>> 14 in test_m3tests 2009-02-04-02-31-17 > /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 > > It seems to be a runtest checking an error: > r_test ("r0", "r004", "negative size for an open array") > > It's just the diff that fails because the line has changed: > > --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 > +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 > @@ -3,6 +3,6 @@ > *** > *** runtime error: > *** An enumeration or subrange value was out of range. > -*** file "../src/runtime/common/RTAllocator.m3", line 309 > +*** file "../src/runtime/common/RTAllocator.m3", line 307 > *** > > Can anybody have a look? > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 10:42:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 09:42:12 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: It gains something, but maybe it isn't enough to be worthwhile. The issue is in the subjectivity. It would remove e.g. the following system-dependent lines: Linux: pthread_t = ADDRESS; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Linux/32: pthread_attr_t = ARRAY[1..9] OF INTEGER; pthread_mutex_t = ARRAY[1..6] OF INTEGER; Linux/64: pthread_attr_t = ARRAY[1..7] OF INTEGER; pthread_mutex_t = ARRAY[1..5] OF INTEGER; FreeBSD: pthread_t = ADDRESS; pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; HP-UX: (* trick from darwin-generic/Upthread.i3 *) X32 = ORD(BITSIZE(INTEGER) = 32); X64 = ORD(BITSIZE(INTEGER) = 64); pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Cygwin: pthread_t = ADDRESS; (* opaque *) pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Solaris: pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) Darwin: (only ppc32 currently) pthread_t = INTEGER; (* opaque *) pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (plus AIX, Irix, VMS, Tru64.) Another approach would be make them all ADDRESS and introduce a portable C layer of "varything thickness", using the same logic. It would look just like the native pthreads, but there'd be extra allocate/cleanup calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. The two layers would be clear and simple, the cost would be the same, but there would be the conceptual cost of two simple layers instead of one just one slightly complicated layer. Another approach is maybe make them all addresses on new platforms and introduce the C layer only on new platforms. Again, about the only change in the Modula-3 code is extra alloc/cleanup calls. And again, some/all of the code already has the indirection/heap allocation unconditionally. And again, maybe not worth it. I show all the system-dependent code, attempting to portray in its worst light by showing all of it, but maybe it's really not a lot. For the attr type, we can do something specific to its use. There is just one use, and we can address it with the following function written in C.. eh..I'll send a diff later tonight/this week I think. pthread_t and pthread_key_t always happen to be address-sized or smaller. Maybe just declare them both to be address and assert their size in some C code. That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. For example, we have: TYPE Activation = UNTRACED REF RECORD (* global doubly-linked, circular list of all active threads *) next, prev: Activation := NIL; (* LL = activeMu *) (* thread handle *) handle: pthread_t; (* LL = activeMu *) (* base of thread stack for use by GC *) stackbase: ADDRESS := NIL; (* LL = activeMu *) so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. Leaving only cond and mutex. Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. rwlock is a useful type though. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 12:53:54 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I am very leery of this proposal -- the code will be inherently opaque > and unmaintainable. I don't see any advantage to it. > > On 4 Feb 2009, at 11:06, Jay wrote: > >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, >> but ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> > From jay.krell at cornell.edu Wed Feb 4 11:14:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 10:14:12 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers Message-ID: The following eliminates the only use of pthread_attr_t from the cloned headers, slightly reducing the work to port to new platforms. It introduces a "small" "portable" C wrapper to encompass the files lines of Modula-3 that use pthread_attr_t. ok? Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.89 diff -u -r1.89 ThreadPThread.m3 --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 @@ -11,11 +11,10 @@ Unix, Utime, Word, Upthread, Usched, Uerror, ThreadPThreadC, Uexec; FROM Upthread -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, pthread_mutex_t, +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; FROM Compiler IMPORT ThisFile, ThisLine; FROM Ctypes IMPORT int; -FROM Utypes IMPORT size_t; FROM ThreadPThreadC IMPORT SIG_SUSPEND; (*----------------------------------------------------- types and globals ---*) @@ -561,9 +560,7 @@ VAR act := NEW(Activation); t := CreateT(act); - attr: pthread_attr_t; size := defaultStackSize; - bytes: size_t; BEGIN (* determine the initial size of the stack for this thread *) TYPECASE closure OF @@ -576,17 +573,12 @@ t.id := nextId; INC(nextId); IF perfOn THEN PerfChanged(t.id, State.alive) END; - WITH r = Upthread.attr_init(attr) DO END; - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; - bytes := MAX(bytes, size * ADRSIZE(Word.T)); - EVAL Upthread.attr_setstacksize(attr, bytes); act.next := allThreads; act.prev := allThreads.prev; act.size := size; allThreads.prev.next := act; allThreads.prev := act; - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO - EVAL Upthread.attr_destroy(attr); + WITH r = ThreadPThreadC.thread_create(act.handle, size * ADRSIZE(Word.T), ThreadBase, act) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: Fork failed with error: ", r); Index: ThreadPThreadC.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.c,v retrieving revision 1.8 diff -u -r1.8 ThreadPThreadC.c --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 @@ -14,6 +14,7 @@ #include #include #endif +#include #ifdef __cplusplus extern "C" { @@ -145,6 +146,32 @@ #endif } +#define VAR(t) t* +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) +typedef void* (*start_routine_t)(void*); + +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t stackSize, start_routine_t start_routine, void* arg) +{ + int r; + size_t bytes; + pthread_attr_t attr; + + r = pthread_attr_init(&attr); + assert(r == 0); + + r = pthread_attr_getstacksize(&attr, &bytes); + assert(r == 0); + + bytes = MAX(bytes, stackSize); + pthread_attr_setstacksize(&attr, bytes); + + r = pthread_create(pthread, &attr, start_routine, arg); + + pthread_attr_destroy(&attr); + + return r; +} + #ifdef __cplusplus } /* extern "C" */ #endif Index: ThreadPThreadC.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.i3,v retrieving revision 1.5 diff -u -r1.5 ThreadPThreadC.i3 --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 @@ -7,6 +7,8 @@ UNSAFE INTERFACE ThreadPThreadC; FROM Ctypes IMPORT int; +FROM Cstddef IMPORT size_t; +FROM Upthread IMPORT pthread_t, start_routine_t; (*---------------------------------------------------------------------------*) @@ -38,4 +40,11 @@ (*---------------------------------------------------------------------------*) +(* pthread_create but replace attr with stackSize so that attr need not be known to Modula-3 *) + + +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; start_routine: start_routine_t; arg: ADDRESS): int; + +(*---------------------------------------------------------------------------*) + END ThreadPThreadC. The corrolary then, ignoring the "cloned headers" that I leave alone, is: Index: Common/Upthread.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v retrieving revision 1.3 diff -u -r1.3 Upthread.i3 --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 @@ -10,7 +10,6 @@ TYPE pthread_t = Usysdep.pthread_t; - pthread_attr_t = Usysdep.pthread_attr_t; pthread_mutex_t = Usysdep.pthread_mutex_t; pthread_cond_t = Usysdep.pthread_cond_t; pthread_key_t = Usysdep.pthread_key_t; @@ -21,14 +20,9 @@ VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; PROCEDURE detach (thread: pthread_t): int; PROCEDURE self (): pthread_t; PROCEDURE equal (t1, t2: pthread_t): int; - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR stacksize: size_t): int; - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: size_t): int; PROCEDURE yield (): int; PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := NIL): int; PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; Index: cygwin/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v retrieving revision 1.12 diff -u -r1.12 Usysdep.i3 --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -28,7 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *) - pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Index: darwin-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,v retrieving revision 1.2 diff -u -r1.2 Usysdep.i3 --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -20,7 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *) - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) Index: freebsd-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,v retrieving revision 1.5 diff -u -r1.5 Usysdep.i3 --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -22,7 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; Index: hpux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/Usysdep.i3,v retrieving revision 1.4 diff -u -r1.4 Usysdep.i3 --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -25,7 +25,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Index: linux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,v retrieving revision 1.10 diff -u -r1.10 Usysdep.i3 --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -21,7 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = Upthreadtypes.pthread_attr_t; pthread_mutex_t = Upthreadtypes.pthread_mutex_t; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Index: solaris-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,v retrieving revision 1.3 diff -u -r1.3 Usysdep.i3 --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -24,7 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) From hosking at cs.purdue.edu Wed Feb 4 11:24:19 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 21:24:19 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: Message-ID: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> ok On 4 Feb 2009, at 21:14, Jay wrote: > > The following eliminates the only use of pthread_attr_t from the > cloned headers, slightly reducing the work to port to new platforms. > It introduces a "small" "portable" C wrapper to encompass the files > lines of Modula-3 that use pthread_attr_t. ok? > > > Index: ThreadPThread.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThread.m3,v > retrieving revision 1.89 > diff -u -r1.89 ThreadPThread.m3 > --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 > +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 > @@ -11,11 +11,10 @@ > Unix, Utime, Word, Upthread, Usched, > Uerror, ThreadPThreadC, Uexec; > FROM Upthread > -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, > pthread_mutex_t, > +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, > PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; > FROM Compiler IMPORT ThisFile, ThisLine; > FROM Ctypes IMPORT int; > -FROM Utypes IMPORT size_t; > FROM ThreadPThreadC IMPORT SIG_SUSPEND; > > (*----------------------------------------------------- types and > globals ---*) > @@ -561,9 +560,7 @@ > VAR > act := NEW(Activation); > t := CreateT(act); > - attr: pthread_attr_t; > size := defaultStackSize; > - bytes: size_t; > BEGIN > (* determine the initial size of the stack for this thread *) > TYPECASE closure OF > @@ -576,17 +573,12 @@ > t.id := nextId; INC(nextId); > IF perfOn THEN PerfChanged(t.id, State.alive) END; > > - WITH r = Upthread.attr_init(attr) DO END; > - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; > - bytes := MAX(bytes, size * ADRSIZE(Word.T)); > - EVAL Upthread.attr_setstacksize(attr, bytes); > act.next := allThreads; > act.prev := allThreads.prev; > act.size := size; > allThreads.prev.next := act; > allThreads.prev := act; > - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO > - EVAL Upthread.attr_destroy(attr); > + WITH r = ThreadPThreadC.thread_create(act.handle, size * > ADRSIZE(Word.T), ThreadBase, act) DO > IF r # 0 THEN > RTError.MsgI(ThisFile(), ThisLine(), > "Thread client error: Fork failed with error: > ", r); > Index: ThreadPThreadC.c > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.c,v > retrieving revision 1.8 > diff -u -r1.8 ThreadPThreadC.c > --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 > +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 > @@ -14,6 +14,7 @@ > #include > #include > #endif > +#include > > #ifdef __cplusplus > extern "C" { > @@ -145,6 +146,32 @@ > #endif > } > > +#define VAR(t) t* > +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) > +typedef void* (*start_routine_t)(void*); > + > +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t > stackSize, start_routine_t start_routine, void* arg) > +{ > + int r; > + size_t bytes; > + pthread_attr_t attr; > + > + r = pthread_attr_init(&attr); > + assert(r == 0); > + > + r = pthread_attr_getstacksize(&attr, &bytes); > + assert(r == 0); > + > + bytes = MAX(bytes, stackSize); > + pthread_attr_setstacksize(&attr, bytes); > + > + r = pthread_create(pthread, &attr, start_routine, arg); > + > + pthread_attr_destroy(&attr); > + > + return r; > +} > + > #ifdef __cplusplus > } /* extern "C" */ > #endif > Index: ThreadPThreadC.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.i3,v > retrieving revision 1.5 > diff -u -r1.5 ThreadPThreadC.i3 > --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 > +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 > @@ -7,6 +7,8 @@ > UNSAFE INTERFACE ThreadPThreadC; > > FROM Ctypes IMPORT int; > +FROM Cstddef IMPORT size_t; > +FROM Upthread IMPORT pthread_t, start_routine_t; > > (*---------------------------------------------------------------------------*) > > @@ -38,4 +40,11 @@ > > (*---------------------------------------------------------------------------*) > > +(* pthread_create but replace attr with stackSize so that attr need > not be known to Modula-3 *) > + > + > +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; > start_routine: start_routine_t; arg: ADDRESS): int; > + > + > (*---------------------------------------------------------------------------*) > + > END ThreadPThreadC. > > > > > > The corrolary then, ignoring the "cloned headers" that I leave > alone, is: > > > Index: Common/Upthread.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v > retrieving revision 1.3 > diff -u -r1.3 Upthread.i3 > --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 > +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 > @@ -10,7 +10,6 @@ > > TYPE > pthread_t = Usysdep.pthread_t; > - pthread_attr_t = Usysdep.pthread_attr_t; > pthread_mutex_t = Usysdep.pthread_mutex_t; > pthread_cond_t = Usysdep.pthread_cond_t; > pthread_key_t = Usysdep.pthread_key_t; > @@ -21,14 +20,9 @@ > VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; > VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; > > - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: > pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; > PROCEDURE detach (thread: pthread_t): int; > PROCEDURE self (): pthread_t; > PROCEDURE equal (t1, t2: pthread_t): int; > - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR > stacksize: size_t): int; > - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: > size_t): int; > PROCEDURE yield (): int; > PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := > NIL): int; > PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; > Index: cygwin/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v > retrieving revision 1.12 > diff -u -r1.12 Usysdep.i3 > --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 > +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -28,7 +28,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; (* opaque *) > - pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > Index: darwin-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ > Usysdep.i3,v > retrieving revision 1.2 > diff -u -r1.2 Usysdep.i3 > --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 > +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -20,7 +20,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = INTEGER; (* opaque *) > - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > Index: freebsd-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ > Usysdep.i3,v > retrieving revision 1.5 > diff -u -r1.5 Usysdep.i3 > --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 > +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -22,7 +22,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > Index: hpux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ > Usysdep.i3,v > retrieving revision 1.4 > diff -u -r1.4 Usysdep.i3 > --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 > +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -25,7 +25,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] > OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF > INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > Index: linux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ > Usysdep.i3,v > retrieving revision 1.10 > diff -u -r1.10 Usysdep.i3 > --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 > +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -21,7 +21,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = Upthreadtypes.pthread_attr_t; > pthread_mutex_t = Upthreadtypes.pthread_mutex_t; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > Index: solaris-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ > Usysdep.i3,v > retrieving revision 1.3 > diff -u -r1.3 Usysdep.i3 > --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 > +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -24,7 +24,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; > (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* > 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) From wagner at elegosoft.com Wed Feb 4 17:38:11 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 17:38:11 +0100 Subject: [M3devel] opencm3 favicon In-Reply-To: <498910C5.6050902@bellsouth.net> References: <498910C5.6050902@bellsouth.net> Message-ID: <20090204173811.6g9osjhs4go8sokw@mail.elegosoft.com> Quoting Martin Bishop : > A little off-topic maybe, but I though opencm3.net needed a favicon. > > I made 2 different ones: > > http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue > square with a white 3, nice and simple. > > http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by > giving the Modula-3 logo to some online favicon generator. Same as the > first one really, only "zoomed in" looking. > > Feel free to use either one if you want. If there are no objections or strong feelings about this or one or the other icon, we can simply place one (the first?) onto our web server. I'd suggest to wait for replies one more day, and then Mike can install it. So speak up now, or be silent forever :-) Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 23:01:58 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:01:58 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html can fail for lack of memory. The use should probably be modified somewhat therefore. e.g. at least: C code: r = pthread_attr_init(...) if (r == ENOMEM) return r; assert(r == 0); Modula-3 code: r = ... IF r = Cerrno.ENOMEM raise out of memory or more generally probably: C: r = pthread_attr_init(...) if (r != 0) return r; Modula-3: r = ... IF r # 0 raise it as is done for errno, whatever or even C: void thread_create(...) { r = pthread_attr_init(...) if (r != 0) raise it as errno, whatever just that I'm a little leary of "certain Modula-3 constructs in C". I'll maybe review more code along these lines. I gather the general gist of things in Modula-3 though is that out of memory is fatal anyway. Raising an exception vs. failing an assertion probably not significantly different if the exception is not meant to be caught and isn't ever caught. (Strange though then the gymnastics I pointed out elsewhere converting one form of out of memory to another form..) The docs also point out that pthread_attr can be reused. It might be reasonable to try to do that somewhat, though of course there are the usual caveats: - how many reusable objects to keep around I suggest 1, for the common case of either using the default or repeatedly using the same non-default. - how to lookup, insert, delete in the cache, in an efficient and thread-safe manner cache size = 1 helps, but doesn't address all questions. I'll leave it alone, unless someone "vehemently agrees". Expect the original change fairly soon.. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 21:24:19 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers > > ok > > On 4 Feb 2009, at 21:14, Jay wrote: > >> >> The following eliminates the only use of pthread_attr_t from the >> cloned headers, slightly reducing the work to port to new platforms. >> It introduces a "small" "portable" C wrapper to encompass the files >> lines of Modula-3 that use pthread_attr_t. ok? >> >> >> Index: ThreadPThread.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThread.m3,v >> retrieving revision 1.89 >> diff -u -r1.89 ThreadPThread.m3 >> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >> @@ -11,11 +11,10 @@ >> Unix, Utime, Word, Upthread, Usched, >> Uerror, ThreadPThreadC, Uexec; >> FROM Upthread >> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >> pthread_mutex_t, >> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >> FROM Compiler IMPORT ThisFile, ThisLine; >> FROM Ctypes IMPORT int; >> -FROM Utypes IMPORT size_t; >> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >> >> (*----------------------------------------------------- types and >> globals ---*) >> @@ -561,9 +560,7 @@ >> VAR >> act := NEW(Activation); >> t := CreateT(act); >> - attr: pthread_attr_t; >> size := defaultStackSize; >> - bytes: size_t; >> BEGIN >> (* determine the initial size of the stack for this thread *) >> TYPECASE closure OF >> @@ -576,17 +573,12 @@ >> t.id := nextId; INC(nextId); >> IF perfOn THEN PerfChanged(t.id, State.alive) END; >> >> - WITH r = Upthread.attr_init(attr) DO END; >> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >> - EVAL Upthread.attr_setstacksize(attr, bytes); >> act.next := allThreads; >> act.prev := allThreads.prev; >> act.size := size; >> allThreads.prev.next := act; >> allThreads.prev := act; >> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >> - EVAL Upthread.attr_destroy(attr); >> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >> ADRSIZE(Word.T), ThreadBase, act) DO >> IF r # 0 THEN >> RTError.MsgI(ThisFile(), ThisLine(), >> "Thread client error: Fork failed with error: >> ", r); >> Index: ThreadPThreadC.c >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.c,v >> retrieving revision 1.8 >> diff -u -r1.8 ThreadPThreadC.c >> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >> @@ -14,6 +14,7 @@ >> #include >> #include >> #endif >> +#include >> >> #ifdef __cplusplus >> extern "C" { >> @@ -145,6 +146,32 @@ >> #endif >> } >> >> +#define VAR(t) t* >> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >> +typedef void* (*start_routine_t)(void*); >> + >> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >> stackSize, start_routine_t start_routine, void* arg) >> +{ >> + int r; >> + size_t bytes; >> + pthread_attr_t attr; >> + >> + r = pthread_attr_init(&attr); >> + assert(r == 0); >> + >> + r = pthread_attr_getstacksize(&attr, &bytes); >> + assert(r == 0); >> + >> + bytes = MAX(bytes, stackSize); >> + pthread_attr_setstacksize(&attr, bytes); >> + >> + r = pthread_create(pthread, &attr, start_routine, arg); >> + >> + pthread_attr_destroy(&attr); >> + >> + return r; >> +} >> + >> #ifdef __cplusplus >> } /* extern "C" */ >> #endif >> Index: ThreadPThreadC.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 ThreadPThreadC.i3 >> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >> @@ -7,6 +7,8 @@ >> UNSAFE INTERFACE ThreadPThreadC; >> >> FROM Ctypes IMPORT int; >> +FROM Cstddef IMPORT size_t; >> +FROM Upthread IMPORT pthread_t, start_routine_t; >> >> (*---------------------------------------------------------------------------*) >> >> @@ -38,4 +40,11 @@ >> >> (*---------------------------------------------------------------------------*) >> >> +(* pthread_create but replace attr with stackSize so that attr need >> not be known to Modula-3 *) >> + >> + >> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >> start_routine: start_routine_t; arg: ADDRESS): int; >> + >> + >> (*---------------------------------------------------------------------------*) >> + >> END ThreadPThreadC. >> >> >> >> >> >> The corrolary then, ignoring the "cloned headers" that I leave >> alone, is: >> >> >> Index: Common/Upthread.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Upthread.i3 >> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >> @@ -10,7 +10,6 @@ >> >> TYPE >> pthread_t = Usysdep.pthread_t; >> - pthread_attr_t = Usysdep.pthread_attr_t; >> pthread_mutex_t = Usysdep.pthread_mutex_t; >> pthread_cond_t = Usysdep.pthread_cond_t; >> pthread_key_t = Usysdep.pthread_key_t; >> @@ -21,14 +20,9 @@ >> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >> >> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >> PROCEDURE detach (thread: pthread_t): int; >> PROCEDURE self (): pthread_t; >> PROCEDURE equal (t1, t2: pthread_t): int; >> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >> stacksize: size_t): int; >> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >> size_t): int; >> PROCEDURE yield (): int; >> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >> NIL): int; >> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >> Index: cygwin/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >> retrieving revision 1.12 >> diff -u -r1.12 Usysdep.i3 >> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -28,7 +28,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; (* opaque *) >> - pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> Index: darwin-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >> Usysdep.i3,v >> retrieving revision 1.2 >> diff -u -r1.2 Usysdep.i3 >> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -20,7 +20,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = INTEGER; (* opaque *) >> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> Index: freebsd-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >> Usysdep.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 Usysdep.i3 >> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -22,7 +22,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> Index: hpux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >> Usysdep.i3,v >> retrieving revision 1.4 >> diff -u -r1.4 Usysdep.i3 >> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -25,7 +25,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> Index: linux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >> Usysdep.i3,v >> retrieving revision 1.10 >> diff -u -r1.10 Usysdep.i3 >> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -21,7 +21,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> Index: solaris-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >> Usysdep.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Usysdep.i3 >> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -24,7 +24,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >> (* 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >> 16 bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) > From jay.krell at cornell.edu Wed Feb 4 23:11:52 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:11:52 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. The entire proposal or the optimizations? The original unoptimized proposal seems like a small change mostly. I checked and the indirection/heap allocation is already there for cond and mutex, but not for pthread_t itself. Factoring out the size I think is a small change. On the other hand, we can also optimize it, pretty much locking in the platform-specificity. It's a tough decision to me. I don't mind the deoptimizations of const-to-var, or adding some function calls, but heap allocs imho are among the things to definitely avoid if not needed. These are untraced as well, so the argument that Modula-3 heap alloc is efficient doesn't apply. One caveat that bothers me though is, like with sem_t, I don't want to have types that are declared "incorrectly". I'd like types that you can only have references too. Probably in that case "give up", declare them as ADDRESS, losing the type safety -- pthread_cond_foo could take a mutex_t and no compilation error. The idea of making them all ADDRESS and adding C functions to alloc/cleanup is also good imho. That allows for one of the optimized forms -- not where the space is at the end of the Thread.T, but where the ADDRESS field is the data itself. I got hung up on pthread_attr_t here because it was efficiently stack allocated and this proposal would have really deoptimized that. The C code I showed avoids that though. Albeit only in the face of creating a thread -- an extra heap allocation per thread create probably not a big deal. Clearly I'm ambivalent. Later, - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 09:42:12 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > It gains something, but maybe it isn't enough > to be worthwhile. The issue is in the subjectivity. > > > It would remove e.g. the following system-dependent lines: > > > Linux: > pthread_t = ADDRESS; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > > > Linux/32: > pthread_attr_t = ARRAY[1..9] OF INTEGER; > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Linux/64: > pthread_attr_t = ARRAY[1..7] OF INTEGER; > pthread_mutex_t = ARRAY[1..5] OF INTEGER; > > > FreeBSD: > pthread_t = ADDRESS; > pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > > > HP-UX: > (* trick from darwin-generic/Upthread.i3 *) > X32 = ORD(BITSIZE(INTEGER) = 32); > X64 = ORD(BITSIZE(INTEGER) = 64); > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Cygwin: > pthread_t = ADDRESS; (* opaque *) > pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > > > Solaris: > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Darwin: (only ppc32 currently) > pthread_t = INTEGER; (* opaque *) > pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > > > (plus AIX, Irix, VMS, Tru64.) > > > Another approach would be make them all ADDRESS and introduce a portable > C layer of "varything thickness", using the same logic. > It would look just like the native pthreads, but there'd be extra allocate/cleanup > calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. > The two layers would be clear and simple, the cost would be the same, > but there would be the conceptual cost of two simple layers instead of one > just one slightly complicated layer. > > > Another approach is maybe make them all addresses on new platforms and introduce > the C layer only on new platforms. Again, about the only change in the Modula-3 > code is extra alloc/cleanup calls. > > > And again, some/all of the code already has the indirection/heap allocation unconditionally. > > > And again, maybe not worth it. I show all the system-dependent code, attempting > to portray in its worst light by showing all of it, but maybe it's really not a lot. > > > For the attr type, we can do something specific to its use. > There is just one use, and we can address it with the following function written in C.. > eh..I'll send a diff later tonight/this week I think. > > > pthread_t and pthread_key_t always happen to be address-sized or smaller. > Maybe just declare them both to be address and assert their size in some C code. > That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. > > For example, we have: > > > TYPE > Activation = UNTRACED REF RECORD > (* global doubly-linked, circular list of all active threads *) > next, prev: Activation := NIL; (* LL = activeMu *) > (* thread handle *) > handle: pthread_t; (* LL = activeMu *) > (* base of thread stack for use by GC *) > stackbase: ADDRESS := NIL; (* LL = activeMu *) > > > so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. > There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. > > > Leaving only cond and mutex. > Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. > rwlock is a useful type though. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 12:53:54 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. >> >> On 4 Feb 2009, at 11:06, Jay wrote: >> >>> >>> There are a few possibilities: >>> >>> >>> Roughly: >>> >>> Where there is >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = ... system specific ... >>> pthread_cond_t = ... system specific ... >>> pthread_mutex_t = ... system specific ... >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> MODULE PThread; >>> VAR >>> a: pthread_t; >>> b: pthread_cond_t; >>> c: pthread_mutex_t; >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> change to: >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = RECORD END; or whatever is correct for an opaque >>> preferably unique type >>> pthread_cond_t = RECORD END; ditto >>> pthread_mutex_t = RECORD END; ditto >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> >>> INTERFACE PThreadC.i3 >>> >>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>> >>> or possibly extern VAR >>> >>> PThreadC.c >>> >>> static pthread_t a = PTHREAD_INIT; >>> static pthread_cond_t b = PTHREAD_COND_INIT; >>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>> >>> pthread_t* GetA() { return &a; } >>> >>> pthread_cond_t* GetB() { return &b; } >>> >>> pthread_mutex_t* GetC() { return &c; } >>> >>> MODULE PThread; >>> VAR >>> a := PThreadC.GetA(); >>> b := PThreadC.GetB(); >>> c := PThreadC.GetA(); >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a^); >>> Upthread.pthread_cond_init_or_whatever(b^); >>> Upthread.pthread_mutex_init_or_whatever(c^); >>> END Foo; >>> >>> or, again, possibly they are variables and it goes a little smaller/ >>> quicker: >>> >>> FROM UPthreadC IMPORT a, b, c; >>> >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> I think that is pretty cut and dry, no controversy. >>> >>> What is less clear is what to do with non-statically allocated >>> variables. >>> >>> Let's say: >>> >>> MODULE PThread; >>> >>> TYPE T = RECORD >>> a:int; >>> b:pthread_t; >>> END; >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T) >>> BEGIN >>> Upthread.init_or_whatever(t.b); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b); >>> DISPOSE(t); >>> END; >>> >>> The desire is something that does not know the size of pthread_t, >>> something like: >>> >>> TYPE T = RECORD >>> a:int; >>> b:UNTRACED REF pthread_t; >>> END; >>> >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T); >>> BEGIN >>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>> CHAR, Upthread.pthread_t_size)); >>> (* Though I really wanted t.b := >>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b^); >>> DISPOSE(t.b); >>> DISPOSE(t); >>> END; >>> >>> >>> However that incurs an extra heap allocation, which is not great. >>> In at least one place, the pointer-indirection-and-heap-allocation >>> is already there >>> so this isn't a deoptimization. However "reoptimizing" it might be >>> nice. >>> >>> >>> What I would prefer a pattern I often use in C -- merging >>> allocations, something like, >>> /assuming/ t is untraced, which I grant it might not be. >>> >>> >>> And ensuring that BYTESIZE(T) is properly aligned: >>> >>> >>> PROCEDURE CreateT():UNTRACED REF T= >>> VAR >>> p : ADDRESS; >>> t : UNTRACED REF T; >>> BEGIN >>> (* Again I would prefer RTAllocator.MallocZeroed *) >>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>> BYTESIZE(T))); >>> t := LOOPHOLE(UNTRACED REF T, p); >>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> >>> That is -- opaque types, size not known at compile-time, but size >>> known at runtime, and >>> do not incur an extra heap allocation for lack of knowing sizes at >>> compile-time. >>> >>> >>> For the statically allocated variables I think there is no >>> controversy. >>> There might a tiny bit of overhead in the use, but it'd be very >>> small, and possibly >>> even removable in the future. I'd rather avoid the variables, as >>> all writable >>> data is to be avoided. Read only pages are better and all that, >>> but ok.. >>> >>> >>> However the value is mainly realized only if statically and >>> dynamically allocated variables are handled. >>> >>> The result of this would be further reduction in platform- >>> specificity when cloning >>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>> platforms. >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jay.krell at cornell.edu >>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>>> >>>> I suggest you come up with a proposal for us to look over before you >>>> change the code base for this. >>>> >>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>> >>>>> >>>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>> in C >>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>> alignment padding anyway so as to allow allocation using >>>>>> malloc(sizeof >>>>>> pthread_mutex_t)? So, it all should just work right? >>>>> >>>>> >>>>> I think "the other way around" and same conclusion. >>>>> malloc should return something "maximally aligned" so that >>>>> >>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>> malloc(sizeof(pthread_mutex_t)); >>>>> >>>>> >>>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>>> speak. >>>>> >>>>> >>>>> Just as long as we don't have >>>>> >>>>> >>>>> TYPE Foo = RECORD >>>>> a: pthread_mutex_t; >>>>> b: pthread_mutex_t; >>>>> c: pthread_t; >>>>> d: pthread_t; >>>>> e: pthread_cond_t; >>>>> f: pthread_cond_t; >>>>> END; >>>>> >>>>> >>>>> and such, ok. >>>>> >>>>> >>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>>> dealing with SSE stuff. >>>>> Something like that. >>>>> >>>>> >>>>> I didn't realize untraced allocations were basically just malloc but >>>>> indeed they are. >>>>> >>>>> >>>>> I'm still mulling over the possible deoptimizations here. >>>>> I'm reluctant to increase heap allocations. >>>>> >>>>> >>>>> >>>>> - Jay >>>> >> From hosking at cs.purdue.edu Thu Feb 5 00:12:18 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:12:18 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: I don't mind if low-level C calls abort rather than raising an exception. Especially, OutOfMemory, which it is unlikely one can recover from with an untraced allocation, unless perhaps a GC can be called to free up space. However, right now, the GC does not return pages to the OS, so the whole question is moot for now. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 5 Feb 2009, at 09:01, Jay wrote: > > http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html > > > can fail for lack of memory. > > > The use should probably be modified somewhat therefore. > > > e.g. at least: > > > C code: > > > r = pthread_attr_init(...) > if (r == ENOMEM) > return r; > assert(r == 0); > > > Modula-3 code: > r = ... > IF r = Cerrno.ENOMEM > raise out of memory > > > or more generally probably: > > > C: > > > r = pthread_attr_init(...) > if (r != 0) > return r; > > > Modula-3: > r = ... > IF r # 0 > raise it as is done for errno, whatever > > > or even C: > > > void thread_create(...) > { > r = pthread_attr_init(...) > if (r != 0) > raise it as errno, whatever > > > just that I'm a little leary of "certain Modula-3 constructs in C". > > > I'll maybe review more code along these lines. > I gather the general gist of things in Modula-3 though > is that out of memory is fatal anyway. Raising an exception > vs. failing an assertion probably not significantly different > if the exception is not meant to be caught and isn't ever caught. > (Strange though then the gymnastics I pointed out elsewhere > converting one form of out of memory to another form..) > > > The docs also point out that pthread_attr can be reused. > It might be reasonable to try to do that somewhat, though > of course there are the usual caveats: > > > - how many reusable objects to keep around > I suggest 1, for the common case of either using the default > or repeatedly using the same non-default. > - how to lookup, insert, delete in the cache, in an efficient > and thread-safe manner > cache size = 1 helps, but doesn't address all questions. > > > I'll leave it alone, unless someone "vehemently agrees". > > > Expect the original change fairly soon.. > > > - Jay > > > > > > > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 21:24:19 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers >> >> ok >> >> On 4 Feb 2009, at 21:14, Jay wrote: >> >>> >>> The following eliminates the only use of pthread_attr_t from the >>> cloned headers, slightly reducing the work to port to new platforms. >>> It introduces a "small" "portable" C wrapper to encompass the files >>> lines of Modula-3 that use pthread_attr_t. ok? >>> >>> >>> Index: ThreadPThread.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThread.m3,v >>> retrieving revision 1.89 >>> diff -u -r1.89 ThreadPThread.m3 >>> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >>> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >>> @@ -11,11 +11,10 @@ >>> Unix, Utime, Word, Upthread, Usched, >>> Uerror, ThreadPThreadC, Uexec; >>> FROM Upthread >>> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >>> pthread_mutex_t, >>> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >>> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >>> FROM Compiler IMPORT ThisFile, ThisLine; >>> FROM Ctypes IMPORT int; >>> -FROM Utypes IMPORT size_t; >>> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >>> >>> (*----------------------------------------------------- types and >>> globals ---*) >>> @@ -561,9 +560,7 @@ >>> VAR >>> act := NEW(Activation); >>> t := CreateT(act); >>> - attr: pthread_attr_t; >>> size := defaultStackSize; >>> - bytes: size_t; >>> BEGIN >>> (* determine the initial size of the stack for this thread *) >>> TYPECASE closure OF >>> @@ -576,17 +573,12 @@ >>> t.id := nextId; INC(nextId); >>> IF perfOn THEN PerfChanged(t.id, State.alive) END; >>> >>> - WITH r = Upthread.attr_init(attr) DO END; >>> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >>> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >>> - EVAL Upthread.attr_setstacksize(attr, bytes); >>> act.next := allThreads; >>> act.prev := allThreads.prev; >>> act.size := size; >>> allThreads.prev.next := act; >>> allThreads.prev := act; >>> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >>> - EVAL Upthread.attr_destroy(attr); >>> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >>> ADRSIZE(Word.T), ThreadBase, act) DO >>> IF r # 0 THEN >>> RTError.MsgI(ThisFile(), ThisLine(), >>> "Thread client error: Fork failed with error: >>> ", r); >>> Index: ThreadPThreadC.c >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.c,v >>> retrieving revision 1.8 >>> diff -u -r1.8 ThreadPThreadC.c >>> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >>> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >>> @@ -14,6 +14,7 @@ >>> #include >>> #include >>> #endif >>> +#include >>> >>> #ifdef __cplusplus >>> extern "C" { >>> @@ -145,6 +146,32 @@ >>> #endif >>> } >>> >>> +#define VAR(t) t* >>> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >>> +typedef void* (*start_routine_t)(void*); >>> + >>> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >>> stackSize, start_routine_t start_routine, void* arg) >>> +{ >>> + int r; >>> + size_t bytes; >>> + pthread_attr_t attr; >>> + >>> + r = pthread_attr_init(&attr); >>> + assert(r == 0); >>> + >>> + r = pthread_attr_getstacksize(&attr, &bytes); >>> + assert(r == 0); >>> + >>> + bytes = MAX(bytes, stackSize); >>> + pthread_attr_setstacksize(&attr, bytes); >>> + >>> + r = pthread_create(pthread, &attr, start_routine, arg); >>> + >>> + pthread_attr_destroy(&attr); >>> + >>> + return r; >>> +} >>> + >>> #ifdef __cplusplus >>> } /* extern "C" */ >>> #endif >>> Index: ThreadPThreadC.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 ThreadPThreadC.i3 >>> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >>> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >>> @@ -7,6 +7,8 @@ >>> UNSAFE INTERFACE ThreadPThreadC; >>> >>> FROM Ctypes IMPORT int; >>> +FROM Cstddef IMPORT size_t; >>> +FROM Upthread IMPORT pthread_t, start_routine_t; >>> >>> (*---------------------------------------------------------------------------*) >>> >>> @@ -38,4 +40,11 @@ >>> >>> (*---------------------------------------------------------------------------*) >>> >>> +(* pthread_create but replace attr with stackSize so that attr need >>> not be known to Modula-3 *) >>> + >>> + >>> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >>> start_routine: start_routine_t; arg: ADDRESS): int; >>> + >>> + >>> (*---------------------------------------------------------------------------*) >>> + >>> END ThreadPThreadC. >>> >>> >>> >>> >>> >>> The corrolary then, ignoring the "cloned headers" that I leave >>> alone, is: >>> >>> >>> Index: Common/Upthread.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Upthread.i3 >>> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >>> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -10,7 +10,6 @@ >>> >>> TYPE >>> pthread_t = Usysdep.pthread_t; >>> - pthread_attr_t = Usysdep.pthread_attr_t; >>> pthread_mutex_t = Usysdep.pthread_mutex_t; >>> pthread_cond_t = Usysdep.pthread_cond_t; >>> pthread_key_t = Usysdep.pthread_key_t; >>> @@ -21,14 +20,9 @@ >>> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >>> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >>> >>> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >>> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >>> PROCEDURE detach (thread: pthread_t): int; >>> PROCEDURE self (): pthread_t; >>> PROCEDURE equal (t1, t2: pthread_t): int; >>> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >>> stacksize: size_t): int; >>> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >>> size_t): int; >>> PROCEDURE yield (): int; >>> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >>> NIL): int; >>> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >>> Index: cygwin/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >>> retrieving revision 1.12 >>> diff -u -r1.12 Usysdep.i3 >>> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >>> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -28,7 +28,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; (* opaque *) >>> - pthread_attr_t = ADDRESS; (* opaque *) >>> pthread_mutex_t = ADDRESS; (* opaque *) >>> pthread_cond_t = ADDRESS; (* opaque *) >>> pthread_key_t = ADDRESS; (* opaque *) >>> Index: darwin-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >>> Usysdep.i3,v >>> retrieving revision 1.2 >>> diff -u -r1.2 Usysdep.i3 >>> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >>> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -20,7 +20,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = INTEGER; (* opaque *) >>> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >>> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >>> pthread_key_t = INTEGER; (* opaque *) >>> Index: freebsd-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >>> Usysdep.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 Usysdep.i3 >>> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >>> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -22,7 +22,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = ADDRESS; >>> pthread_mutex_t = ADDRESS; >>> pthread_cond_t = ADDRESS; >>> pthread_key_t = int; >>> Index: hpux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.4 >>> diff -u -r1.4 Usysdep.i3 >>> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >>> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -25,7 +25,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >>> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >>> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >>> pthread_key_t = int32_t; (* opaque *) >>> Index: linux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.10 >>> diff -u -r1.10 Usysdep.i3 >>> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >>> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -21,7 +21,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >>> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >>> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >>> pthread_key_t = uint32_t; >>> Index: solaris-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >>> Usysdep.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Usysdep.i3 >>> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >>> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -24,7 +24,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >>> (* 32 bytes with 64 bit alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >>> 16 bytes with 64 bit alignment *) >>> pthread_key_t = int32_t; (* opaque *) >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 02:19:58 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 01:19:58 +0000 Subject: [M3devel] cygwin jmp_buf size incorrect In-Reply-To: <495B901F.1E75.00D7.1@scires.com> References: <20081231105208.9CF4710D5DDE@birch.elegosoft.com> <495B4846.1E75.00D7.1@scires.com> <495B901F.1E75.00D7.1@scires.com> Message-ID: > Cygwin's setjmp.h incorrectly typedefs jmp_buf confirmed fyi/fwiw, unfortunate: http://cygwin.com/ml/cygwin/2009-01/msg00863.html - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: rcoleburn at scires.com; m3devel at elegosoft.com > Subject: RE: [M3devel] [M3commit] CVS Update: cm3 > Date: Thu, 29 Jan 2009 17:10:53 +0000 > > >> In reading your post, you state that you deoptimized the native implementation >> to make it match Cygwin. Now, I'm not sure how > > > I was wrong on this point. > Cygwin's setjmp.h incorrectly typedefs jmp_buf, indeed, to be much larger than "native", but the header is incorrect. Cygwin actually has a slightly smaller jmp_buf than native (13 ints vs. 16 ints), but we use the native size always, deoptimizing the Cygwin case. > > - Jay > > ________________________________ >> Date: Wed, 31 Dec 2008 15:30:40 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> >> >> >> >> >> >> Jay: >> >> >> >> First, I do want to say thanks for all you are doing for the cause of Modula-3. I don't think we say thanks enough for what others do for us. THANK YOU! >> >> >> >> I don't want to be perceived as "complaining", rather I am trying to voice my opinion in the hopes of influencing future direction. Of course, since I'm not doing the work, I can only make suggestions. >> >> >> >> In reading your post, you state that you deoptimized the native implementation to make it match Cygwin. Now, I'm not sure how much effect this deoptimization has (maybe little), but it is clear that in this case your implementation choice has favored the non-native implementation over the native one. IMO, tradeoffs of this type are not good. If one is trying to convince someone to use Modula-3, why would you want to give them a "deoptimized" version just to make it easier to support a non-native environment---indeed, one that they may not even want/use? If we have to make a trade-off, I say favor the native implementation always over the non-native one. >> >> >> >> What I'm trying to say here is that my experience as a software, systems, and program engineer is that I've always been forced to justify the cost/benefit of development tools for any project. Many times I've had to go head to head with folks higher up in my own organization or in the customer's organization whose preconceived opinions were based on rumor and what they've heard rather than actual factual hands-on experience. I want to pick the best tool for the job instead of being forced to pick an inferior tool because someone higher in the food chain demanded it based on faulty preconceived opinion. I like Modula-3. I've found that I am more productive using it. But, if the compiler doesn't produce efficient code, I lose ground in arguing with the higher-ups. >> >> >> >> As for Python, I've never ventured to learn it, so for me, it is something of a mystery. But you miss the point. I'm not arguing the merits of Python, I'm just saying that anything Modula-3 requires on top of what is provided by the standard host platform represents a potential obstacle or barrier to ease of use/implementation. It also sends the message that somehow Modula-3 is not complete on its own, we have get Python just to install and oh yes we need a C compiler and a linker and a ...? IMO, ultimately we need a turn-key download and install routine for Modula-3 that just works, out-of-the-box. If you give me an EXE, a CMD, or a BAT, for the install, I can run it on Windows, but if you give me an install routine that requires I first install something else, e.g. Python, then that becomes a barrier to the folks who don't know Python or already have it installed. >> >> >> >> Am I alone in this line of thought? If so, I'll just be quiet. >> >> >> >> BTW, I can certainly help in maintaining the CMD/BAT install routines or in making a better CMINSTALL. My problem is that right now, it is hard to understand all the dependencies for proper building of cm3 from scratch. Indeed, I've contributed some CMD/BAT install stuff in the past, but it is now out of date. Perhaps if there is a way we could better document the proper build order and dependencies, it would be easier for folks in the community to help in this area. I certainly would volunteer to do the CMD files as long as I had enough information to do it right. At one point, I thought we had a file that showed the package build order and dependencies. Not sure if the format of this file is well-documented or if the file is kept up-to-date. >> >> >> >> Regards, >> >> Randy >> >> >>>>> Jay 12/31/2008 1:34 PM>>> >>> you've made the CYGWIN implementation "appear" >>> be the same as the native Windows implementation. >>> But they are not the same. >> >> >> But they mostly are, from the front end's point of view. >> They are both little endian, x86, use the same jump_buf size (I grew it to match Cygwin's, which is a deoptimization of stack use on native NT386), the same type sizes and alignments..er..not sure about LONGINT. >> They might vary in newline and one uses the internal backend and one the external, however which backend they use is actually minor to the front end, though I think it affects if the front end "deals with" calling conventions, particularly left-to-right vs. right-to-left and struct returns. >> Object code produced by one can generally be linked with object code produced by the other. >> >> >> SOLgnu and SOLsun are a better example of this, though they do go ahead and duplicate tons of stuff that if I had implemented them, I would have avoided. >> They are truly identical in every respect in the front end and back end. >> They only vary in the config file. >> This is wasteful, because, "by default", if I'm put together a comprehensive cross build system without being a little smarter, I end up building two identical m3cgs. My config files are willing to "probe across" SOLsun and SOLgnu though, so I need only one m3cg for the two of them. >> >> >> Given that "NT386" can describe a combinatorial explosion of configurations, it makes some sense to keep it just one if possible. The compiler mostly doesn't care. >> >> >> >>> "- BUILD_DIR does not necessarily equal HOST or TARGET, >>> because of how I structured I386_CYGWIN to be a "configuration" >>> where TARGET is still NT386." >> >>> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". >> >> BUILD_DIR also does not equal HOST or TARGET when doing profiled builds, which admittedly I never have. >> Therefore, BUILD_DIR is arbitrary. >> I might be confusing something here though -- since I have never built a profiled build, I also haven't shipped one. It could be that "shipped BUILD_DIR" does equal TARGET, for profiled builds, in which case I did set a precedent. But the "override" code isn't using shipped files, so.. >> I have to check. >> >>> as long as it does not compromise the native Windows implementation >> >> Agreed and it basically doesn't. >> Show me where it does. >> The only thing I can think of is the jmpbuf size. >> >>> I don't want to have to install CYGWIN either in order to make >>> the native implementation work on Windows. >> >> Please don't complain about stuff that isn't true or without being more specific. >> I know of no dependency by the native implementation on Cygwin. >> >> In fact, installing Cygwin does tend to break the native implementation, depending on $PATH, because it has a link.exe that is a completely different program (ie: ln.exe). >> I tried experimenting with using cl to drive link.exe but couldn't quite get it to work, for stupid reasons related to response files, which surely is fixable by extending response file support in cm3... >> >> As it is, I usually delete \cygwin\bin\link.exe, or remove cygwin from $PATH. >> True, I don't ever uninstall Cygwin for testing, so the dependency could creep in by accident. >> >> >>> I also still prefer the CMINSTALL, CMD, or BAT files >>> for install as opposed to having to get Python or something else. Just my 2 cents. >> >> Once built and installed, there is no dependency on cmd, bat, cminstall, or python. >> cminstall is pretty worthless imho, as long as you set PATH, INCLUDE, and LIB. >> That is also a competing workaround for paths with spaces. >> And allows moving around among different versions of Visual C++, which is good and bad. >> Either you can have n installs of cm3, each configured tightly for one specific Visual C++, >> or you can have 1 install of cm3, that is flexibly configured, that you "reconfigure" by altering the environment. I do the second. >> >> If you want to build the system, in a well automated way, with cmd and bat, you are welcome to write them. >> Maybe the ones I left in the tree work, but i never use them any longer. >> I use the Python all the time. >> >> Or you can manually cd around (as I suspect Tony does). >> Personally I find cmd/bat among the worst programming languages ever and would rather not write it. >> jscript via cscript.exe would be a good alternative, it is always there at least as of Windows 2000 or perhaps with IE installed on older versions, but then you have to duplicate work across Unix and Windows. >> That is, for Windows-only no-cmd, no-install command line automation, JScript and VBScript are good choices, but Windows-only rules them out. The install is worth it. >> Python is a very decent programming language that is very portable across "all" systems. >> Perl would be the next best choice, though..I just don't like much. >> sh/bash requires an install on Windows, so its built-inness on Posix I claim isn't a conclusive win. >> I strongly encourage you to try out Python. >> >> Another avenue is to merge the sh/cmd/python into cm3 itself. >> It shouldn't be all that hard. >> >> Modula-3 still needs a C linker. >> And there is C code that I didn't put in -- hand.c and dtoa.c. >> If someone writes a linker in Modula-3, or gets the .obj loader working, I'll be more open to eliminating C. >> >> But using C is much less error prone and much more portable, in some parts of the system. >> >> You may label C as "evil", but the other "evil" I am battling is tedious error prone "header cloning". >> You pretty much must chose one. >> The header cloning can be reduced, and its error proned-ness and difficulty various per system, depending on how gnarled up the headers are with ifdefs, compatibility hacks, processor-specificty, "cleansing" (where the installed headers are processor specific, deriving from #ifdef'ed or somesuch other files, but now I argue both sides, #ifdef is hard to read, but removing them removes information unless you track further back), etc. For example the OpenBSD headers are much more readable. I suspect NetBSD are too but haven't looked yet. The Linux headers contain a lot of #ifdef and they are also processor-specific I think -- you know, my /usr/include/errno.h on one system I think didn't show that x86 and SPARC use different values. >> >> >> - Jay >> >> >> >> ________________________________ >> >> >> Date: Wed, 31 Dec 2008 10:28:37 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> Jay: >> >> >> >> Please explain what you mean by: >> >> >> >> "- BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386." >> >> >> >> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". Indeed, I have stuff that depends on the meaning of these things. Your statement seems to imply that "under the covers" you've made the CYGWIN implementation "appear" to be the same as the native Windows implementation. But they are not the same. >> >> >> >> On another note, All this CYGWIN stuff may be a nice way for die-hard Unix fans to run Modula-3 on Windows, and I have no objection to providing it, as long as it does not compromise the native Windows implementation. My main concern is the native implementation of Modula-3 on Windows. My preference would be to keep the NT386 implementation's dependencies on other stuff to a bare minimum, i.e., don't introduce anything that would require someone to have to acquire something besides what comes in the standard Windows OS in order to make Modula-3 run. As it is now, we already have to get a C compiler and linker. Fortunately, Microsoft has made the Visual Studio Express editions a free download, so this is not too bad. I don't want to have to install CYGWIN either in order to make the native implementation work on Windows. I also still prefer the CMINSTALL, CMD, or BAT files for install as opposed to having to get Python or something else. Just my 2 cents. >> >> >> >> Finally, I would go a step further and suggest that the Modula-3 implementation on every platform should strive to require minimal dependencies on anything not provided standard with that platform's operating system. >> >> >> >> Call me an idealist, but it just galls me that I have to have a C compiler/linker to build Modula-3. Modula-3 is a systems programming language. It should stand on its own. From a purely economical viewpoint, why should I have to buy something I don't want (C language development environment) in order to have the privilege of using what I do want (Modula-3 language development environment). >> >> >> >> Regards, >> >> Randy >> >>>>> Jay Krell 12/31/2008 11:52 AM>>> >> CVSROOT:/usr/cvs >> Changes by:jkrell at birch.08/12/31 11:52:08 >> >> Modified files: >> cm3/m3-comm/netobj/src/: netobj-ov.tmpl >> cm3/m3-comm/sharedobj/src/: sharedobj-ov.tmpl >> cm3/m3-libs/libm3/src/bundleintf/: bundle-ov.tmpl >> cm3/m3-ui/zeus/src/: m3zume-ov.tmpl >> cm3/m3-ui/juno-2/juno-app/src/: m3makefile >> >> Log message: >> Partly kinda sorta fix some cross build scenarios, without >> affecting native builds. >> >> It's a larger more general problem though. >> >> - BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386. >> >> - a cross build can run the shipped binary anyway, >> and probably should (I didn't have the unshipped binaries around) >> >> - There should probably be automation to ensure all the tools are build. >> ie: do-cm3-tools or do-cm3-crosstools. ie: build just the needed packages, >> for the sniffed native platform. >> >> Cross builds have other problems. >> >> I keep hitting the following annoyances: >> >> ignoring foo/bar override when foo\bar already overridden >> override paths should either be canonicalized to one slash type >> or at least when there is a duplicate, canonicalize then and only >> complain if canonicals vary >> This is due to mixing I386_NT and I386_CYGWIN. >> Similarly the problem demonstrated regarding m3unix.h in Uwaitpid.quake. >> >> Perhaps the change I made to allow forward slashes on Win32 was not good, esp. due to >> its apparent inadequacy. >> >> The "lib" directory, specifically \cm3\lib\hand.obj is target..er, configuration dependent >> the gcc hand.obj cannot be directly linked by Visual C++, for reasons to do with libgcc >> >> lib should probably have "target" or "build_dir" under it >> >> and/or hand.obj specifically should be merged into m3core.lib >> >> The mentor quake code generally fails in cross environments, probably due to slashes. >> >> host=NT386 (GNU?), target=LINUXLIBC6 m3zume is access violating >> >> I'm also highly suspicious of all this "override" stuff. >> It clearly causes too much duplication and distribution of information. >> I shouldn't have to know the directory structure of my dependencies, >> and even if I do, I should be able to share that knowledge with their many >> other dependents. The "scripts" directory also figures this sort of stuff out automatically.. >> Being able to have multiple package stores is well and good. >> I'm not sure they need to ever be used in an "unshipped" form, but instead just >> use alternate roots and create new empty roots as needed. ? >> >> From hosking at cs.purdue.edu Thu Feb 5 00:04:47 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:04:47 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: On 5 Feb 2009, at 09:11, Jay wrote: > >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. > > > The entire proposal or the optimizations? The C allocation of M3 objects, without going through NEW. There are a whole slew of reasons why I'd like to avoid that. > The original unoptimized proposal seems like a small change mostly. > I checked and the indirection/heap allocation is already there > for cond and mutex, but not for pthread_t itself. > Factoring out the size I think is a small change. Yes, possibly. Let me look at it. > On the other hand, we can also optimize it, pretty much > locking in the platform-specificity. It's a tough decision to me. > I don't mind the deoptimizations of const-to-var, or adding > some function calls, but heap allocs imho are among the things > to definitely avoid if not needed. These are untraced as well, > so the argument that Modula-3 heap alloc is efficient doesn't apply. Right, just that you lose some compiler knowledge of where allocations occur. I have some work I am doing where I analyse code for allocation sites. > One caveat that bothers me though is, like with sem_t, > I don't want to have types that are declared "incorrectly". > I'd like types that you can only have references too. > Probably in that case "give up", declare them as ADDRESS, > losing the type safety -- pthread_cond_foo could take a mutex_t > and no compilation error. Sure. > The idea of making them all ADDRESS and adding C functions to alloc/ > cleanup > is also good imho. That allows for one of the optimized forms -- > not where the space is at the end of the Thread.T, but where the > ADDRESS field is the data itself. Possibly. > I got hung up on pthread_attr_t here because it was efficiently > stack allocated and this proposal would have really deoptimized that. > The C code I showed avoids that though. > Albeit only in the face of creating a thread -- an extra heap > allocation > per thread create probably not a big deal. Hmm. > Clearly I'm ambivalent. OK, let me think on it. > Later, > > - Jay > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 09:42:12 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> It gains something, but maybe it isn't enough >> to be worthwhile. The issue is in the subjectivity. >> >> >> It would remove e.g. the following system-dependent lines: >> >> >> Linux: >> pthread_t = ADDRESS; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> >> >> Linux/32: >> pthread_attr_t = ARRAY[1..9] OF INTEGER; >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Linux/64: >> pthread_attr_t = ARRAY[1..7] OF INTEGER; >> pthread_mutex_t = ARRAY[1..5] OF INTEGER; >> >> >> FreeBSD: >> pthread_t = ADDRESS; >> pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> >> >> HP-UX: >> (* trick from darwin-generic/Upthread.i3 *) >> X32 = ORD(BITSIZE(INTEGER) = 32); >> X64 = ORD(BITSIZE(INTEGER) = 64); >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF >> INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Cygwin: >> pthread_t = ADDRESS; (* opaque *) >> pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> >> >> Solaris: >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* >> 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 >> bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Darwin: (only ppc32 currently) >> pthread_t = INTEGER; (* opaque *) >> pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> >> >> (plus AIX, Irix, VMS, Tru64.) >> >> >> Another approach would be make them all ADDRESS and introduce a >> portable >> C layer of "varything thickness", using the same logic. >> It would look just like the native pthreads, but there'd be extra >> allocate/cleanup >> calls -- to do the heap alloc/cleanup when the underlying types are >> larger than addresses. >> The two layers would be clear and simple, the cost would be the same, >> but there would be the conceptual cost of two simple layers instead >> of one >> just one slightly complicated layer. >> >> >> Another approach is maybe make them all addresses on new platforms >> and introduce >> the C layer only on new platforms. Again, about the only change in >> the Modula-3 >> code is extra alloc/cleanup calls. >> >> >> And again, some/all of the code already has the indirection/heap >> allocation unconditionally. >> >> >> And again, maybe not worth it. I show all the system-dependent >> code, attempting >> to portray in its worst light by showing all of it, but maybe it's >> really not a lot. >> >> >> For the attr type, we can do something specific to its use. >> There is just one use, and we can address it with the following >> function written in C.. >> eh..I'll send a diff later tonight/this week I think. >> >> >> pthread_t and pthread_key_t always happen to be address-sized or >> smaller. >> Maybe just declare them both to be address and assert their size in >> some C code. >> That might waste a few bytes esp. on 64 bit platforms, or it might >> merely fill in the padding-for-alignment. >> >> For example, we have: >> >> >> TYPE >> Activation = UNTRACED REF RECORD >> (* global doubly-linked, circular list of all active threads *) >> next, prev: Activation := NIL; (* LL = activeMu *) >> (* thread handle *) >> handle: pthread_t; (* LL = activeMu *) >> (* base of thread stack for use by GC *) >> stackbase: ADDRESS := NIL; (* LL = activeMu *) >> >> >> so on 64 bit platforms where pthread_t is a 32bit integer, it is >> taking up 64 bits anyway. >> There are two static pthread_key_ts, so making them address would >> waste 8 bytes on some/many 64bit platforms. >> >> >> Leaving only cond and mutex. >> Some of the platforms declare more types such as rwlock, >> rwlockattr, but they are never used. >> rwlock is a useful type though. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 12:53:54 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. >>> >>> On 4 Feb 2009, at 11:06, Jay wrote: >>> >>>> >>>> There are a few possibilities: >>>> >>>> >>>> Roughly: >>>> >>>> Where there is >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = ... system specific ... >>>> pthread_cond_t = ... system specific ... >>>> pthread_mutex_t = ... system specific ... >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> MODULE PThread; >>>> VAR >>>> a: pthread_t; >>>> b: pthread_cond_t; >>>> c: pthread_mutex_t; >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> change to: >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = RECORD END; or whatever is correct for an opaque >>>> preferably unique type >>>> pthread_cond_t = RECORD END; ditto >>>> pthread_mutex_t = RECORD END; ditto >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> >>>> INTERFACE PThreadC.i3 >>>> >>>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>>> >>>> or possibly extern VAR >>>> >>>> PThreadC.c >>>> >>>> static pthread_t a = PTHREAD_INIT; >>>> static pthread_cond_t b = PTHREAD_COND_INIT; >>>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>>> >>>> pthread_t* GetA() { return &a; } >>>> >>>> pthread_cond_t* GetB() { return &b; } >>>> >>>> pthread_mutex_t* GetC() { return &c; } >>>> >>>> MODULE PThread; >>>> VAR >>>> a := PThreadC.GetA(); >>>> b := PThreadC.GetB(); >>>> c := PThreadC.GetA(); >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a^); >>>> Upthread.pthread_cond_init_or_whatever(b^); >>>> Upthread.pthread_mutex_init_or_whatever(c^); >>>> END Foo; >>>> >>>> or, again, possibly they are variables and it goes a little >>>> smaller/ >>>> quicker: >>>> >>>> FROM UPthreadC IMPORT a, b, c; >>>> >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> I think that is pretty cut and dry, no controversy. >>>> >>>> What is less clear is what to do with non-statically allocated >>>> variables. >>>> >>>> Let's say: >>>> >>>> MODULE PThread; >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:pthread_t; >>>> END; >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T) >>>> BEGIN >>>> Upthread.init_or_whatever(t.b); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> The desire is something that does not know the size of pthread_t, >>>> something like: >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:UNTRACED REF pthread_t; >>>> END; >>>> >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T); >>>> BEGIN >>>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>>> CHAR, Upthread.pthread_t_size)); >>>> (* Though I really wanted t.b := >>>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b^); >>>> DISPOSE(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> >>>> However that incurs an extra heap allocation, which is not great. >>>> In at least one place, the pointer-indirection-and-heap-allocation >>>> is already there >>>> so this isn't a deoptimization. However "reoptimizing" it might be >>>> nice. >>>> >>>> >>>> What I would prefer a pattern I often use in C -- merging >>>> allocations, something like, >>>> /assuming/ t is untraced, which I grant it might not be. >>>> >>>> >>>> And ensuring that BYTESIZE(T) is properly aligned: >>>> >>>> >>>> PROCEDURE CreateT():UNTRACED REF T= >>>> VAR >>>> p : ADDRESS; >>>> t : UNTRACED REF T; >>>> BEGIN >>>> (* Again I would prefer RTAllocator.MallocZeroed *) >>>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>>> BYTESIZE(T))); >>>> t := LOOPHOLE(UNTRACED REF T, p); >>>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> >>>> That is -- opaque types, size not known at compile-time, but size >>>> known at runtime, and >>>> do not incur an extra heap allocation for lack of knowing sizes at >>>> compile-time. >>>> >>>> >>>> For the statically allocated variables I think there is no >>>> controversy. >>>> There might a tiny bit of overhead in the use, but it'd be very >>>> small, and possibly >>>> even removable in the future. I'd rather avoid the variables, as >>>> all writable >>>> data is to be avoided. Read only pages are better and all that, >>>> but ok.. >>>> >>>> >>>> However the value is mainly realized only if statically and >>>> dynamically allocated variables are handled. >>>> >>>> The result of this would be further reduction in platform- >>>> specificity when cloning >>>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>>> platforms. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> From: hosking at cs.purdue.edu >>>>> To: jay.krell at cornell.edu >>>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>>> CC: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] further reducing cloned headers wrt >>>>> pthread? >>>>> >>>>> I suggest you come up with a proposal for us to look over before >>>>> you >>>>> change the code base for this. >>>>> >>>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>>> >>>>>> >>>>>>> Hmm, yes, you are right that there is a possible alignment >>>>>>> issue. I >>>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>>> in C >>>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>>> alignment padding anyway so as to allow allocation using >>>>>>> malloc(sizeof >>>>>>> pthread_mutex_t)? So, it all should just work right? >>>>>> >>>>>> >>>>>> I think "the other way around" and same conclusion. >>>>>> malloc should return something "maximally aligned" so that >>>>>> >>>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>>> malloc(sizeof(pthread_mutex_t)); >>>>>> >>>>>> >>>>>> works. pthread_mutex_t doesn't need the padding, malloc does, >>>>>> so to >>>>>> speak. >>>>>> >>>>>> >>>>>> Just as long as we don't have >>>>>> >>>>>> >>>>>> TYPE Foo = RECORD >>>>>> a: pthread_mutex_t; >>>>>> b: pthread_mutex_t; >>>>>> c: pthread_t; >>>>>> d: pthread_t; >>>>>> e: pthread_cond_t; >>>>>> f: pthread_cond_t; >>>>>> END; >>>>>> >>>>>> >>>>>> and such, ok. >>>>>> >>>>>> >>>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>>> I think on Win9x only 4 alignment, thus there is >>>>>> _malloc_aligned for >>>>>> dealing with SSE stuff. >>>>>> Something like that. >>>>>> >>>>>> >>>>>> I didn't realize untraced allocations were basically just >>>>>> malloc but >>>>>> indeed they are. >>>>>> >>>>>> >>>>>> I'm still mulling over the possible deoptimizations here. >>>>>> I'm reluctant to increase heap allocations. >>>>>> >>>>>> >>>>>> >>>>>> - Jay >>>>> >>> From mika at async.caltech.edu Thu Feb 5 05:33:09 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Wed, 04 Feb 2009 20:33:09 -0800 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: Your message of "Wed, 04 Feb 2009 22:01:58 GMT." Message-ID: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Jay writes: ... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) ... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika From hosking at cs.purdue.edu Thu Feb 5 05:45:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 15:45:46 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. On that count, does anyone know what happened to the CM Java VM? Is it available anywhere? On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > Jay writes: > ... >> I'll maybe review more code along these lines. >> I gather the general gist of things in Modula-3 though >> is that out of memory is fatal anyway. Raising an exception >> vs. failing an assertion probably not significantly different >> if the exception is not meant to be caught and isn't ever caught. >> (Strange though then the gymnastics I pointed out elsewhere >> converting one form of out of memory to another form..) > ... > > Back in SRC days I remember there was a discussion at some length > about what to do in case of running out of memory. I think the > project was abandoned as people realized it was quite a tricky > problem... > > I don't believe PM3 has out of memory exceptions, nor did SRC > M3...? It's a wild guess but maybe this has something to do with > the Critical Mass modifications for their JVM? > > Mika From dabenavidesd at yahoo.es Thu Feb 5 18:56:06 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Thu, 5 Feb 2009 09:56:06 -0800 (PST) Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <519119.97354.qm@web24711.mail.ird.yahoo.com> Hi all; I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at: ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/ Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps. Thanks --- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headers Para: "Jay" CC: m3devel at elegosoft.com Fecha: mi?rcoles, 4 febrero, 2009 11:33 Jay writes: .... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) .... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:11:37 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:11:37 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Does this make sense? It is pushing my Modula-3 knowledge. I didn't yet check the number of bytes requested by malloc/calloc. All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 7.txt URL: From jay.krell at cornell.edu Thu Feb 5 19:29:59 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:29:59 +0000 Subject: [M3devel] out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: Here are some ideas that contribute to handling out of memory being useful/good: "stress" Stress a system.Things start going slow and failing, ok. You can't succeed against all odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion" A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources. Assuming that important state is managed well, like in a transactional database. And that most state is expendable. As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/ "malicious", as well as insulating "important" server processes (daemons) from run away/malicious clients. Guard against "denial of service attacks". Some people like to put hard limits on things. "I will reject any strings longer than 2gig". However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it. Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:39:09 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:39:09 +0000 Subject: [M3devel] FW: out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: (truncated..) From: jay.krell at cornell.eduTo: dabenavidesd at yahoo.es; m3devel at elegosoft.comSubject: RE: out of memory philosophyDate: Thu, 5 Feb 2009 18:29:59 +0000 Here are some ideas that contribute to handling out of memory being useful/good: "stress"Stress a system.Things start going slow and failing, ok. You can't succeed againstall odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion"A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources.Assuming that important state is managed well, like in a transactional database.And that most state is expendable.As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/"malicious", as well as insulating "important" server processes (daemons)from run away/malicious clients. Guard against "denial of service attacks".Some people like to put hard limits on things. "I will reject any strings longer than 2gig".However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it.Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:57:17 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:57:17 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Hm, nevermind that. More later. I think either wrapping it up more in C would be cleaner or even Modula-3 ("Upthread.m3"), than this sort of "split", or at least changing it to ADDRESS and if size <= BYTESIZE(ADDRESS), just use that space and save the heap alloc. On systems that already have either a small object or an indirection, save the heap alloc. Later, - Jay From: jay.krell at cornell.eduTo: m3devel at elegosoft.comSubject: reducing system-dependence in Upthread.i3?Date: Thu, 5 Feb 2009 18:11:37 +0000 Does this make sense?It is pushing my Modula-3 knowledge.I didn't yet check the number of bytes requested by malloc/calloc.All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Fri Feb 6 16:12:00 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Fri, 06 Feb 2009 16:12:00 +0100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Message-ID: <20090206161200.em81i2uh44sg8koo@mail.elegosoft.com> Quoting Tony Hosking : > Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. > > On that count, does anyone know what happened to the CM Java VM? Is it > available anywhere? AFAIK it is not. I think I asked Farshad Nayeri some years ago, but got no answer. Maybe it's still in commercial use, or there are some other legal problems with the code (as Sun was probably involved). Nonetheless, it cannot harm to ask again... Olaf > On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > >> Jay writes: >> ... >>> I'll maybe review more code along these lines. >>> I gather the general gist of things in Modula-3 though >>> is that out of memory is fatal anyway. Raising an exception >>> vs. failing an assertion probably not significantly different >>> if the exception is not meant to be caught and isn't ever caught. >>> (Strange though then the gymnastics I pointed out elsewhere >>> converting one form of out of memory to another form..) >> ... >> >> Back in SRC days I remember there was a discussion at some length >> about what to do in case of running out of memory. I think the >> project was abandoned as people realized it was quite a tricky >> problem... >> >> I don't believe PM3 has out of memory exceptions, nor did SRC >> M3...? It's a wild guess but maybe this has something to do with >> the Critical Mass modifications for their JVM? >> >> Mika -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From martinbishop at bellsouth.net Wed Feb 11 05:01:38 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 10 Feb 2009 22:01:38 -0600 Subject: [M3devel] modula3.org updated links Message-ID: <49924DA2.6090607@bellsouth.net> A while back I said it would be nice if modula3.org could get it's links updated, as quite a few of them were dead. Well I went through the links on the front page of modula3.org (as well as the separate "Links" page) and updated them. I only removed one link, and replaced all the dead ones with either mirrors or just better links. (NOTE: They look bad because they aren't using the CSS, but I'm just putting these up so someone (Olaf?) can save the source and push to the modula3.org CVS.) http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html (Main page) http://mbishop.esoteriq.org/modula3.org/index.html (Links page) From jay.krell at cornell.edu Wed Feb 11 07:07:20 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 06:07:20 +0000 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: I must say, I find the design of the various web sites terrible. The stuff i want is far buried, not just deep, but sometimes under odd sounding links. The offenders include: "www service" is one of the worst named but most useful links, it is a link to one of the main Modula-3 pages. Given that this is already on a web page, "www service" adds no meaning. It is slightly a pain to find the CVS browsing page, the tinderbox status, and something else I forget. And it is annoying how the CVS pages opens doubly nested. Gotta run, - Jay> Date: Tue, 10 Feb 2009 22:01:38 -0600> From: martinbishop at bellsouth.net> To: m3devel at elegosoft.com> Subject: [M3devel] modula3.org updated links> > A while back I said it would be nice if modula3.org could get it's links> updated, as quite a few of them were dead. Well I went through the> links on the front page of modula3.org (as well as the separate "Links"> page) and updated them.> > I only removed one link, and replaced all the dead ones with either> mirrors or just better links.> > (NOTE: They look bad because they aren't using the CSS, but I'm just> putting these up so someone (Olaf?) can save the source and push to the> modula3.org CVS.)> > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html> (Main page)> > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 11 09:28:06 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 08:28:06 +0000 Subject: [M3devel] apsl? (Apple source license?) Message-ID: Can we add Apple APSL-licensed code into the Modula-3 libraries? In particular, like, _setjmp.h? Or maybe even the get/set/make/swapcontext code? It looks me like ASPL is: "not viral" -- it does not impact the code it is linked to, mostly It carries with it an "advertising clause", which is somewhat viral. That is, you have to state you are using APSL code, and you might have to reveal that specific code (unknown) but there are no additional restrictions on code it is linked with. Upon further reading.. The license discusses "original code" and "modified code". If code is modified, it must be clearly marked as such. Reasonable, but annoying. If you modify the code, you do have to distribute it with binaries. Mildly viral. If you don't modify the code, you don't have to distribute any source. Good. http://www.opensource.apple.com/apsl/ http://www.gnu.org/philosophy/apsl.html (I wish everyone would just use the BSD license...but oh well..) - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Fri Feb 13 19:22:33 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:22:33 -0600 Subject: [M3devel] More on new Text package Message-ID: <4995BA69.6080705@wichita.edu> I neglected to mention that the new package, by default, uses the old algorithms, although there will be constant-time slowdown, because it decides dynamically on every call to do this. Also, there is a lot of instrumentation being executed. To get the new algorithms, set TextClass.Old to FALSE. You can change this between any two calls into the package. Rodney Bates From rodney.bates at wichita.edu Fri Feb 13 19:05:30 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:05:30 -0600 Subject: [M3devel] New experimental Text module Message-ID: <4995B66A.8000906@wichita.edu> There is an experimental replacement for the various library code involving the type TEXT, now checked in the CVS repository, in cm3/m3-libs/m3core/src/text, under branch devel_m3core_text_newtext_branch. There is a test program for it in cm3/m3-libs/m3core/tests/newtext. Approach: I tried to see how much I could improve the performance of CM3 TEXT operations by changing the algorithms only, leaving the data structure, both declarations and invariants, unchanged. This presents minimum disruption elsewhere. Both the pickle code and existing pickle files will be unaffected, along with other things that use pickles. Changes: I eliminated as much recursion as possible, converting some instances of recursion to tail-recursions, and then converting all tail-recursion instances to iteration. Recursion remains when: 1) There is true nonlinear recursion. This happens in only one place in concatenation. Here, I did the recursion on the shorter (and thus hopefully shallower) side of the tree. 2) Where necessary to avoid the chance of creating an identical copy of a known, already existing TextCat.T node. 3) The recursion needs to go through a method dispatch. In concatenations, I "flattened" concatenation results that do not exceed a length cutoff. By "flattening", I mean copying into a single node of type Text8.T, Text8Short.T, Text16, or Text16Short.T. I experimentally tuned the length cutoff to 32 bytes, for best compromise among speed and time and in various use cases. In concatenations, I did some heuristic rebalancing. I used the relative lengths of strings as a crude approximation for the relative depths of trees. Actual depths are not cached in the nodes, and computing them would have been O(n) for each concatenation operation. I postponed rebalancing flat strings into a tree, keeping them at the top, where they are available for further flattening, until there is no chance of this happening. Most of the existing operations were sometimes unnecessarily converting strings from CHAR to WIDECHAR arrays, involving character-at-a-time conversion. This was a likely very common case, and I eliminated it when easily detectable. Bugs: I fixed (I hope!) a few bugs I discovered in the existing code. Find[Wide]CharR had an off-by-one bug in the where the search started. String[8|16].FindCharR was doing an address computation too early, in a local variable declaration, before a needed NIL check, making the check fail to work. HasWideChars was only computing whether the representation had the capability to hold wide characters, not whether any were actually there. This was not a useful meaning for the result. TextCat.MultiCat (and NewMulti, which calls it) were not checking for NILs. Assuming the result was ever used, these would eventually cause runtime errors, but not until it was more difficult to diagnose them. Testing: The modified code can be dynamically switched between the old and new algorithms. It is also loaded with instrumentation. All of this will slow it down, but the old/new comparisons should not have significant bias. TextClass.i3 has a lot of new stuff to allow clients to control the algorithms and collect results from the instrumentation. If people decide they like this package, I will produce a version with all this extra stuff stripped out. I wrote an elaborate test driver, both for bug-testing and for experimenting and gathering performance comparisons with the old code. It runs large numbers of randomly-generated test cases, typically 50000 flat strings, 100000 string-producing operations, heavily biased to concatenations (substring is the only other one), and 100000 text querying operations, roughly equally distributed. Concatenations can be built randomly from previous strings or "linearly", i.e., strictly left-to-right, or strictly right-to-left. The latter two cases are symmetrical, and once the symmetry bugs were gone, they give virtually identical performance. In the linear construction cases, there are no substring operations done. The old and new algorithms can be run side-by-side on pairs of strings that have identical abstract values (but often different internal representations). The results can be mechanically compared this way, for correctness testing. Performance summary: In a number of different situations, the new algorithms give improvements in total time spent in the operations, ranging from 17% to 60%, the latter for linear concatenations, which are much slower than random, using both the old and new algorithms. Tree balance improves dramatically in the linear cases (the random case is well-balanced even by the old algorithms) and recursion depth decreases even more dramatically. The new algorithms allocate 27% (random) to 79% (linear) more heap memory, but a lot is garbage. After collection, the new algorithms retain 20% more (random) to 2% less (linear). Total space runs somewhat larger in the linear case, for both algorithms. The old algorithms toss no garbage. In the special case of linear concatentations with all leaf strings having length one, the new algorithms allocate over twice as much heap storage but retain 63% less. Rodney M. Bates From mika at async.caltech.edu Sat Feb 14 19:10:51 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sat, 14 Feb 2009 10:10:51 -0800 Subject: [M3devel] Question about PM3 Message-ID: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika From rodney.bates at wichita.edu Sat Feb 14 21:30:23 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sat, 14 Feb 2009 14:30:23 -0600 Subject: [M3devel] Question about PM3 In-Reply-To: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Message-ID: <499729DF.3000800@wichita.edu> I have no immediate ideas, but a few questions and thoughts. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. How recent is your m3gdb? For a long time, it has been putting out much better demangled names that what you are getting. You can use the m3gdb in the CM3 distribution and build just it with 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically adapts to PM3-compiled code (unless there is a bug :-). Which code generator did you use, the integrated i386 backend or the gcc-derived one? (If you aren't sure, the latest m3gdb will tell you this and other things about what language implementation it uses with the 'info m3' command, entered after the M3 runtime has initialized.) If there is a code generation problem, it could also go away after just changing backends. However, I'm not sure if there would be trouble without rebuilding all the libraries with the same backend as your application. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. Mika Nystrom wrote: > Dear Modula-3-ers: > > I'm going to ask a question about an old, obsolete piece of software, and > don't expect anybody knows the answer, but would be grateful for any > insight: > > I have a Modula-3 program compiled with one of the last releases of PM3 > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code > that looks like this: > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = > VAR seq : FIXFieldSeq.T; > BEGIN > LOOP > (* update seq *) > seq := i.t.data[i.part]; > > (* first see if we are at end or pointing to an uninteresting part *) > (* seq can be NIL on certain error conditions *) > IF seq # NIL THEN > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN > IF i.part = LAST(Part) THEN (* at bitter end *) > RETURN FALSE > ELSE > INC(i.part); i.nextI := 0 > END > ELSE (* not at end, but in the middle of an interesting Part *) > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO > TRY > IF cur.type() IN i.fields THEN (* nteresting field? *) > f := cur; RETURN TRUE > END > FINALLY > INC(i.nextI) (* in any case, advance to next *) > END > END > END > END > END > END UINext; > > What I am seeing is the following > > Program received signal SIGSEGV, Segmentation fault. > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > 893 INC(i.nextI) (* in any case, advance to next *) > (m3gdb) list > 888 TRY > 889 IF cur.type() IN i.fields THEN (* nteresting field? *) > 890 f := cur; RETURN TRUE > 891 END > 892 FINALLY > 893 INC(i.nextI) (* in any case, advance to next *) > 894 END > 895 END > 896 END > 897 END > > The crash makes no sense, because "i" has already been dereferenced > several times before this, without problem. > > (m3gdb) where > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 > > We're in some sort of "fake" stack frame, and... > > (m3gdb) up > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > 890 f := cur; RETURN TRUE > (m3gdb) print i > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > nextI = 0; END > (m3gdb) > > everything looks OK with i. > > Is it possible there is some sort of problem with TRY .. FINALLY under > PM3? And of course, if so, might it go away with CM3? > > Mika > > From wagner at elegosoft.com Sat Feb 14 23:55:19 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sat, 14 Feb 2009 23:55:19 +0100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4995B9A8.5020403@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> Message-ID: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Quoting "Rodney M. Bates" : > Well, I can work on compilers, debuggers, and functional text packages, but > I can never operate CVS correctly. > > As far as I can tell, I think I got these checkins done in the trunk, rather > than the branch I created for them. I created a tag on the trunk, > "devel_m3core_text_2009_02_13", then created a branch with tag > "devel_m3core_text_newtext_branch". Apparently I got that much right. > > But I am not sure whether the changed files went into the branch. My > CVS book reads as if just a cvs tag -b ..., followed by a cvs commit > will do the commits in the branch, but the commit message doesn't look > like that happened. > > Can anybody help me with: > 1) What really happened? > 2) How should I have done this? You probably forgot to update your workspace to the branch: cvs up -r devel_m3core_text_newtext_branch After that, the branch tag will be `sticky' in your workspace, until you use cvs up -A, which clears it again (and transports you to the trunk). > 3) How can I fix the damage? Well, you can easily revert the changes on the main trunk by checking out the latest version and using -j old-version -j current version, and then commit it. This should put the old-version at the head of the trunk again. Before you do that, you should probably commit everything to the branch, thus you don't need to checkout your version again. I think the version before yours was tagged devel_m3core_d2_4_0. But perhaps it is not necessary to do this? Have tou had feedback from others about the new sources? If nothing breaks and performance gets better, I won't complain ;-) Thanks for all the work, Olaf > PS: I believe that if you use the new files with no additional action, > that you > will get the same behavior as before, except that there will be considerable > constant-time slowdown due to lots of instrumentation and dynamic deciding to > use the original algorithms. But I have not tested this. So probably some improvements are needed before a release. -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Sun Feb 15 00:04:12 2009 From: jay.krell at cornell.edu (Jay) Date: Sat, 14 Feb 2009 23:04:12 +0000 Subject: [M3devel] Question about PM3 In-Reply-To: <499729DF.3000800@wichita.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> <499729DF.3000800@wichita.edu> Message-ID: I agree with Rodney's sentiment to double check whatever you can. If you can rebuild the compiler/runtime, try growing the jmpbuf. Or see what size is being used and write one line of C to see what it should be. (#include #include int main() { printf("%u\n", (unsigned) sizeof(jmpbuf)); }) If you are using user threads, try kernel threads and/or DisableSwitching/EnableSwitching around the crashing code. Read the generated code to try to confirm correctness. If you are optimizing the code, try not. If the loop only runs "a few" times, print out the address as it is dereferenced. See if the failing address is the same as one of the successful ones. Nag me and I'll set up FreeBSD/x86/5.5, send me instructions to build pm3 and send me your code. :) Try any other configuration. pm3 on Linux. cm3 on FreeBSD. cm3 on Linux. etc. - Jay> Date: Sat, 14 Feb 2009 14:30:23 -0600> From: rodney.bates at wichita.edu> To: mika at async.caltech.edu> CC: m3devel at elegosoft.com> Subject: Re: [M3devel] Question about PM3> > I have no immediate ideas, but a few questions and thoughts.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > How recent is your m3gdb? For a long time, it has been putting out> much better demangled names that what you are getting. You can use> the m3gdb in the CM3 distribution and build just it with> 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable> will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically> adapts to PM3-compiled code (unless there is a bug :-).> > Which code generator did you use, the integrated i386 backend or> the gcc-derived one? (If you aren't sure, the latest m3gdb will> tell you this and other things about what language implementation> it uses with the 'info m3' command, entered after the M3 runtime> has initialized.)> > If there is a code generation problem, it could also go away after> just changing backends. However, I'm not sure if there would be> trouble without rebuilding all the libraries with the same backend> as your application.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> > Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > Mika Nystrom wrote:> > Dear Modula-3-ers:> > > > I'm going to ask a question about an old, obsolete piece of software, and> > don't expect anybody knows the answer, but would be grateful for any> > insight:> > > > I have a Modula-3 program compiled with one of the last releases of PM3> > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code> > that looks like this:> > > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN => > VAR seq : FIXFieldSeq.T;> > BEGIN> > LOOP> > (* update seq *)> > seq := i.t.data[i.part];> > > > (* first see if we are at end or pointing to an uninteresting part *)> > (* seq can be NIL on certain error conditions *)> > IF seq # NIL THEN> > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN> > IF i.part = LAST(Part) THEN (* at bitter end *)> > RETURN FALSE> > ELSE> > INC(i.part); i.nextI := 0> > END> > ELSE (* not at end, but in the middle of an interesting Part *)> > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO> > TRY> > IF cur.type() IN i.fields THEN (* nteresting field? *)> > f := cur; RETURN TRUE> > END> > FINALLY> > INC(i.nextI) (* in any case, advance to next *)> > END> > END> > END> > END> > END> > END UINext;> > > > What I am seeing is the following> > > > Program received signal SIGSEGV, Segmentation fault.> > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > 893 INC(i.nextI) (* in any case, advance to next *)> > (m3gdb) list> > 888 TRY> > 889 IF cur.type() IN i.fields THEN (* nteresting field? *)> > 890 f := cur; RETURN TRUE> > 891 END> > 892 FINALLY> > 893 INC(i.nextI) (* in any case, advance to next *)> > 894 END> > 895 END> > 896 END> > 897 END> > > > The crash makes no sense, because "i" has already been dereferenced> > several times before this, without problem.> > > > (m3gdb) where> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846> > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411> > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321> > > > We're in some sort of "fake" stack frame, and...> > > > (m3gdb) up> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > 890 f := cur; RETURN TRUE> > (m3gdb) print i> > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > > nextI = 0; END> > (m3gdb) > > > > everything looks OK with i.> > > > Is it possible there is some sort of problem with TRY .. FINALLY under> > PM3? And of course, if so, might it go away with CM3?> > > > Mika> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sun Feb 15 06:27:38 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 14 Feb 2009 21:27:38 -0800 (PST) Subject: [M3devel] Question about PM3 Message-ID: <954132.49377.qm@web24715.mail.ird.yahoo.com> Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible that the assignment statement in line 890 is failing and because of the TRY-FINALLY you don't get a Runtime Error (which would be the ideal behaviour if the MODULE is safe and correspondent IMPORT Modules aren't? ill behaved ). 890 f := cur; RETURN TRUEYou could make a sanity check before that line with ?ISTYPE(cur, FIXField.T) (*is cur a member of f's type, FIXField.T *)? Please feel free to ask further questions. Hope this helps. Thanks. --- El s?b, 14/2/09, Mika Nystrom wrote: De: Mika Nystrom Asunto: [M3devel] Question about PM3 Para: m3devel at elegosoft.com Fecha: s?bado, 14 febrero, 2009 1:10 Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Sun Feb 15 12:51:49 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sun, 15 Feb 2009 12:51:49 +0100 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: <20090215125149.rgbaxncveok4okw4@mail.elegosoft.com> Quoting Martin Bishop : > A while back I said it would be nice if modula3.org could get it's links > updated, as quite a few of them were dead. Well I went through the > links on the front page of modula3.org (as well as the separate "Links" > page) and updated them. > > I only removed one link, and replaced all the dead ones with either > mirrors or just better links. > > (NOTE: They look bad because they aren't using the CSS, but I'm just > putting these up so someone (Olaf?) can save the source and push to the > modula3.org CVS.) > > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html > (Main page) > > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) I've downloaded the pages, but I'm not able to get a meaningful diff listing, as there are so many arbitrary changes, even ignoring all blanks, newlines, and case, that I don't have the time to check them. I don't want to put them up without testing, as images seem to be broken, for example, and changes in the case of tags don't improve maintainability. There also seem to be some strange changes in the location of pages, like s/images/Modula-3%20Resource%20Page_files/, which simply don't look right. Couldn't you send a minimal diff with just the substitutions needed, without any unnecessary changes? Or simply a list like an sed script with s/old link/new link/? That would make it considerably easier to integrate them for me. Don't misunderstand me, I think it's great that you've checked and updated all the links, and would like to put the new information on the server, but I cannot spend too much time on it. As a general rule, changes in layout and style which don't affect the funtionality of a page should be separated from content changes, which need to be checked in a different way. Thanks in advance for your understanding and help, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 16 00:31:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 16 Feb 2009 10:31:54 +1100 Subject: [M3devel] Tinderbox failures Message-ID: Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 02:42:25 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 01:42:25 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 03:15:02 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 02:15:02 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: I think it depends on what cm3 you start with. I noticed the Tinderbox has "last-ok" runs and "last-release" runs. last-ok appears to be working. last-release has the error. Updating my current cygwin build seemed to work. Starting with 5.4 (which is what last release appears to be) on Linux/x86 gave me a cm3 that just seg faults. I'll try to dig more. - Jay From: jay.krell at cornell.eduTo: hosking at cs.purdue.edu; m3devel at elegosoft.com; m3commit at elegosoft.comSubject: RE: [M3devel] Tinderbox failuresDate: Mon, 16 Feb 2009 01:42:25 +0000 Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Mon Feb 16 04:16:27 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sun, 15 Feb 2009 21:16:27 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Message-ID: <4998DA8B.7000605@wichita.edu> I managed to get the trunk back to the original code, as I intended. The Tinderbox failure is undoubtedly a bug in the new stuff. But it leaves me with more CVS questions, see below. Olaf Wagner wrote: > Quoting "Rodney M. Bates" : > >> Well, I can work on compilers, debuggers, and functional text >> packages, but >> I can never operate CVS correctly. >> >> As far as I can tell, I think I got these checkins done in the trunk, >> rather >> than the branch I created for them. I created a tag on the trunk, >> "devel_m3core_text_2009_02_13", then created a branch with tag >> "devel_m3core_text_newtext_branch". Apparently I got that much right. >> >> But I am not sure whether the changed files went into the branch. My >> CVS book reads as if just a cvs tag -b ..., followed by a cvs commit >> will do the commits in the branch, but the commit message doesn't look >> like that happened. >> >> Can anybody help me with: >> 1) What really happened? >> 2) How should I have done this? > > You probably forgot to update your workspace to the branch: > > cvs up -r devel_m3core_text_newtext_branch This command is in the recipe in my book, but my book assumes you make a branch first, get a copy of the trunk code, edit that, then commit. I had done the coding first, naively thinking I could just create a branch when ready to commit it. So I deliberately left this step out, thinking (rightly, as it turned out) that it would overlay my work with the unmodified code. So today, I made safe copies in other directories of both versions and started trying to unravel things. Sure enough, the update -r promptly replaced my new code with the old. I used a different machine to do updates, and quickly found I now had the new code in the trunk and the old code in the branch. And of course, update -A first overlaid the old code I had now put in my text directory with what is in the repository trunk (the modified code), before clearing the sticky tag. By going through procedures doing CVS commands, interspersed with copying versions of the code from my backup directories to the text directory, I managed to get the trunk straightened out, (I think.) But it was convoluted. To do any of this reasonably, I need a command that changes the sticky tag CVS considers me to be working on (like the -r and -A options of update), but without the undesired side effect of also overlaying my local directory with what was in old tagged version, before changing the sticky tag. Is there such a command? I will worry about the getting the new code into the branch tomorrow. > > After that, the branch tag will be `sticky' in your workspace, until > you use cvs up -A, which clears it again (and transports you to the trunk). > >> 3) How can I fix the damage? > > Well, you can easily revert the changes on the main trunk by checking > out the latest version and using -j old-version -j current version, > and then commit it. This should put the old-version at the head of > the trunk again. Before you do that, you should probably commit everything > to the branch, thus you don't need to checkout your version again. > > I think the version before yours was tagged devel_m3core_d2_4_0. > > But perhaps it is not necessary to do this? Have tou had feedback > from others about the new sources? If nothing breaks and performance > gets better, I won't complain ;-) > > Thanks for all the work, > > Olaf > >> PS: I believe that if you use the new files with no additional action, >> that you >> will get the same behavior as before, except that there will be >> considerable >> constant-time slowdown due to lots of instrumentation and dynamic >> deciding to >> use the original algorithms. But I have not tested this. > > So probably some improvements are needed before a release. From dabenavidesd at yahoo.es Mon Feb 16 05:25:53 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 15 Feb 2009 20:25:53 -0800 (PST) Subject: [M3devel] Question about PM3 In-Reply-To: <954132.49377.qm@web24715.mail.ird.yahoo.com> Message-ID: <793526.97016.qm@web24715.mail.ird.yahoo.com> Hi all, Better more accurately to the language definition check before the mentioned line 890: ISTYPE(cur, FIXField.T) OR ISTYPE(f, ProtocolFields.T) (*is cur a member of f's type, FIXField.T or is f? a member of cur's type, ProtocolFields.T, that is ProtocolFields.T <: FIXField? OR FIXField.T <: ProtocolFields.T *)? Thanks and sorry about the forgot detail. --- El dom, 15/2/09, Daniel Alejandro Benavides D. escribi?: De: Daniel Alejandro Benavides D. Asunto: Re: [M3devel] Question about PM3 Para: "Mika Nystrom" CC: m3devel at elegosoft.com Fecha: domingo, 15 febrero, 2009 12:27 Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible that the assignment statement in line 890 is failing and because of the TRY-FINALLY you don't get a Runtime Error (which would be the ideal behaviour if the MODULE is safe and correspondent IMPORT Modules aren't? ill behaved ). 890 f := cur; RETURN TRUEYou could make a sanity check before that line with ?ISTYPE(cur, FIXField.T) (*is cur a member of f's type, FIXField.T *)? Please feel free to ask further questions. Hope this helps. Thanks. --- El s?b, 14/2/09, Mika Nystrom wrote: De: Mika Nystrom Asunto: [M3devel] Question about PM3 Para: m3devel at elegosoft.com Fecha: s?bado, 14 febrero, 2009 1:10 Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Mon Feb 16 06:47:03 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 16 Feb 2009 16:47:03 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4998DA8B.7000605@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> Message-ID: <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> Does the trunk still contain your bug-fixes? On 16 Feb 2009, at 14:16, Rodney M. Bates wrote: > I managed to get the trunk back to the original code, as I intended. > The Tinderbox failure is undoubtedly a bug in the new stuff. But it > leaves me with more CVS questions, see below. > > Olaf Wagner wrote: >> Quoting "Rodney M. Bates" : >>> Well, I can work on compilers, debuggers, and functional text >>> packages, but >>> I can never operate CVS correctly. >>> >>> As far as I can tell, I think I got these checkins done in the >>> trunk, rather >>> than the branch I created for them. I created a tag on the trunk, >>> "devel_m3core_text_2009_02_13", then created a branch with tag >>> "devel_m3core_text_newtext_branch". Apparently I got that much >>> right. >>> >>> But I am not sure whether the changed files went into the branch. >>> My >>> CVS book reads as if just a cvs tag -b ..., followed by a cvs commit >>> will do the commits in the branch, but the commit message doesn't >>> look >>> like that happened. >>> >>> Can anybody help me with: >>> 1) What really happened? >>> 2) How should I have done this? >> You probably forgot to update your workspace to the branch: >> cvs up -r devel_m3core_text_newtext_branch > > This command is in the recipe in my book, but my book assumes you make > a branch first, get a copy of the trunk code, edit that, then commit. > I had done the coding first, naively thinking I could just create a > branch > when ready to commit it. So I deliberately left this step out, > thinking > (rightly, as it turned out) that it would overlay my work with the > unmodified code. > > So today, I made safe copies in other directories of both versions and > started trying to unravel things. Sure enough, the update -r > promptly > replaced my new code with the old. I used a different machine to do > updates, and quickly found I now had the new code in the trunk and the > old code in the branch. > > And of course, update -A first overlaid the old code I had now put in > my text directory with what is in the repository trunk (the modified > code), before clearing the sticky tag. > > By going through procedures doing CVS commands, interspersed with > copying > versions of the code from my backup directories to the text > directory, I > managed to get the trunk straightened out, (I think.) > > But it was convoluted. To do any of this reasonably, I need a command > that changes the sticky tag CVS considers me to be working on (like > the -r and > -A options of update), but without the undesired side effect of also > overlaying my local directory with what was in old tagged version, > before changing the sticky tag. Is there such a command? > > I will worry about the getting the new code into the branch tomorrow. > >> After that, the branch tag will be `sticky' in your workspace, until >> you use cvs up -A, which clears it again (and transports you to the >> trunk). >>> 3) How can I fix the damage? >> Well, you can easily revert the changes on the main trunk by checking >> out the latest version and using -j old-version -j current version, >> and then commit it. This should put the old-version at the head of >> the trunk again. Before you do that, you should probably commit >> everything >> to the branch, thus you don't need to checkout your version again. >> I think the version before yours was tagged devel_m3core_d2_4_0. >> But perhaps it is not necessary to do this? Have tou had feedback >> from others about the new sources? If nothing breaks and performance >> gets better, I won't complain ;-) >> Thanks for all the work, >> Olaf >>> PS: I believe that if you use the new files with no additional >>> action, >>> that you >>> will get the same behavior as before, except that there will be >>> considerable >>> constant-time slowdown due to lots of instrumentation and dynamic >>> deciding to >>> use the original algorithms. But I have not tested this. >> So probably some improvements are needed before a release. From wagner at elegosoft.com Mon Feb 16 11:36:16 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 16 Feb 2009 11:36:16 +0100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4998DA8B.7000605@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> Message-ID: <20090216113616.blncsdl9q88kwkcg@mail.elegosoft.com> Quoting "Rodney M. Bates" : > I managed to get the trunk back to the original code, as I intended. > The Tinderbox failure is undoubtedly a bug in the new stuff. But it > leaves me with more CVS questions, see below. [...] >> cvs up -r devel_m3core_text_newtext_branch > > This command is in the recipe in my book, but my book assumes you make > a branch first, get a copy of the trunk code, edit that, then commit. > I had done the coding first, naively thinking I could just create a branch > when ready to commit it. So I deliberately left this step out, thinking > (rightly, as it turned out) that it would overlay my work with the > unmodified code. > > So today, I made safe copies in other directories of both versions and > started trying to unravel things. Sure enough, the update -r promptly > replaced my new code with the old. I used a different machine to do > updates, and quickly found I now had the new code in the trunk and the > old code in the branch. > > And of course, update -A first overlaid the old code I had now put in > my text directory with what is in the repository trunk (the modified > code), before clearing the sticky tag. > > By going through procedures doing CVS commands, interspersed with copying > versions of the code from my backup directories to the text directory, I > managed to get the trunk straightened out, (I think.) > > But it was convoluted. To do any of this reasonably, I need a command > that changes the sticky tag CVS considers me to be working on (like > the -r and > -A options of update), but without the undesired side effect of also > overlaying my local directory with what was in old tagged version, > before changing the sticky tag. Is there such a command? > > I will worry about the getting the new code into the branch tomorrow. You should have switched your workspace to the branch before changing the code or before the first commit. Then it would have been straight forward. The general way to fix things like this is a three-point merge. You use two -j options to specify the diff to be applied to your workspace and then commit it (after validating the consistency, of course). So yo get the changes from trunk to branch you (1) update your workspace to the branch top (cvs up -r devel_m3core_text_newtext_branch) (2) merge from the branch point to the tag containing you changes on the trunk, for example by cvs up -j devel_m3core_text_newtext_branch_bp \ -j erroneously_committed_version_on_trunk (I don't know what tag applies here offhand) AFAIK there is no command to change the workspace sticky tag without changing the sources. Regards, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From rodney.bates at wichita.edu Mon Feb 16 18:57:04 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Mon, 16 Feb 2009 11:57:04 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> Message-ID: <4999A8F0.50801@wichita.edu> No, the trunk right now is as it was before I started working on it, which, I believe, has been unchanged for years. I guess it's confusing, as my way of putting it back probably gives recent dates and new version numbers on everything. I guess I could backport the bug fixes into the trunk. Tony Hosking wrote: > Does the trunk still contain your bug-fixes? > From jay.krell at cornell.edu Tue Feb 17 01:00:01 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 00:00:01 +0000 Subject: [M3devel] suggestion for "atomic ops" In-Reply-To: References: Message-ID: [replaced m3commit with m3devel..] Let a code generator advertise that it doesn't support them. And if so, instead generate a call to some set of functions. I realize this fallback could be implemented in the code generators themselves. Windows has various "interlocked" functions that should make this easy. Thanks, - Jay From hosking at cs.purdue.edu Tue Feb 17 01:24:04 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 17 Feb 2009 11:24:04 +1100 Subject: [M3devel] suggestion for "atomic ops" In-Reply-To: References: Message-ID: <901A0F1B-84F1-4182-BD14-2BAFF3D848B6@cs.purdue.edu> With the gcc-based backend we get exactly that behavior. On 17 Feb 2009, at 11:00, Jay wrote: > > [replaced m3commit with m3devel..] > > Let a code generator advertise that it doesn't support them. > And if so, instead generate a call to some set of functions. > I realize this fallback could be implemented in the code generators > themselves. > Windows has various "interlocked" functions that should make this > easy. > > Thanks, > - Jay From hosking at cs.purdue.edu Tue Feb 17 03:57:17 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 17 Feb 2009 13:57:17 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4999A8F0.50801@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> Message-ID: <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Yes, it would be good to get the bugfixes in separately from your current new TEXT development branch. On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: > No, the trunk right now is as it was before I started working on it, > which, I believe, has been unchanged for years. I guess it's > confusing, > as my way of putting it back probably gives recent dates and new > version > numbers on everything. > > I guess I could backport the bug fixes into the trunk. > > Tony Hosking wrote: >> Does the trunk still contain your bug-fixes? From jay.krell at cornell.edu Tue Feb 17 04:33:46 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 03:33:46 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Message-ID: Rodney, "it seems obvious" the problem was related to: PROCEDURE Bar(start: INTEGER); PROCEDURE Foo(start := LAST(INTEGER)) = BEGIN Bar(start + 1); END Foo; LAST(INTEGER) + 1 => error Though I grant, that is about all I looked at, couldn't be much shallower of an analysis. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: rodney.bates at wichita.edu > Date: Tue, 17 Feb 2009 13:57:17 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Yes, it would be good to get the bugfixes in separately from your > current new TEXT development branch. > > On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: > >> No, the trunk right now is as it was before I started working on it, >> which, I believe, has been unchanged for years. I guess it's >> confusing, >> as my way of putting it back probably gives recent dates and new >> version >> numbers on everything. >> >> I guess I could backport the bug fixes into the trunk. >> >> Tony Hosking wrote: >>> Does the trunk still contain your bug-fixes? > From wagner at elegosoft.com Tue Feb 17 08:01:35 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Tue, 17 Feb 2009 08:01:35 +0100 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: <90251234839259@webmail63.yandex.ru> References: <90251234839259@webmail63.yandex.ru> Message-ID: <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Quoting ??????? ????? : > Hello! At first, excuse me, but my english is very-very bad! > > 1. I try to build CM3 on Windows XP with MinGW toolset. But when I > build m3core and libm3, there are many errors appears. I use > cm3-min-WIN32-NT386GNU-d5.5.1 and > cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how > to build m3core and libm3? All other libraries and packages I'll > build manually. This may be best answered on the m3devel list, but you'll probably have to provide some more details as to the many errors. There should be a binary installation archive for CM3 based on Cygwin in the upload area of www.opencm3.net. > 2. Tell me please, may I put binary package of CM3 for Win32 on my > own site for public downloads? That should be no problem. You can also upload new packages you want to publish to www.opencm3.net. Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Tue Feb 17 08:20:13 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 07:20:13 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: NT386GNU corresponds to cygwin. It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. NT386MINGNU corresponds to mingwin. It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. NT386MINGNU was working, at least for command line apps. I can spin another build, make sure it still works, and maybe get around to fixing gui apps. (I think I'll just put in a small workaround for the gui issue.) In the meantime, can try cygwin? Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? - Jay ---------------------------------------- > Date: Tue, 17 Feb 2009 08:01:35 +0100 > From: wagner at elegosoft.com > To: rv82 at ya.ru > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > Quoting ??????? ????? : > >> Hello! At first, excuse me, but my english is very-very bad! >> >> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I >> build m3core and libm3, there are many errors appears. I use >> cm3-min-WIN32-NT386GNU-d5.5.1 and >> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how >> to build m3core and libm3? All other libraries and packages I'll >> build manually. > > This may be best answered on the m3devel list, but you'll probably have > to provide some more details as to the many errors. > There should be a binary installation archive for CM3 based on > Cygwin in the upload area of www.opencm3.net. > >> 2. Tell me please, may I put binary package of CM3 for Win32 on my >> own site for public downloads? > > That should be no problem. You can also upload new packages you > want to publish to www.opencm3.net. > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > From jay.krell at cornell.edu Tue Feb 17 08:35:43 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 17 Feb 2009 07:35:43 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: (ps: more complete list: NT386GNU: gcc backend gcc for C compiler gcc/GNU ld for linker cygwin C runtime X windows pthreads forward slashes on paths debuggable with gdb ("stabs" debug format) or printf.. NT386MINGNU gcc backend gcc for C compiler gcc/GNU ld for linker MS C runtime (provided by mingw's gcc) I think debuggable with gdb. ("stabs" debug format) or printf.. Win32 windows Win32 threads backwards slashes on paths, or forward NT386: integrated backend -- very fast no 64 bit LONGINT Visual C++ compiler/linker/runtime Win32 thread/windows backwards slashes on paths, or forward debugable with Visual Studio/cdb/ntsd/windbg ("CodeView" debug format), not gdb or printf.. ) The various factors are mixable/matchable to SOME extent, but they aren't tested, they might be confusing, and they don't all work necessarily. These are "friendly" names to encompass a set of underlying factors. I think I386_NT or I386_MSWIN, I386_CYGWIN, I386_MINGWIN might be better names. (I would avoid saying "WIN32" anywhere, due to Windows also running on IA64 and AMD64). - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: wagner at elegosoft.com; rv82 at ya.ru > Date: Tue, 17 Feb 2009 07:20:13 +0000 > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > > NT386GNU corresponds to cygwin. > It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. > > > NT386MINGNU corresponds to mingwin. > It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. > > > NT386MINGNU was working, at least for command line apps. > > I can spin another build, make sure it still works, and maybe get around to fixing gui apps. > (I think I'll just put in a small workaround for the gui issue.) > > > In the meantime, can try cygwin? > > > Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? > > > - Jay > > > > ---------------------------------------- >> Date: Tue, 17 Feb 2009 08:01:35 +0100 >> From: wagner at elegosoft.com >> To: rv82 at ya.ru >> CC: m3devel at elegosoft.com; m3-support at elego.de >> Subject: Re: [M3devel] CM3 on Win32 (MinGW) >> >> Quoting ??????? ????? : >> >>> Hello! At first, excuse me, but my english is very-very bad! >>> >>> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I >>> build m3core and libm3, there are many errors appears. I use >>> cm3-min-WIN32-NT386GNU-d5.5.1 and >>> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how >>> to build m3core and libm3? All other libraries and packages I'll >>> build manually. >> >> This may be best answered on the m3devel list, but you'll probably have >> to provide some more details as to the many errors. >> There should be a binary installation archive for CM3 based on >> Cygwin in the upload area of www.opencm3.net. >> >>> 2. Tell me please, may I put binary package of CM3 for Win32 on my >>> own site for public downloads? >> >> That should be no problem. You can also upload new packages you >> want to publish to www.opencm3.net. >> >> Olaf >> -- >> Olaf Wagner -- elego Software Solutions GmbH >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 >> From jay.krell at cornell.edu Wed Feb 18 12:27:23 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 11:27:23 +0000 Subject: [M3devel] FW: winRes.tmpl/mingw/rc/windres/etc. In-Reply-To: <20090218105139.4860F10D4261@birch.elegosoft.com> References: <20090218105139.4860F10D4261@birch.elegosoft.com> Message-ID: I think this code should be moved into the config files. ? All non-Windows config files would just say: readonly proc WindowsResource (file) isendand then NT386.common would have the current content of winRes.tmpl. Thoughts? More so, cm3.exe should just implement proc WindowsResource (file) isend without readonly, and then NT386.common can replace it. The others can leave it alone. Thoughts? I'm not really sure what should be "core" vs. what should be "an extension". It is nice to have such an extensible system, but it can also be bad. Besides that, Windows has a nice feature called "version resources". If nothing else, every .dll/.exe should have one. cm3 should give everyone some default. imho. - Jay> Date: Wed, 18 Feb 2009 11:51:39 +0000> To: m3commit at elegosoft.com> From: jkrell at elego.de> Subject: [M3commit] CVS Update: cm3> > CVSROOT: /usr/cvs> Changes by: jkrell at birch. 09/02/18 11:51:39> > Modified files:> cm3/m3-sys/windowsResources/src/: winRes.tmpl > > Log message:> adapt to MinGW which has windres instead of rc with different command line usage; detect MinGW by checking if backend mode is integrated backend or not, not great..it should really be informed by a variable in the toplevel configuration -- CONFIG_HAS_RC and CONFIG_HAS_WINDRES?> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 18 12:40:54 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 11:40:54 +0000 Subject: [M3devel] FW: winRes.tmpl/mingw/rc/windres/etc. In-Reply-To: <20090218105139.4860F10D4261@birch.elegosoft.com> References: <20090218105139.4860F10D4261@birch.elegosoft.com> Message-ID: [truncated..] From: jay.krell at cornell.eduTo: m3devel at elegosoft.comSubject: FW: winRes.tmpl/mingw/rc/windres/etc.Date: Wed, 18 Feb 2009 11:27:23 +0000 I think this code should be moved into the config files. ?All non-Windows config files would just say: readonly proc WindowsResource (file) isendand then NT386.common would have the current content of winRes.tmpl. Thoughts? More so, cm3.exe should just implementproc WindowsResource (file) isendwithout readonly, and then NT386.common can replace it.The others can leave it alone. Thoughts? I'm not really sure what should be "core" vs. what should be "an extension".It is nice to have such an extensible system, but it can also be bad. Besides that, Windows has a nice feature called "version resources".If nothing else, every .dll/.exe should have one.cm3 should give everyone some default.imho. - Jay> Date: Wed, 18 Feb 2009 11:51:39 +0000> To: m3commit at elegosoft.com> From: jkrell at elego.de> Subject: [M3commit] CVS Update: cm3> > CVSROOT: /usr/cvs> Changes by: jkrell at birch. 09/02/18 11:51:39> > Modified files:> cm3/m3-sys/windowsResources/src/: winRes.tmpl > > Log message:> adapt to MinGW which has windres instead of rc with different command line usage; detect MinGW by checking if backend mode is integrated backend or not, not great..it should really be informed by a variable in the toplevel configuration -- CONFIG_HAS_RC and CONFIG_HAS_WINDRES?> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 18 18:58:04 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 18 Feb 2009 17:58:04 +0000 Subject: [M3devel] CM3 on Win32 (MinGW) In-Reply-To: References: <90251234839259@webmail63.yandex.ru> <20090217080135.ijf8dcon7ockw0sk@mail.elegosoft.com> Message-ID: Please try: http://modula3.elegosoft.com/cm3/uploaded-archives/cm3-min-NT386MINGNU-d5.7.1.tar.gz or: http://modula3.elegosoft.com/cm3/uploaded-archives/cm3-std-NT386MINGNU-d5.7.1.tar.gz I know many of the gui apps crash pretty early, in ways that don't look gui-app-specific. - Jay > From: jay.krell at cornell.edu > To: wagner at elegosoft.com; rv82 at ya.ru > CC: m3devel at elegosoft.com; m3-support at elego.de > Subject: RE: [M3devel] CM3 on Win32 (MinGW) > Date: Tue, 17 Feb 2009 07:35:43 +0000 > > > (ps: more complete list: > > > NT386GNU: > gcc backend > gcc for C compiler > gcc/GNU ld for linker > cygwin C runtime > X windows > pthreads > forward slashes on paths > debuggable with gdb ("stabs" debug format) > or printf.. > > > NT386MINGNU > gcc backend > gcc for C compiler > gcc/GNU ld for linker > MS C runtime (provided by mingw's gcc) > I think debuggable with gdb. ("stabs" debug format) > or printf.. > Win32 windows > Win32 threads > backwards slashes on paths, or forward > > > NT386: > integrated backend -- very fast > no 64 bit LONGINT > Visual C++ compiler/linker/runtime > Win32 thread/windows > backwards slashes on paths, or forward > debugable with Visual Studio/cdb/ntsd/windbg ("CodeView" debug format), not gdb > or printf.. > ) > > > The various factors are mixable/matchable to SOME extent, but they aren't tested, they might be confusing, and they don't all work necessarily. > These are "friendly" names to encompass a set of underlying factors. > I think I386_NT or I386_MSWIN, I386_CYGWIN, I386_MINGWIN might be better names. > (I would avoid saying "WIN32" anywhere, due to Windows also running on IA64 and AMD64). > > > - Jay > > > > ---------------------------------------- > > From: jay.krell at cornell.edu > > To: wagner at elegosoft.com; rv82 at ya.ru > > Date: Tue, 17 Feb 2009 07:20:13 +0000 > > CC: m3devel at elegosoft.com; m3-support at elego.de > > Subject: Re: [M3devel] CM3 on Win32 (MinGW) > > > > > > NT386GNU corresponds to cygwin. > > It uses the gcc backend (has a 64 bit integer), and Cygwin runtime, pthreads, and forward slashes on all paths. > > > > > > NT386MINGNU corresponds to mingwin. > > It uses the gcc backend (has a 64 bit integer), MS runtime, Win32 threads, backwards slashes on all paths, but is ok with forward slashes, but doesn't do any "fancy" path conversions -- c:/windows is ok for example. > > > > > > NT386MINGNU was working, at least for command line apps. > > > > I can spin another build, make sure it still works, and maybe get around to fixing gui apps. > > (I think I'll just put in a small workaround for the gui issue.) > > > > > > In the meantime, can try cygwin? > > > > > > Anyone ok if I rename these I386_CYGWIN and I386_MINGW or I386_MINGWIN? > > > > > > - Jay > > > > > > > > ---------------------------------------- > >> Date: Tue, 17 Feb 2009 08:01:35 +0100 > >> From: wagner at elegosoft.com > >> To: rv82 at ya.ru > >> CC: m3devel at elegosoft.com; m3-support at elego.de > >> Subject: Re: [M3devel] CM3 on Win32 (MinGW) > >> > >> Quoting ??????? ????? : > >> > >>> Hello! At first, excuse me, but my english is very-very bad! > >>> > >>> 1. I try to build CM3 on Windows XP with MinGW toolset. But when I > >>> build m3core and libm3, there are many errors appears. I use > >>> cm3-min-WIN32-NT386GNU-d5.5.1 and > >>> cm3-src-all-d5.7.1-2009-02-09-15-06-52.tgz. May you recomend me, how > >>> to build m3core and libm3? All other libraries and packages I'll > >>> build manually. > >> > >> This may be best answered on the m3devel list, but you'll probably have > >> to provide some more details as to the many errors. > >> There should be a binary installation archive for CM3 based on > >> Cygwin in the upload area of www.opencm3.net. > >> > >>> 2. Tell me please, may I put binary package of CM3 for Win32 on my > >>> own site for public downloads? > >> > >> That should be no problem. You can also upload new packages you > >> want to publish to www.opencm3.net. > >> > >> Olaf > >> -- > >> Olaf Wagner -- elego Software Solutions GmbH > >> Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > >> phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > >> http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > >> Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Thu Feb 19 03:02:55 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Wed, 18 Feb 2009 20:02:55 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> <4998DA8B.7000605@wichita.edu> <1EAC1098-B8FE-4EBF-88E3-87580727BA8B@cs.purdue.edu> <4999A8F0.50801@wichita.edu> <0FA71CB5-1F46-4E06-90AD-55E327D2409A@cs.purdue.edu> Message-ID: <499CBDCF.6080001@wichita.edu> Yes. This is a wonderful example of a half bugfix. Original code was String8.FindCharR (i.start, MIN (i.length, start), c); start is off by one here and needs to be increased by one, so I changed it to String8.FindCharR (i.start, MIN (i.length, start+1), c); This is correct for every case except start=LAST(INTEGER), (which is likely to happen because it is the defaulted value of parameter start). Even so, I thought the MIN function should take care of this, but the intermediate value of start+1 overflows silently, wraps around to FIRST(INTEGER), and becomes the minimum. So now its: String8.FindCharR (i.start, MIN (i.length-1, start)+1, c); which can have the same problem on the low end, i.e., it can go temporarily negative by one, but that is OK because the intermediate arithmetic is done in INTEGER, and the final result will always end up at least zero, within the needed range of CARDINAL. This would make a good textbook example. Jay wrote: > Rodney, "it seems obvious" the problem was related to: > > PROCEDURE Bar(start: INTEGER); > > PROCEDURE Foo(start := LAST(INTEGER)) = > BEGIN > Bar(start + 1); > END Foo; > > LAST(INTEGER) + 1 => error > Though I grant, that is about all I looked at, > couldn't be much shallower of an analysis. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: rodney.bates at wichita.edu >> Date: Tue, 17 Feb 2009 13:57:17 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Yes, it would be good to get the bugfixes in separately from your >> current new TEXT development branch. >> >> On 17 Feb 2009, at 04:57, Rodney M. Bates wrote: >> >>> No, the trunk right now is as it was before I started working on it, >>> which, I believe, has been unchanged for years. I guess it's >>> confusing, >>> as my way of putting it back probably gives recent dates and new >>> version >>> numbers on everything. >>> >>> I guess I could backport the bug fixes into the trunk. >>> >>> Tony Hosking wrote: >>>> Does the trunk still contain your bug-fixes? >> From rodney.bates at wichita.edu Sat Feb 21 00:36:07 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 20 Feb 2009 17:36:07 -0600 Subject: [M3devel] Assert failure in ThreadPThread.m3 Message-ID: <499F3E67.9080605@wichita.edu> I got an assertion failure in ThreadPThread.m3. Here is a transcript. Below that is a more helpful backtrace I got by manually stopping it as quickly as I could after the assertion failure messages. I think the second backtrace is not on the relevant thread however, because commenting out the Thread.Pause does not make the failure go away, just makes it harder to catch. Note: I have a lot of weakref cleanups registered. Executing RTCollector.Disable ( ) early in the program and leaving it disabled makes the problem go away. --------------------------------------------------------------------------------------------------------------------- rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/newtext/src$ m3gdb test GNU gdb plus Modula-3 6.4 Copyright 2005 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (m3gdb) run -nos Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/newtext/src/test -nos Signal Stop Print Pass to program Description SIG64 No No Yes Real-time event 64 [Thread debugging using libthread_db enabled] [New LWP 32595] Estimating overhead of timing. Generating initial leaf strings. Generating initial leaf strings. 0\ Garbage collection disabled for better timing. 62[New Thread -1220703344 (LWP 32598)] [New Thread -1220429104 (LWP 32595)] ....+....1....+....2....+....3....+....4....+....| 5000....+....6....+....7....+....8....+....9....+....| 10000....+....1....+....2....+....3....+....4....+....| 15000....+....6....+....7....+....8....+....9....+....| 20000....+....1....+....2....+....3....+....4....+....| 25000....+....6....+....7....+....8....+....9....+....| 30000....+....1....+....2....+....3....+....4....+....| 35000....+....6....+....7....+....8....+....9....+....| 40000....+....1....+....2....+....3....+....4....+....| 45000....+....6....+....7....+....8....+....9....+....| 50000 Garbage collection enabled and triggered ... *** *** runtime error: *** <*ASSERT*> failed. *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 *** Garbage collection completed. Program received signal SIGINT, Interrupt. [Switching to Thread -1220429104 (LWP 32595)] 0xb7f7d410 in __kernel_vsyscall () (m3gdb) bt #0 0xb7f7d410 in __kernel_vsyscall () #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/libpthread.so.0 ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI encountered. A problem internal to GDB has been detected, further debugging may prove unreliable. Quit this debugging session? (y or n) y ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI encountered. A problem internal to GDB has been detected, further debugging may prove unreliable. Create a core file of GDB? (y or n) y Aborted (core dumped) --------------------------------------------------------------------------------------------------------------------- Garbage collection enabled and triggered ... *** *** runtime error: *** <*ASSERT*> failed. *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 *** Program received signal SIGINT, Interrupt. [Switching to Thread -1220732208 (LWP 32623)] 0xb7f33410 in __kernel_vsyscall () (m3gdb) bt #0 0xb7f33410 in __kernel_vsyscall () #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/libpthread.so.0 #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 Can't find child block 1, at level 1, of parent procedure "Test__GetParams", for nested procedure "Test__GetParams__1__1__NumArg.778" #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol table. ) at ../src/Test.m3:1628 #6 0x0805b764 in Work () at ../src/Test.m3:2536 #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol table. ) at ../src/Test.m3:2658 #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in symbol table. ) at ../src/runtime/common/RTLinker.m3:399 #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol table. ) at ../src/runtime/common/RTLinker.m3:113 #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol table. ) at ../src/runtime/common/RTLinker.m3:122 #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at _m3main.mc:4 #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #13 0x08049ed1 in _start () (m3gdb) frame 4 #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 1354 ; Thread . Pause ( 2.0D0 ) Current language: auto; currently Modula-3 (m3gdb) down #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 668 XPause(self, n, alertable := FALSE); (m3gdb) down #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type code 44 in symbol table. ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 651 WITH r = Utime.nanosleep(amount, remaining) DO (m3gdb) down #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/libpthread.so.0 (m3gdb) down #0 0xb7f33410 in __kernel_vsyscall () (m3gdb) --------------------------------------------------------------------------------------------------------------------- From hosking at cs.purdue.edu Sat Feb 21 01:52:44 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 21 Feb 2009 11:52:44 +1100 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: <499F3E67.9080605@wichita.edu> References: <499F3E67.9080605@wichita.edu> Message-ID: <234E7866-DDEC-478D-A620-EF697873AF1A@cs.purdue.edu> Looks like a spurious wakeup. Let me look in to it. Perhaps broken by my recent changes. On 21 Feb 2009, at 10:36, Rodney M. Bates wrote: > I got an assertion failure in ThreadPThread.m3. > > Here is a transcript. Below that is a more helpful backtrace I got by > manually stopping it as quickly as I could after the assertion failure > messages. I think the second backtrace is not on the relevant thread > however, because commenting out the Thread.Pause does not make the > failure > go away, just makes it harder to catch. > > Note: I have a lot of weakref cleanups registered. Executing > RTCollector.Disable ( ) early in the program and leaving it > disabled makes the problem go away. > > > --------------------------------------------------------------------------------------------------------------------- > > rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/ > newtext/src$ m3gdb test > GNU gdb plus Modula-3 6.4 > Copyright 2005 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and > you are > welcome to change it and/or distribute copies of it under certain > conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for > details. > This GDB was configured as "i686-pc-linux-gnu"...Using host > libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". > > (m3gdb) run -nos > Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/ > tests/newtext/src/test -nos > Signal Stop Print Pass to program Description > SIG64 No No Yes Real-time event 64 > [Thread debugging using libthread_db enabled] > [New LWP 32595] > Estimating overhead of timing. > Generating initial leaf strings. > Generating initial leaf strings. > > 0\ > Garbage collection disabled for better timing. > > 62[New Thread -1220703344 (LWP 32598)] > [New Thread -1220429104 (LWP 32595)] > ....+....1....+....2....+....3....+....4....+....| > 5000....+....6....+....7....+....8....+....9....+....| > 10000....+....1....+....2....+....3....+....4....+....| > 15000....+....6....+....7....+....8....+....9....+....| > 20000....+....1....+....2....+....3....+....4....+....| > 25000....+....6....+....7....+....8....+....9....+....| > 30000....+....1....+....2....+....3....+....4....+....| > 35000....+....6....+....7....+....8....+....9....+....| > 40000....+....1....+....2....+....3....+....4....+....| > 45000....+....6....+....7....+....8....+....9....+....| > 50000 > > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > Garbage collection completed. > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220429104 (LWP 32595)] > 0xb7f7d410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f7d410 in __kernel_vsyscall () > #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/ > libpthread.so.0 > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Quit this debugging session? (y or n) y > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Create a core file of GDB? (y or n) y > Aborted (core dumped) > --------------------------------------------------------------------------------------------------------------------- > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220732208 (LWP 32623)] > 0xb7f33410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f33410 in __kernel_vsyscall () > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol > table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > Can't find child block 1, at level 1, of parent procedure > "Test__GetParams", for nested procedure > "Test__GetParams__1__1__NumArg.778" > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol > table. > ) at ../src/Test.m3:1628 > #6 0x0805b764 in Work () at ../src/Test.m3:2536 > #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol > table. > ) at ../src/Test.m3:2658 > #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in > symbol table. > ) at ../src/runtime/common/RTLinker.m3:399 > #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:113 > #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:122 > #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at > _m3main.mc:4 > #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/ > libc.so.6 > #13 0x08049ed1 in _start () > (m3gdb) frame 4 > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > 1354 ; Thread . Pause ( 2.0D0 ) > Current language: auto; currently Modula-3 > (m3gdb) down > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > 668 XPause(self, n, alertable := FALSE); > (m3gdb) down > #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type > code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > 651 WITH r = Utime.nanosleep(amount, remaining) DO > (m3gdb) down > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > (m3gdb) down > #0 0xb7f33410 in __kernel_vsyscall () > (m3gdb) > > > --------------------------------------------------------------------------------------------------------------------- -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Sat Feb 21 02:29:05 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Sat, 21 Feb 2009 12:29:05 +1100 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: <499F3E67.9080605@wichita.edu> References: <499F3E67.9080605@wichita.edu> Message-ID: Rodney, I see what the problem is. Please try with the latest version of ThreadPThread.m3. -- Tony On 21 Feb 2009, at 10:36, Rodney M. Bates wrote: > I got an assertion failure in ThreadPThread.m3. > > Here is a transcript. Below that is a more helpful backtrace I got by > manually stopping it as quickly as I could after the assertion failure > messages. I think the second backtrace is not on the relevant thread > however, because commenting out the Thread.Pause does not make the > failure > go away, just makes it harder to catch. > > Note: I have a lot of weakref cleanups registered. Executing > RTCollector.Disable ( ) early in the program and leaving it > disabled makes the problem go away. > > > --------------------------------------------------------------------------------------------------------------------- > > rodney at yellowstone:~/proj/m3/cm3-new/cm3/m3-libs/m3core/tests/ > newtext/src$ m3gdb test > GNU gdb plus Modula-3 6.4 > Copyright 2005 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and > you are > welcome to change it and/or distribute copies of it under certain > conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for > details. > This GDB was configured as "i686-pc-linux-gnu"...Using host > libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". > > (m3gdb) run -nos > Starting program: /home/rodney/proj/m3/cm3-new/cm3/m3-libs/m3core/ > tests/newtext/src/test -nos > Signal Stop Print Pass to program Description > SIG64 No No Yes Real-time event 64 > [Thread debugging using libthread_db enabled] > [New LWP 32595] > Estimating overhead of timing. > Generating initial leaf strings. > Generating initial leaf strings. > > 0\ > Garbage collection disabled for better timing. > > 62[New Thread -1220703344 (LWP 32598)] > [New Thread -1220429104 (LWP 32595)] > ....+....1....+....2....+....3....+....4....+....| > 5000....+....6....+....7....+....8....+....9....+....| > 10000....+....1....+....2....+....3....+....4....+....| > 15000....+....6....+....7....+....8....+....9....+....| > 20000....+....1....+....2....+....3....+....4....+....| > 25000....+....6....+....7....+....8....+....9....+....| > 30000....+....1....+....2....+....3....+....4....+....| > 35000....+....6....+....7....+....8....+....9....+....| > 40000....+....1....+....2....+....3....+....4....+....| > 45000....+....6....+....7....+....8....+....9....+....| > 50000 > > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > Garbage collection completed. > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220429104 (LWP 32595)] > 0xb7f7d410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f7d410 in __kernel_vsyscall () > #1 0xb7577589 in __lll_lock_wait () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb7572ba6 in _L_lock_95 () from /lib/tls/i686/cmov/ > libpthread.so.0 > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Quit this debugging session? (y or n) y > ../../gdb/gdb/dwarf2-frame.c:490: internal-error: Unknown CFI > encountered. > A problem internal to GDB has been detected, > further debugging may prove unreliable. > Create a core file of GDB? (y or n) y > Aborted (core dumped) > --------------------------------------------------------------------------------------------------------------------- > Garbage collection enabled and triggered ... > > *** > *** runtime error: > *** <*ASSERT*> failed. > *** file "../src/thread/PTHREAD/ThreadPThread.m3", line 1449 > *** > > > Program received signal SIGINT, Interrupt. > [Switching to Thread -1220732208 (LWP 32623)] > 0xb7f33410 in __kernel_vsyscall () > (m3gdb) bt > #0 0xb7f33410 in __kernel_vsyscall () > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > #2 0xb75cd016 in XPause (self=Invalid C/C++ type code 26 in symbol > table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > Can't find child block 1, at level 1, of parent procedure > "Test__GetParams", for nested procedure > "Test__GetParams__1__1__NumArg.778" > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > #5 0x0805631b in FillBase (N=Invalid C/C++ type code 40 in symbol > table. > ) at ../src/Test.m3:1628 > #6 0x0805b764 in Work () at ../src/Test.m3:2536 > #7 0x0805d387 in Test (mode=Invalid C/C++ type code 39 in symbol > table. > ) at ../src/Test.m3:2658 > #8 0xb75ba22c in RunMainBody (m=Invalid C/C++ type code 29 in > symbol table. > ) at ../src/runtime/common/RTLinker.m3:399 > #9 0xb75b95e6 in AddUnitI (m=Invalid C/C++ type code 29 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:113 > #10 0xb75b9674 in AddUnit (b=Invalid C/C++ type code 31 in symbol > table. > ) at ../src/runtime/common/RTLinker.m3:122 > #11 0x08049f7e in main (argc=2, argv=0xbfdd4424, envp=0xbfdd4430) at > _m3main.mc:4 > #12 0xb73e8450 in __libc_start_main () from /lib/tls/i686/cmov/ > libc.so.6 > #13 0x08049ed1 in _start () > (m3gdb) frame 4 > #4 0x08054c4c in ResumeCollection () at ../src/Test.m3:1354 > 1354 ; Thread . Pause ( 2.0D0 ) > Current language: auto; currently Modula-3 > (m3gdb) down > #3 0xb75cd193 in Pause (n=Invalid C/C++ type code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:668 > 668 XPause(self, n, alertable := FALSE); > (m3gdb) down > #2 0xb75cd016 in XPause (self=16_b66607ac, n=Invalid C/C++ type > code 44 in symbol table. > ) at ../src/thread/PTHREAD/ThreadPThread.m3:651 > 651 WITH r = Utime.nanosleep(amount, remaining) DO > (m3gdb) down > #1 0xb752e196 in __nanosleep_nocancel () from /lib/tls/i686/cmov/ > libpthread.so.0 > (m3gdb) down > #0 0xb7f33410 in __kernel_vsyscall () > (m3gdb) > > > --------------------------------------------------------------------------------------------------------------------- From rodney.bates at wichita.edu Sat Feb 21 03:51:04 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 20 Feb 2009 20:51:04 -0600 Subject: [M3devel] Assert failure in ThreadPThread.m3 In-Reply-To: References: <499F3E67.9080605@wichita.edu> Message-ID: <499F6C18.2070101@wichita.edu> Thanks, that fixed it. Tony Hosking wrote: > Rodney, > > I see what the problem is. Please try with the latest version of > ThreadPThread.m3. > > -- Tony > From rodney.bates at wichita.edu Mon Feb 23 02:53:26 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sun, 22 Feb 2009 19:53:26 -0600 Subject: [M3devel] New Text branch introduces no build failures on LINUXLIBC6 Message-ID: <49A20196.3050101@wichita.edu> A second generation compiler using the new Text branch now builds everything in so-cm3-all.sh, on LINUXLIBC6, with no failures that are not already present when building using the trunk Text code. Rodney Bates. From wagner at elegosoft.com Wed Feb 25 08:05:03 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 25 Feb 2009 08:05:03 +0100 Subject: [M3devel] cm3 builds broken Message-ID: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> I noticed that all recent tinderbox builds failed: http://tinderbox.elegosoft.com/tinderbox/cm3/status.html Rodney and Jay, please have a look (you were the last to commit). Thanks, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 25 08:43:37 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 25 Feb 2009 07:43:37 +0000 Subject: [M3devel] cm3 builds broken In-Reply-To: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> References: <20090225080503.2d8087eeio08cogk@mail.elegosoft.com> Message-ID: I wish the Tinderbox could send some mail for failures, not too many, but some. 4487 "../src/text/TextCat.m3", line 56: unknown qualification ?.? (NoteIter) 4488 "../src/text/TextCat.m3", line 56: unknown qualification ?.? (Op) Rodney? >From my read a week+ ago, this is just debug/perf tracing from the new branch and can be removed in the mainline if the mainline only has the small bug fixes. - Jay > Date: Wed, 25 Feb 2009 08:05:03 +0100 > From: wagner at elegosoft.com > To: m3devel at elegosoft.com > Subject: [M3devel] cm3 builds broken > > I noticed that all recent tinderbox builds failed: > > http://tinderbox.elegosoft.com/tinderbox/cm3/status.html > > Rodney and Jay, please have a look (you were the last to commit). > > Thanks, > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 25 18:30:36 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 25 Feb 2009 17:30:36 +0000 Subject: [M3devel] scan_float Message-ID: Hm, scan_float is probably wrong, when crossing that changes endianness. PA is big endian. Crossing from little endian Cygwin, in TimePosix.ms I have: L$C0003: .word 0 .word 1093567616 TimePosix__FromUtime .PROC .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 .ENTRY copy %r3,%r1 copy %r30,%r3 stwm %r1,64(%r30) stw %r3,-4(%r30) stw %r19,-32(%r30) stw %r26,-36(%r3) L$M0009: ldw -36(%r3),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr24 ldw -36(%r3),%r28 ldo 4(%r28),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr23 addil LT'L$C0003,%r19 ldw RT'L$C0003(%r1),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr23,%fr22,%fr22 fadd,dbl %fr24,%fr22,%fr22 and Utime_M3 hangs. Yet it I write the equivalent C code on the target system I get: L$C0000: .word 1093567616 .word 0 .SPACE $TEXT$ .NSUBSPA $CODE$ .align 4 .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU FromUtime: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY fldws 4(%r26),%fr22L fcnvxf,sgl,dbl %fr22L,%fr4 ldil LR'L$C0000,%r28 fldws 0(%r26),%fr23L ldo RR'L$C0000(%r28),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr4,%fr22,%fr4 fcnvxf,sgl,dbl %fr23L,%fr24 bv %r0(%r2) fadd,dbl %fr24,%fr4,%fr4 I'll dig into it more later.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From hosking at cs.purdue.edu Thu Feb 26 00:07:35 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 26 Feb 2009 10:07:35 +1100 Subject: [M3devel] scan_float In-Reply-To: References: Message-ID: I think you wrote the most recent version of that code. Can you take a look? On 26 Feb 2009, at 04:30, Jay wrote: > Hm, scan_float is probably wrong, when crossing that changes > endianness. > PA is big endian. > Crossing from little endian Cygwin, in TimePosix.ms I have: > > L$C0003: > .word 0 > .word 1093567616 > > TimePosix__FromUtime > .PROC > .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 > .ENTRY > copy %r3,%r1 > copy %r30,%r3 > stwm %r1,64(%r30) > stw %r3,-4(%r30) > stw %r19,-32(%r30) > stw %r26,-36(%r3) > L$M0009: > ldw -36(%r3),%r28 > fldws 0(%r28),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr24 > ldw -36(%r3),%r28 > ldo 4(%r28),%r28 > fldws 0(%r28),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr23 > addil LT'L$C0003,%r19 > ldw RT'L$C0003(%r1),%r28 > fldds 0(%r28),%fr22 > fdiv,dbl %fr23,%fr22,%fr22 > fadd,dbl %fr24,%fr22,%fr22 > > > and Utime_M3 hangs. > > > Yet it I write the equivalent C code on the target system I get: > > > L$C0000: > .word 1093567616 > .word 0 > .SPACE $TEXT$ > .NSUBSPA $CODE$ > .align 4 > .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU > FromUtime: > .PROC > .CALLINFO FRAME=0,NO_CALLS > .ENTRY > fldws 4(%r26),%fr22L > fcnvxf,sgl,dbl %fr22L,%fr4 > ldil LR'L$C0000,%r28 > fldws 0(%r26),%fr23L > ldo RR'L$C0000(%r28),%r28 > fldds 0(%r28),%fr22 > fdiv,dbl %fr4,%fr22,%fr4 > fcnvxf,sgl,dbl %fr23L,%fr24 > bv %r0(%r2) > fadd,dbl %fr24,%fr4,%fr4 > > > I'll dig into it more later.. > > > - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 26 01:07:24 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 26 Feb 2009 00:07:24 +0000 Subject: [M3devel] scan_float In-Reply-To: References: Message-ID: Yes. From: hosking at cs.purdue.edu To: jay.krell at cornell.edu Date: Thu, 26 Feb 2009 10:07:35 +1100 CC: m3devel at elegosoft.com Subject: Re: [M3devel] scan_float I think you wrote the most recent version of that code. Can you take a look? On 26 Feb 2009, at 04:30, Jay wrote: Hm, scan_float is probably wrong, when crossing that changes endianness. PA is big endian. Crossing from little endian Cygwin, in TimePosix.ms I have: L$C0003: .word 0 .word 1093567616 TimePosix__FromUtime .PROC .CALLINFO FRAME=64,NO_CALLS,SAVE_SP,ENTRY_GR=3 .ENTRY copy %r3,%r1 copy %r30,%r3 stwm %r1,64(%r30) stw %r3,-4(%r30) stw %r19,-32(%r30) stw %r26,-36(%r3) L$M0009: ldw -36(%r3),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr24 ldw -36(%r3),%r28 ldo 4(%r28),%r28 fldws 0(%r28),%fr22L fcnvxf,sgl,dbl %fr22L,%fr23 addil LT'L$C0003,%r19 ldw RT'L$C0003(%r1),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr23,%fr22,%fr22 fadd,dbl %fr24,%fr22,%fr22 and Utime_M3 hangs. Yet it I write the equivalent C code on the target system I get: L$C0000: .word 1093567616 .word 0 .SPACE $TEXT$ .NSUBSPA $CODE$ .align 4 .EXPORT FromUtime,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=FU FromUtime: .PROC .CALLINFO FRAME=0,NO_CALLS .ENTRY fldws 4(%r26),%fr22L fcnvxf,sgl,dbl %fr22L,%fr4 ldil LR'L$C0000,%r28 fldws 0(%r26),%fr23L ldo RR'L$C0000(%r28),%r28 fldds 0(%r28),%fr22 fdiv,dbl %fr4,%fr22,%fr4 fcnvxf,sgl,dbl %fr23L,%fr24 bv %r0(%r2) fadd,dbl %fr24,%fr4,%fr4 I'll dig into it more later.. - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From martinbishop at bellsouth.net Thu Feb 26 04:35:46 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Wed, 25 Feb 2009 21:35:46 -0600 Subject: [M3devel] Dynamic open array question Message-ID: <49A60E12.9090703@bellsouth.net> I have this code: MODULE Callback EXPORTS Main; IMPORT IO, Fmt; TYPE CallBack = PROCEDURE (a: CARDINAL; b: INTEGER); Values = ARRAY [1..5] OF INTEGER; VAR sample := Values{5, 4, 3, 2, 1}; callback := Display; PROCEDURE Display(loc: CARDINAL; val: INTEGER) = BEGIN IO.Put("array[" & Fmt.Int(loc) & "] = " & Fmt.Int(val * val) & "\n"); END Display; PROCEDURE Map(values: Values; worker: CallBack) = BEGIN FOR i := FIRST(values) TO LAST(values) DO worker(i, values[i]); END; END Map; BEGIN Map(sample, callback); END Callback. This code works just fine, but I was thinking of making the array a dynamic open array, but I couldn't figure out what I needed to change. I tried making Values have the type REF ARRAY OF INTEGER and then calling NEW inside of Map(), but I couldn't figure out how to use an array constructor (since Values{5, 4, 3, 2, 1} would complain when Values was a reference type). From hosking at cs.purdue.edu Thu Feb 26 04:54:59 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 26 Feb 2009 14:54:59 +1100 Subject: [M3devel] Dynamic open array question In-Reply-To: <49A60E12.9090703@bellsouth.net> References: <49A60E12.9090703@bellsouth.net> Message-ID: The only constructor for a dynamic array is NEW. To initialize the elements you need to copy them in, something like: a := NEW(REF ARRAY OF INTEGER, n); SUBARRAY(a^, 0, LENGTH(sample)-1) := sample; From jay.krell at cornell.edu Thu Feb 26 17:23:49 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 26 Feb 2009 16:23:49 +0000 Subject: [M3devel] FW: "CheckFloatsAndTypes"? In-Reply-To: <20090226161605.75D9B10D65F2@birch.elegosoft.com> References: <20090226161605.75D9B10D65F2@birch.elegosoft.com> Message-ID: I assume wedging this tiny bit of code into RTLinker would not be welcome? I think it'd have by far the most value there -- get it to run and fail clearly before any other harder to debug problems. void Test__CheckFloatsAndTypes(const T* t2, size_t size, size_t jbsize) { if (size != sizeof(t1)) { printf("%x vs. %x\n", (U)size, (U)sizeof(t1)); assert(size == sizeof(t1)); } if (memcmp(&t1, t2, sizeof(t1)) != 0) { U i = 0; U8* a = (U8*)&t1; U8* b = (U8*)t2; printf("FD_SETSIZE 0x%x\n", (U)FD_SETSIZE); /*printf("offset of max_fdset 0x%x\n", (U)offsetof(T, max_fdset));*/ for (i = 0; i != sizeof(t1); ++i) { if (a[i] != b[i]) { printf("different at offset 0x%x\n", i); } } assert(memcmp(&t1, t2, sizeof(t1)) == 0); } #ifdef __CYGWIN__ assert(jbsize >= (sizeof(jmp_buf) / 4)); #else assert(jbsize == sizeof(jmp_buf)); #endif } - Jay > Date: Thu, 26 Feb 2009 17:16:05 +0000 > To: m3commit at elegosoft.com > From: jkrell at elego.de > Subject: [M3commit] CVS Update: cm3 > > CVSROOT: /usr/cvs > Changes by: jkrell at birch. 09/02/26 17:16:05 > > Modified files: > cm3/m3-sys/m3tests/src/: Test.i3 m3makefile > cm3/m3-sys/m3tests/src/p0/p001/: Main.m3 m3makefile > Added files: > cm3/m3-sys/m3tests/src/: TestC.c > > Log message: > nice little test case to verify compilation of floating point constants > and correctness of Usysdep > I would really like to have this "run" in RTLinker but suspect that would be rejected. > Anywhere else, e.g. here, is kind of too late to be valuable, unless we manage > to get this into boot1.py, and very early in the list of modules that RTLinker > initializes. > > This reveals some existing possible problems. > - arrays of odd number of float and/or double don't > match up between C and Modula-3; probably related to -mno-aligned-floats > - there are other mismatches here masked by inserting size_t padding > in particular I think cywin linger_t has 16 bit integers and there is > disagreement there. But I didn't look into it. > > Luckily the interactions between C and Modula-3 are relatively rare /and/ > relatively conservative and not very likely to hit these issues. > They do merit further attention though. > > "Running this test case" is merely evaluation three efficient assertions > plus dedicating the constant static space to two structs (Modula-3 > might run initialization code for its "const static" though?) > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Sun Feb 1 14:55:59 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 13:55:59 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: How about thread/posix/x86? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jkrell at elego.de > Date: Fri, 30 Jan 2009 14:43:24 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Probably the wrong place for this. If it is x86-dependent it should > go somewhere in the x86 hierarchy, not in a top-level directory like > "context". > > On 30 Jan 2009, at 04:25, Jay Krell wrote: > >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/01/30 04:25:37 >> >> Added files: >> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >> >> Log message: >> highly non-portable working version of set/get/make/swapcontext for >> NT386; >> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >> non-x86, >> though again, it is highly system specific, and inline assembly >> syntax >> is very different between Visual C++ and gcc From jay.krell at cornell.edu Sun Feb 1 15:05:30 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:05:30 +0000 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? Message-ID: Does anyone think the division between m3core/runtime/RTThread and m3core/thread/posix makes sense, is correct, is important, is at all "good", etc.? thread/posix is the only user of RTThread. RTThread was forked into platform-specific variants, but they are all nearly identical. I think this code belongs in m3core/thread/posix/ThreadPosix.m3 or m3core/thread/posix/ThreadPosixC.c and have begun making it so. It is not much code, but it is multiplied out per-platform. There is already RTThreadC.c for many platforms, and introducing ThreadPosixC.c gives me a place to park related C code, in a less disruptive way (ie: ThreadPosixC.c and RTThreadC.c could be merged at some point, probably by deleting RTThreadC.c, once ThreadPosixC.c is complete). My /real/ agenda here is to move to "my rewritten drastically reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), which reduce porting effort, but I feel I can't do that unless user thread support is there, so I am "cleaning up" user thread support along a few lines (make it work on LINUXLIBC6, make it more portable). - Jay From jay.krell at cornell.edu Sun Feb 1 15:11:07 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:11:07 +0000 Subject: [M3devel] solaris RTThread__Transfer? Message-ID: SOLgnu/SOLsun have this: void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { if (getcontext(from) == 0) { to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp return */ setcontext(to); /* fire it up */ } } Two questions: The longjmp emulation is unnecessary, right? (and platform specific) getcontext + setcontext could just be swapcontext, right? Specifically, the "entire function" could "just" be: (yeah yeah, only a slight reduction). void RTThread__Transfer (ucontext_t *from, ucontext_t *to) { swapcontext(from, to); } or even RTThread.i3 PROCEDURE Transfer(...); Yes, I notice the error checking, but a) why would it ever fail b) is that really complete anyway? Just silently ignore the error? ? - Jay From jay.krell at cornell.edu Sun Feb 1 15:44:20 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 14:44:20 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? Message-ID: I'd like to consider further reducing "system dependent cloned headers". Upthread.i3 in particular. We have for example: pthread_mutex_t = ARRAY[1..6] OF INTEGER; Now, pthread_mutex_t is used in two ways. Some statically allocated variables: VAR activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *) slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *) initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *) Some untraced heap allocated variables: PROCEDURE InitMutex (m: Mutex) = VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO END; IF m.mutex # NIL THEN RETURN END; mutex := NEW(UNTRACED REF pthread_mutex_t); WITH r = Upthread.mutex_init(mutex^, NIL) DO END; m.mutex := mutex; FINALLY WITH r = Upthread.mutex_unlock(initMu) DO END; END; RTHeapRep.RegisterFinalCleanup (m, CleanMutex); END InitMutex; The statically allocated variables can just be moved to C, trivial. And their initialization then kept efficient. What is the right way to translate the untraced allocation? OR, here is kind of the opposite question: Why is the mutex heap allocated anyway? Why not embed it "by value"? Granted, that makes it more difficult to smush out platform-specificity. And then to address that: I would kind of like the idea of an "extern type". An extern type is a type whose instances may only be embedded within heap allocated objects, possibly only at the end, possibly with an implied alignment=maximum, their size would be exposed via constant C variable, probably they would have a designated initialization function, or be zeroed. They could also be "standalone" heap allocated objects. Specifically, something like this: TYPE pthread_t; TYPE Thread.T = RECORD (* Modula-3 stuff *) pthread: pthread_t; END; Thread := NEW(Thread.T); roughly equiv to Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); pthread.c: extern const size_t pthread_t_size = sizeof(pthread_t); You know -- so that they can be implemented "portably". Given that they are already opaque and all the Modula-3 code knows is their size, alignment, and what functions they can be passed to. - Jay From hosking at cs.purdue.edu Sun Feb 1 23:31:44 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:31:44 +1100 Subject: [M3devel] m3core/runtime/RTThread vs. m3core/thread/posix? In-Reply-To: References: Message-ID: These divisions are largely historical, and so long as we preserve the required interfaces (see the language report) I don't see a problem with this plan. On 2 Feb 2009, at 01:05, Jay wrote: > > Does anyone think the division between > m3core/runtime/RTThread and m3core/thread/posix makes sense, > is correct, is important, is at all "good", etc.? > > > thread/posix is the only user of RTThread. > RTThread was forked into platform-specific variants, > but they are all nearly identical. > > > I think this code belongs in m3core/thread/posix/ThreadPosix.m3 > or m3core/thread/posix/ThreadPosixC.c and have begun making it so. > > > It is not much code, but it is multiplied out per-platform. > > > There is already RTThreadC.c for many platforms, and > introducing ThreadPosixC.c gives me a place to park related C > code, in a less disruptive way (ie: ThreadPosixC.c and > RTThreadC.c could be merged at some point, probably by deleting > RTThreadC.c, once ThreadPosixC.c is complete). > > > My /real/ agenda here is to move to "my rewritten drastically > reduced headers" on other platforms (*_DARWIN, LINUXLIBC6, FreeBSD), > which reduce porting effort, but I feel > I can't do that unless user thread support is there, > so I am "cleaning up" user thread support along a few lines > (make it work on LINUXLIBC6, make it more portable). > > > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:32:56 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:32:56 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> Message-ID: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> What is the purpose of this code? On 2 Feb 2009, at 00:55, Jay wrote: > > How about thread/posix/x86? > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jkrell at elego.de >> Date: Fri, 30 Jan 2009 14:43:24 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Probably the wrong place for this. If it is x86-dependent it should >> go somewhere in the x86 hierarchy, not in a top-level directory like >> "context". >> >> On 30 Jan 2009, at 04:25, Jay Krell wrote: >> >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>> >>> Added files: >>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>> >>> Log message: >>> highly non-portable working version of set/get/make/swapcontext for >>> NT386; >>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>> non-x86, >>> though again, it is highly system specific, and inline assembly >>> syntax >>> is very different between Visual C++ and gcc From hosking at cs.purdue.edu Sun Feb 1 23:41:29 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:41:29 +1100 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: References: Message-ID: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Sorry, I had mis-remembered that code as using swapcontext, which it clearly does not. I seem to recall that the longjmp emulation was necessary for some reason, but I forget why right now. Was Transfer being called from some place as if it was a longjmp? Hmm... It's been 10 years since I wrote that code for the Solaris port... ;-) On 2 Feb 2009, at 01:11, Jay wrote: > > SOLgnu/SOLsun have this: > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > if (getcontext(from) == 0) { > to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp > return */ > setcontext(to); /* fire it up */ > } > } > > Two questions: > The longjmp emulation is unnecessary, right? (and platform specific) > getcontext + setcontext could just be swapcontext, right? > > > Specifically, the "entire function" could "just" be: (yeah yeah, > only a slight reduction). > > > void RTThread__Transfer (ucontext_t *from, ucontext_t *to) > { > swapcontext(from, to); > } > > > or even > > > RTThread.i3 > PROCEDURE Transfer(...); > > > Yes, I notice the error checking, but a) why would it ever fail b) > is that really complete anyway? > Just silently ignore the error? > > > ? > - Jay From hosking at cs.purdue.edu Sun Feb 1 23:54:27 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 09:54:27 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: Message-ID: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> On 2 Feb 2009, at 01:44, Jay wrote: > I'd like to consider further reducing "system dependent cloned > headers". > Upthread.i3 in particular. > > > We have for example: > > > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Now, pthread_mutex_t is used in two ways. > > > Some statically allocated variables: > > > VAR > activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of > active threads *) > slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread > slot table *) > initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for > initializers *) > > > Some untraced heap allocated variables: > > > PROCEDURE InitMutex (m: Mutex) = > VAR mutex: UNTRACED REF pthread_mutex_t; > BEGIN > TRY > WITH r = Upthread.mutex_lock(initMu) DO END; > IF m.mutex # NIL THEN RETURN END; > mutex := NEW(UNTRACED REF pthread_mutex_t); > WITH r = Upthread.mutex_init(mutex^, NIL) DO END; > m.mutex := mutex; > FINALLY > WITH r = Upthread.mutex_unlock(initMu) DO END; > END; > RTHeapRep.RegisterFinalCleanup (m, CleanMutex); > END InitMutex; > > > The statically allocated variables can just be moved to C, trivial. > And their initialization then kept efficient. Sure, except that now you smear code across the C and Modula-3 universes. Lack of clarity... > What is the right way to translate the untraced allocation? Not sure what you mean by "translate". We are writing Modula-3 in Modula-3 here, so why translate it? I suppose you could invoke some C code to allocate the mutex and return it, but then you have a call to malloc that might not play nice with the Modula-3 code. In the old days this was certainly the case (on user-level thread systems we need malloc to be atomic with respect to thread transfer). Thus, NEW(UNTRACED REF ...) does bottom out at malloc, but RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching around the call to malloc (these disable switching on user-thread platforms, but are no-ops on system threading platforms where malloc should already be thread-safe). How about simply having some C variable that records sizeof(pthread_mutex_t) and use that in a call to new: array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) mutex := ADR(array[0]) > OR, here is kind of the opposite question: > > > Why is the mutex heap allocated anyway? > > Why not embed it "by value"? Because it is difficult to embed by value when the type is opaque. > Granted, that makes it more difficult to smush out platform- > specificity. Indeed. And the rest of what you say here is a pretty disgusting hack. Modula-3 has pretty clean type semantics and you are compromising that in a rather gross way. > > And then to address that: > > > I would kind of like the idea of an "extern type". > An extern type is a type whose instances may only be embedded within > heap allocated objects, > possibly only at the end, possibly with an implied > alignment=maximum, their size > would be exposed via constant C variable, probably they would have a > designated initialization > function, or be zeroed. They could also be "standalone" heap > allocated objects. > > > Specifically, something like this: > > > TYPE pthread_t; > > > TYPE Thread.T = RECORD > (* Modula-3 stuff *) > pthread: pthread_t; > END; > Thread := NEW(Thread.T); > > > roughly equiv to > Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); > > > pthread.c: > > > extern const size_t pthread_t_size = sizeof(pthread_t); > > > You know -- so that they can be implemented "portably". > Given that they are already opaque and all the Modula-3 code knows > is their size, alignment, and what functions they can be passed to. > > > - Jay From jay.krell at cornell.edu Sun Feb 1 23:59:27 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 22:59:27 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > What is the purpose of this code? OpenBSD does not have the *context functions. This provides them for OpenBSD/x86. I /assume/ their only user will be ThreadPosix.m3. That there will be unix/common/ucontext.i3 that declares them. Even if that is a little bit "dishonest" on platforms that lack them. Eh, I guess that begs for the answer, they belong in unix/common/x86? (forking for x86-thisos, x86-thatos, if/as needed) A reason not to put in unix/common/x86 however is if there are compromises that make them not meet the general spec, but adequate for ThreadPosix.m3. I don't have any in mind currently. Restricting makecontext to have argc=1 is tempting, but so far avoided. Perhaps I will see about getting these into OpenBSD. I also anticipate trying to implement them for other systems e.g. PPC_DARWIN. (again, current 10.5 Darwin has them, older 10.4 does not). Possibly in both cases I can just use the "real" versions, I should have thought of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, copy them. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:32:56 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > What is the purpose of this code? > > On 2 Feb 2009, at 00:55, Jay wrote: > >> >> How about thread/posix/x86? >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jkrell at elego.de >>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Probably the wrong place for this. If it is x86-dependent it should >>> go somewhere in the x86 hierarchy, not in a top-level directory like >>> "context". >>> >>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>> >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>> >>>> Added files: >>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>> >>>> Log message: >>>> highly non-portable working version of set/get/make/swapcontext for >>>> NT386; >>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>> non-x86, >>>> though again, it is highly system specific, and inline assembly >>>> syntax >>>> is very different between Visual C++ and gcc > From jay.krell at cornell.edu Mon Feb 2 00:10:17 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:10:17 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: I meant translate Modula-3 to C -- C because it knows size and alignment. I didn't presume I could just call malloc. Even if untraced, I thought calling "the allocator" might have some positive interaction with the garbage collector. Maybe not? (I should look at the code....could be untraced really does just call malloc and no gc interaction. Oops.) > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) That is good. I must have had some hangup about it. NEW is guaranteed to be "very aligned" so there is no alignment issue here? > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... I agree. I'm conflicted here. Look at for example at the dealings with "ackSem". It is a "simple transform" but "transform" is the suspicious word there, not wholly exonerated by "simple". The static variables may also have an issue on Darwin -- can't have non-static variables in a shared object or somesuch. So I'll hold off. (no access to Darwin past few days) Solution could be wrapping the variables up in functions, or every operation on them, like for ackSem. Both kind of not ideal though. On the other hand, the RTThread / RTThreadStk / ThreadPosix split is also a bit smearing/unclear -- you know, FreeStack vs. DisposeStack. But two wrongs don't make a right, I understand. I do consider the user thread code to be a second class citizen. >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. Why? I understand issues of "binary compatibility + dynamic linking". "Pointers are good because they never change size." "Pointers are good for opaque types because they never change size. Better than an int because int often can't store a pointer." But I think we ignore these issues in Modula-3. I know I have been. > hack Seemed a good way to generalize what I'm thinking about for pthread/mutex/etc. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:54:27 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > On 2 Feb 2009, at 01:44, Jay wrote: > >> I'd like to consider further reducing "system dependent cloned >> headers". >> Upthread.i3 in particular. >> >> >> We have for example: >> >> >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Now, pthread_mutex_t is used in two ways. >> >> >> Some statically allocated variables: >> >> >> VAR >> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >> active threads *) >> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >> slot table *) >> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >> initializers *) >> >> >> Some untraced heap allocated variables: >> >> >> PROCEDURE InitMutex (m: Mutex) = >> VAR mutex: UNTRACED REF pthread_mutex_t; >> BEGIN >> TRY >> WITH r = Upthread.mutex_lock(initMu) DO END; >> IF m.mutex # NIL THEN RETURN END; >> mutex := NEW(UNTRACED REF pthread_mutex_t); >> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >> m.mutex := mutex; >> FINALLY >> WITH r = Upthread.mutex_unlock(initMu) DO END; >> END; >> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >> END InitMutex; >> >> >> The statically allocated variables can just be moved to C, trivial. >> And their initialization then kept efficient. > > Sure, except that now you smear code across the C and Modula-3 > universes. Lack of clarity... > >> What is the right way to translate the untraced allocation? > > Not sure what you mean by "translate". We are writing Modula-3 in > Modula-3 here, so why translate it? I suppose you could invoke some C > code to allocate the mutex and return it, but then you have a call to > malloc that might not play nice with the Modula-3 code. In the old > days this was certainly the case (on user-level thread systems we need > malloc to be atomic with respect to thread transfer). Thus, > NEW(UNTRACED REF ...) does bottom out at malloc, but > RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching > around the call to malloc (these disable switching on user-thread > platforms, but are no-ops on system threading platforms where malloc > should already be thread-safe). How about simply having some C > variable that records sizeof(pthread_mutex_t) and use that in a call > to new: > > array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > mutex := ADR(array[0]) > >> OR, here is kind of the opposite question: >> >> >> Why is the mutex heap allocated anyway? >> >> Why not embed it "by value"? > > Because it is difficult to embed by value when the type is opaque. > >> Granted, that makes it more difficult to smush out platform- >> specificity. > > Indeed. > > And the rest of what you say here is a pretty disgusting hack. > Modula-3 has pretty clean type semantics and you are compromising that > in a rather gross way. > >> >> And then to address that: >> >> >> I would kind of like the idea of an "extern type". >> An extern type is a type whose instances may only be embedded within >> heap allocated objects, >> possibly only at the end, possibly with an implied >> alignment=maximum, their size >> would be exposed via constant C variable, probably they would have a >> designated initialization >> function, or be zeroed. They could also be "standalone" heap >> allocated objects. >> >> >> Specifically, something like this: >> >> >> TYPE pthread_t; >> >> >> TYPE Thread.T = RECORD >> (* Modula-3 stuff *) >> pthread: pthread_t; >> END; >> Thread := NEW(Thread.T); >> >> >> roughly equiv to >> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >> >> >> pthread.c: >> >> >> extern const size_t pthread_t_size = sizeof(pthread_t); >> >> >> You know -- so that they can be implemented "portably". >> Given that they are already opaque and all the Modula-3 code knows >> is their size, alignment, and what functions they can be passed to. >> >> >> - Jay > From jay.krell at cornell.edu Mon Feb 2 00:14:32 2009 From: jay.krell at cornell.edu (Jay) Date: Sun, 1 Feb 2009 23:14:32 +0000 Subject: [M3devel] solaris RTThread__Transfer? In-Reply-To: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> References: <7969FBA1-2E65-4494-90BC-560E38745EC8@cs.purdue.edu> Message-ID: > sorry No problem. I just want to understand, if possible, for when I handle other platforms. > Was Transfer being called from some place as if it was a longjmp? I don't think so but I'll double check. The primary use of it I think ignores the return value. Thanks, - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Mon, 2 Feb 2009 09:41:29 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] solaris RTThread__Transfer? > > Sorry, I had mis-remembered that code as using swapcontext, which it > clearly does not. > > I seem to recall that the longjmp emulation was necessary for some > reason, but I forget why right now. Was Transfer being called from > some place as if it was a longjmp? > > Hmm... > > It's been 10 years since I wrote that code for the Solaris port... ;-) > > On 2 Feb 2009, at 01:11, Jay wrote: > >> >> SOLgnu/SOLsun have this: >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> if (getcontext(from) == 0) { >> to->uc_mcontext.gregs[REG_O0] = (greg_t)1; /* emulate longjmp >> return */ >> setcontext(to); /* fire it up */ >> } >> } >> >> Two questions: >> The longjmp emulation is unnecessary, right? (and platform specific) >> getcontext + setcontext could just be swapcontext, right? >> >> >> Specifically, the "entire function" could "just" be: (yeah yeah, >> only a slight reduction). >> >> >> void RTThread__Transfer (ucontext_t *from, ucontext_t *to) >> { >> swapcontext(from, to); >> } >> >> >> or even >> >> >> RTThread.i3 >> PROCEDURE Transfer(...); >> >> >> Yes, I notice the error checking, but a) why would it ever fail b) >> is that really complete anyway? >> Just silently ignore the error? >> >> >> ? >> - Jay > From wagner at elegosoft.com Mon Feb 2 00:12:43 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Mon, 02 Feb 2009 00:12:43 +0100 Subject: [M3devel] ssh outage on birch.elegosoft.com, was: Re: ssh down? In-Reply-To: References: Message-ID: <20090202001243.csodfhd1scg4o8ws@mail.elegosoft.com> Currently all ssh services on birch are out of order. We don't have direct access to this machine; we'll be able to get access again tomorrow morning at 9 CET (without further costs). I expect that Michael will be able to get everything working again soon after, if there is no unrecoverable hardware failure. Restoring from backup would take some hours, I'd expect... Sorry for the inconveniences, Olaf Quoting Jay : > > C:\Documents and Settings\jay>ssh -v -v -v -v jkrell at birch.elegosoft.com > OpenSSH_5.1p1, OpenSSL 0.9.8i 15 Sep 2008 > debug2: ssh_connect: needpriv 0 > debug1: Connecting to birch.elegosoft.com [88.198.39.217] port 22. > debug1: connect to address 88.198.39.217 port 22: Connection refused > ssh: connect to host birch.elegosoft.com port 22: Connection refused > > > C:\Documents and Settings\jay>ping birch.elegosoft.com > PING birch.elegosoft.com (88.198.39.217): 56 data bytes > 64 bytes from 88.198.39.217: icmp_seq=0 ttl=59 time=206 ms > 64 bytes from 88.198.39.217: icmp_seq=1 ttl=59 time=217 ms > ----birch.elegosoft.com PING Statistics---- > 2 packets transmitted, 2 packets received, 0.0% packet loss > round-trip (ms) min/avg/max/med = 206/212/217/212 > > - Jay -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 2 00:27:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:27:46 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> Message-ID: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> On 2 Feb 2009, at 10:10, Jay wrote: > > I meant translate Modula-3 to C -- C because it knows size and > alignment. > I didn't presume I could just call malloc. > Even if untraced, I thought calling "the allocator" might > have some positive interaction with the garbage collector. > Maybe not? > (I should look at the code....could be untraced really > does just call malloc and no gc interaction. Oops.) No GC interaction at all. Just user-level thread interaction to make malloc atomic w.r. to thread switches. >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) > > > That is good. I must have had some hangup about it. > NEW is guaranteed to be "very aligned" so there is no alignment > issue here? Hmm, yes, you are right that there is a possible alignment issue. I am used to pthread_mutext_t being a simple reference. But surely in C the type of the pthread_mutex_t struct would have appropriate alignment padding anyway so as to allow allocation using malloc(sizeof pthread_mutex_t)? So, it all should just work right? >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... > > > I agree. I'm conflicted here. > Look at for example at the dealings with "ackSem". > It is a "simple transform" but "transform" is the suspicious > word there, not wholly exonerated by "simple". I don't have your code in front of me at the moment, but I am leery. > The static variables may also have an issue on Darwin -- can't have > non-static variables in a shared object or somesuch. So I'll hold off. > (no access to Darwin past few days) > Solution could be wrapping the variables up in functions, or every > operation on them, like for ackSem. Both kind of not ideal though. Function call would be fine. You could cache the value in a module variable as needed. > On the other hand, the RTThread / RTThreadStk / ThreadPosix > split is also a bit smearing/unclear -- you know, FreeStack vs. > DisposeStack. > But two wrongs don't make a right, I understand. Indeed, but they originally encapsulated unrelated things. > I do consider the user thread code to be a second class citizen. That's still no reason to muddy it's implementation... :-) >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. > > Why? > I understand issues of "binary compatibility + dynamic linking". > "Pointers are good because they never change size." > "Pointers are good for opaque types because they never change size. > Better than an int because int often can't store a pointer." > > But I think we ignore these issues in Modula-3. I know I have been. I would like to think that we don't ignore these issues and as a result we get a cleaner system. Err on the side of promoting elegance rather than lowering ourselves to the standards of legacy code. >> hack > > Seemed a good way to generalize what I'm thinking about for pthread/ > mutex/etc. > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:54:27 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> On 2 Feb 2009, at 01:44, Jay wrote: >> >>> I'd like to consider further reducing "system dependent cloned >>> headers". >>> Upthread.i3 in particular. >>> >>> >>> We have for example: >>> >>> >>> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >>> >>> >>> Now, pthread_mutex_t is used in two ways. >>> >>> >>> Some statically allocated variables: >>> >>> >>> VAR >>> activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of >>> active threads *) >>> slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread >>> slot table *) >>> initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for >>> initializers *) >>> >>> >>> Some untraced heap allocated variables: >>> >>> >>> PROCEDURE InitMutex (m: Mutex) = >>> VAR mutex: UNTRACED REF pthread_mutex_t; >>> BEGIN >>> TRY >>> WITH r = Upthread.mutex_lock(initMu) DO END; >>> IF m.mutex # NIL THEN RETURN END; >>> mutex := NEW(UNTRACED REF pthread_mutex_t); >>> WITH r = Upthread.mutex_init(mutex^, NIL) DO END; >>> m.mutex := mutex; >>> FINALLY >>> WITH r = Upthread.mutex_unlock(initMu) DO END; >>> END; >>> RTHeapRep.RegisterFinalCleanup (m, CleanMutex); >>> END InitMutex; >>> >>> >>> The statically allocated variables can just be moved to C, trivial. >>> And their initialization then kept efficient. >> >> Sure, except that now you smear code across the C and Modula-3 >> universes. Lack of clarity... >> >>> What is the right way to translate the untraced allocation? >> >> Not sure what you mean by "translate". We are writing Modula-3 in >> Modula-3 here, so why translate it? I suppose you could invoke some C >> code to allocate the mutex and return it, but then you have a call to >> malloc that might not play nice with the Modula-3 code. In the old >> days this was certainly the case (on user-level thread systems we >> need >> malloc to be atomic with respect to thread transfer). Thus, >> NEW(UNTRACED REF ...) does bottom out at malloc, but >> RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching >> around the call to malloc (these disable switching on user-thread >> platforms, but are no-ops on system threading platforms where malloc >> should already be thread-safe). How about simply having some C >> variable that records sizeof(pthread_mutex_t) and use that in a call >> to new: >> >> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t) >> mutex := ADR(array[0]) >> >>> OR, here is kind of the opposite question: >>> >>> >>> Why is the mutex heap allocated anyway? >>> >>> Why not embed it "by value"? >> >> Because it is difficult to embed by value when the type is opaque. >> >>> Granted, that makes it more difficult to smush out platform- >>> specificity. >> >> Indeed. >> >> And the rest of what you say here is a pretty disgusting hack. >> Modula-3 has pretty clean type semantics and you are compromising >> that >> in a rather gross way. >> >>> >>> And then to address that: >>> >>> >>> I would kind of like the idea of an "extern type". >>> An extern type is a type whose instances may only be embedded within >>> heap allocated objects, >>> possibly only at the end, possibly with an implied >>> alignment=maximum, their size >>> would be exposed via constant C variable, probably they would have a >>> designated initialization >>> function, or be zeroed. They could also be "standalone" heap >>> allocated objects. >>> >>> >>> Specifically, something like this: >>> >>> >>> TYPE pthread_t; >>> >>> >>> TYPE Thread.T = RECORD >>> (* Modula-3 stuff *) >>> pthread: pthread_t; >>> END; >>> Thread := NEW(Thread.T); >>> >>> >>> roughly equiv to >>> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t)); >>> >>> >>> pthread.c: >>> >>> >>> extern const size_t pthread_t_size = sizeof(pthread_t); >>> >>> >>> You know -- so that they can be implemented "portably". >>> Given that they are already opaque and all the Modula-3 code knows >>> is their size, alignment, and what functions they can be passed to. >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Mon Feb 2 00:30:22 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 10:30:22 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: On 2 Feb 2009, at 09:59, Jay wrote: >> What is the purpose of this code? > > > OpenBSD does not have the *context functions. > This provides them for OpenBSD/x86. Are they correct w.r. to signals and floating point state? > I /assume/ their only user will be ThreadPosix.m3. > That there will be unix/common/ucontext.i3 that declares them. > Even if that is a little bit "dishonest" on platforms that lack them. > Eh, I guess that begs for the answer, they belong in > unix/common/x86? Yeah, that's where I thought they might go. > (forking for x86-thisos, x86-thatos, if/as needed) > > > A reason not to put in unix/common/x86 however is if there are > compromises that make them not meet the general spec, but adequate > for ThreadPosix.m3. I don't have any in mind currently. > Restricting makecontext to have argc=1 is tempting, but so far > avoided. > > > Perhaps I will see about getting these into OpenBSD. > I also anticipate trying to implement them for other systems e.g. > PPC_DARWIN. > (again, current 10.5 Darwin has them, older 10.4 does not). > Possibly in both cases I can just use the "real" versions, I should > have thought > of that. You know, look the NetBSD/FreeBSD/Darwin 10.5 versions, > copy them. Why do we care about older Darwin versions? The support on Darwin has become much more stable since I first did the port to 10.3, as the base platform has become more reliable. As far as I can tell, prior to 10.5 Darwin still showed signs of being a work in progress (at least w.r. to POSIX compatibility). > > > > - Jay > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Mon, 2 Feb 2009 09:32:56 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> What is the purpose of this code? >> >> On 2 Feb 2009, at 00:55, Jay wrote: >> >>> >>> How about thread/posix/x86? >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jkrell at elego.de >>>> Date: Fri, 30 Jan 2009 14:43:24 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Probably the wrong place for this. If it is x86-dependent it should >>>> go somewhere in the x86 hierarchy, not in a top-level directory >>>> like >>>> "context". >>>> >>>> On 30 Jan 2009, at 04:25, Jay Krell wrote: >>>> >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/01/30 04:25:37 >>>>> >>>>> Added files: >>>>> cm3/m3-libs/m3core/src/context/: context.c context.h tcontext.c >>>>> >>>>> Log message: >>>>> highly non-portable working version of set/get/make/swapcontext >>>>> for >>>>> NT386; >>>>> should assist in providing e.g. Cygwin, OpenBSD/x86, and perhaps >>>>> non-x86, >>>>> though again, it is highly system specific, and inline assembly >>>>> syntax >>>>> is very different between Visual C++ and gcc >> From jay.krell at cornell.edu Mon Feb 2 01:13:04 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 00:13:04 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: References: <20090130032538.030B410D5DAA@birch.elegosoft.com> <8BC6DF3E-5D83-4447-B606-C5A6B24EA315@cs.purdue.edu> Message-ID: > Tony > > Are they correct w.r. to signals and floating point state? > >> Jay Eh, I guess that begs for the answer, they belong in >> unix/common/x86? > > Yeah, that's where I thought they might go. > > Why do we care about older Darwin versions? The support on Darwin has > become much more stable since I first did the port to 10.3, as the > Floating point state and signal mask Not sure. NetBSD getcontext: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/arch/i386/sys/getcontext.S?rev=1.3&content-type=text/x-cvsweb-markup&only_with_tag=MAIN doesn't do anything here...oh..but that clearly isn't the entire implementation.. I'll have to dig around. I will have to write a test case with a bunch of threads and floating point and signal mask changes..and compare to setjmp/longjmp.. You really think 10.5 is so much better than previous? As a user I never noticed much change since 10.2. Anyone else here using prior to 10.5 or care to support them? (I suspect nobody is using any Darwin version but...) But again, IF their get/make/swap/setcontext in 10.5 is all usermode, and presumably BSD-licensed, we can just copy it into m3core. (I suspect the bit I haven't found in NetBSD is in the kernel. Should only take a few minutes to find, but I have to run..) I'll move to unix/src/common/x86 as we both thought of, if it works. Or maybe just work on a system that provides *context. - Jay From mika at async.caltech.edu Mon Feb 2 01:42:32 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sun, 01 Feb 2009 16:42:32 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." Message-ID: <200902020042.n120gXij073476@camembert.async.caltech.edu> I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin (10.3 -> 10.4), all Hell broke loose, too... Mika >> >> Why do we care about older Darwin versions? The support on Darwin has >> become much more stable since I first did the port to 10.3, as the > From jay.krell at cornell.edu Mon Feb 2 02:00:40 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 2 Feb 2009 01:00:40 +0000 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: Your message of "Mon, 02 Feb 2009 00:13:04 GMT." <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: Ok, I forgot to qualify the question -- do you care about user threads? - Jay ---------------------------------------- > To: jay.krell at cornell.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > Date: Sun, 1 Feb 2009 16:42:32 -0800 > From: mika at async.caltech.edu > > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:36:30 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:36:30 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <306B482E-57C1-4711-8760-C5C53C8DED7F@cs.purdue.edu> The CM3 transition 10.2-10.3 was much more difficult than 10.4-10.5. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From hosking at cs.purdue.edu Mon Feb 2 02:37:02 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 2 Feb 2009 12:37:02 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902020042.n120gXij073476@camembert.async.caltech.edu> References: <200902020042.n120gXij073476@camembert.async.caltech.edu> Message-ID: <17D3AB18-01A2-49B8-8D4F-3EB349401E76@cs.purdue.edu> Sorry, meant 10.4-10.5 much easier than previous. On 2 Feb 2009, at 11:42, Mika Nystrom wrote: > > I use CM3 on Darwin 10.4.11 on PPC... Last time I upgraded Darwin > (10.3 -> 10.4), all Hell broke loose, too... > > Mika > >>> >>> Why do we care about older Darwin versions? The support on Darwin >>> has >>> become much more stable since I first did the port to 10.3, as the >> From mika at async.caltech.edu Tue Feb 3 07:21:53 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Mon, 02 Feb 2009 22:21:53 -0800 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> Message-ID: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Jay Krell writes: >CVSROOT: /usr/cvs >Changes by: jkrell at birch. 09/02/03 06:17:25 > >Modified files: > cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 > RTAllocator.m3 > >Log message: > expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely you can't have Free in a non-UNSAFE interface... Mika > introduce internal RTAlloc.MallocUninitialized > > These include Disable/EnableSwitching, and > raising exceptions upon failure. > (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 07:50:21 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 17:50:21 +1100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <931183AC-9652-4F06-8EEB-A5D077669667@cs.purdue.edu> Indeed! I just repaired this. On 3 Feb 2009, at 17:21, Mika Nystrom wrote: > Jay Krell writes: >> CVSROOT: /usr/cvs >> Changes by: jkrell at birch. 09/02/03 06:17:25 >> >> Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >> Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:07:55 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:07:55 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <200902030621.n136LrRM025700@camembert.async.caltech.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: Sorry, fair enough. I don't think about safety much. Can I put these in a new unsafe RTAllocateUnsafe.i3 or RTUnsafeAllocator.i3? And then the function names I had come up with MallocUninitialized, MallocZeroed. Using array of char seems non-ideal to me somehow. It seems like a "workaround". It doesn't seem really any safer than not having a type at all. I understand, the array, the type, does imply a size, and so I would get some bounds checking against it, except I never access these things anyway, I just pass them on to unsafe C code. Related but tangential question, something I also didn't pay close enough attention to: What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise OutOfMemory directly? - Jay ---------------------------------------- > To: jkrell at elego.de > Date: Mon, 2 Feb 2009 22:21:53 -0800 > From: mika at async.caltech.edu > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] [M3commit] CVS Update: cm3 > > Jay Krell writes: >>CVSROOT: /usr/cvs >>Changes by: jkrell at birch. 09/02/03 06:17:25 >> >>Modified files: >> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >> RTAllocator.m3 >> >>Log message: >> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free > > RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely > you can't have Free in a non-UNSAFE interface... > > Mika > >> introduce internal RTAlloc.MallocUninitialized >> >> These include Disable/EnableSwitching, and >> raising exceptions upon failure. >> (Disable/Enable only do something for user threads). From hosking at cs.purdue.edu Tue Feb 3 09:35:38 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 19:35:38 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> Message-ID: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> On 3 Feb 2009, at 19:07, Jay wrote: > > Sorry, fair enough. I don't think about safety much. > > > Can I put these in a new unsafe RTAllocateUnsafe.i3 or > RTUnsafeAllocator.i3? > And then the function names I had come up with MallocUninitialized, > MallocZeroed. What do you need them for? RTAllocator is there so one can allocate by typecode. I don't see the point of Malloc/Free. > Using array of char seems non-ideal to me somehow. > It seems like a "workaround". > It doesn't seem really any safer than not having a type at all. > I understand, the array, the type, does imply a size, and so I would > get some bounds checking against it, except I never access these > things anyway, I just pass them on to unsafe C code. > > > Related but tangential question, something I also didn't pay close > enough attention to: > What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? The first is an explicit exception while the latter is implicit. > Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise > OutOfMemory directly? Because the exception is implicit. Any procedure can raise a RuntimeError. > > > > - Jay > > > ---------------------------------------- >> To: jkrell at elego.de >> Date: Mon, 2 Feb 2009 22:21:53 -0800 >> From: mika at async.caltech.edu >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> Jay Krell writes: >>> CVSROOT: /usr/cvs >>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>> >>> Modified files: >>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>> RTAllocator.m3 >>> >>> Log message: >>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >> >> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >> you can't have Free in a non-UNSAFE interface... >> >> Mika >> >>> introduce internal RTAlloc.MallocUninitialized >>> >>> These include Disable/EnableSwitching, and >>> raising exceptions upon failure. >>> (Disable/Enable only do something for user threads). From jay.krell at cornell.edu Tue Feb 3 09:58:53 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 08:58:53 +0000 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: > What do you need them for? RTAllocator is there so one can allocate How do I get a typecode in C? Perhaps the attached is unnecessarily elaborate? Or the new/dispose functions should be moved to Modula-3? Or eliminated and the small number of callers can say NEW(ARRAY OF CHAR, Uucontext.Size)? - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Tue, 3 Feb 2009 19:35:38 +1100 > CC: jkrell at elego.de; m3devel at elegosoft.com > Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) > > On 3 Feb 2009, at 19:07, Jay wrote: > >> >> Sorry, fair enough. I don't think about safety much. >> >> >> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >> RTUnsafeAllocator.i3? >> And then the function names I had come up with MallocUninitialized, >> MallocZeroed. > > What do you need them for? RTAllocator is there so one can allocate > by typecode. I don't see the point of Malloc/Free. > >> Using array of char seems non-ideal to me somehow. >> It seems like a "workaround". >> It doesn't seem really any safer than not having a type at all. >> I understand, the array, the type, does imply a size, and so I would >> get some bounds checking against it, except I never access these >> things anyway, I just pass them on to unsafe C code. >> >> >> Related but tangential question, something I also didn't pay close >> enough attention to: >> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? > > The first is an explicit exception while the latter is implicit. > >> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >> OutOfMemory directly? > > Because the exception is implicit. Any procedure can raise a > RuntimeError. > >> >> >> >> - Jay >> >> >> ---------------------------------------- >>> To: jkrell at elego.de >>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>> From: mika at async.caltech.edu >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>> >>> Jay Krell writes: >>>> CVSROOT: /usr/cvs >>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>> >>>> Modified files: >>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>> RTAllocator.m3 >>>> >>>> Log message: >>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>> >>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? Surely >>> you can't have Free in a non-UNSAFE interface... >>> >>> Mika >>> >>>> introduce internal RTAlloc.MallocUninitialized >>>> >>>> These include Disable/EnableSwitching, and >>>> raising exceptions upon failure. >>>> (Disable/Enable only do something for user threads). > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.c URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.h URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Uucontext.i3 URL: From hosking at cs.purdue.edu Tue Feb 3 11:42:00 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Tue, 3 Feb 2009 21:42:00 +1100 Subject: [M3devel] unsafety in RTAllocator (Malloc/Free) In-Reply-To: References: Your message of "Tue, 03 Feb 2009 06:17:25." <20090203051725.B402910D5599@birch.elegosoft.com> <200902030621.n136LrRM025700@camembert.async.caltech.edu> <93E01A35-2213-435D-9DF5-1A8C66885923@cs.purdue.edu> Message-ID: This will highly likely break. Let me take a look and see if there's an alternative. On 3 Feb 2009, at 19:58, Jay wrote: > >> What do you need them for? RTAllocator is there so one can allocate > > How do I get a typecode in C? > > Perhaps the attached is unnecessarily elaborate? > Or the new/dispose functions should be moved to Modula-3? > Or eliminated and the small number of callers can say NEW(ARRAY OF > CHAR, Uucontext.Size)? > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Tue, 3 Feb 2009 19:35:38 +1100 >> CC: jkrell at elego.de; m3devel at elegosoft.com >> Subject: Re: [M3devel] unsafety in RTAllocator (Malloc/Free) >> >> On 3 Feb 2009, at 19:07, Jay wrote: >> >>> >>> Sorry, fair enough. I don't think about safety much. >>> >>> al >>> Can I put these in a new unsafe RTAllocateUnsafe.i3 or >>> RTUnsafeAllocator.i3? >>> And then the function names I had come up with MallocUninitialized, >>> MallocZeroed. >> >> What do you need them for? RTAllocator is there so one can allocate >> by typecode. I don't see the point of Malloc/Free. >> >>> Using array of char seems non-ideal to me somehow. >>> It seems like a "workaround". >>> It doesn't seem really any safer than not having a type at all. >>> I understand, the array, the type, does imply a size, and so I would >>> get some bounds checking against it, except I never access these >>> things anyway, I just pass them on to unsafe C code. >>> >>> >>> Related but tangential question, something I also didn't pay close >>> enough attention to: >>> What is the deal with OutOfMemory vs. RuntimeError.T.OutOfMemory? >> >> The first is an explicit exception while the latter is implicit. >> >>> Why don't Malloc, GetUntracedOpenArray, GetUntracedObj, etc. raise >>> OutOfMemory directly? >> >> Because the exception is implicit. Any procedure can raise a >> RuntimeError. >> >>> >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> To: jkrell at elego.de >>>> Date: Mon, 2 Feb 2009 22:21:53 -0800 >>>> From: mika at async.caltech.edu >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >>>> >>>> Jay Krell writes: >>>>> CVSROOT: /usr/cvs >>>>> Changes by: jkrell at birch. 09/02/03 06:17:25 >>>>> >>>>> Modified files: >>>>> cm3/m3-libs/m3core/src/runtime/common/: RTAllocator.i3 >>>>> RTAllocator.m3 >>>>> >>>>> Log message: >>>>> expose RTAllocator.MallocZeroed (calloc), and RTAllocator.Free >>>> >>>> RTAllocator isn't UNSAFE is it (it isn't in my installation)? >>>> Surely >>>> you can't have Free in a non-UNSAFE interface... >>>> >>>> Mika >>>> >>>>> introduce internal RTAlloc.MallocUninitialized >>>>> >>>>> These include Disable/EnableSwitching, and >>>>> raising exceptions upon failure. >>>>> (Disable/Enable only do something for user threads). > From martinbishop at bellsouth.net Tue Feb 3 20:22:06 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:22:06 -0600 Subject: [M3devel] Initialize array to zero? Message-ID: <4988995E.4040605@bellsouth.net> Quick question, is it possible to initialize an array to all zeros? I tried: VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; but I get errors...I also tried just {0} but that errors too. From martinbishop at bellsouth.net Tue Feb 3 20:45:12 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 13:45:12 -0600 Subject: [M3devel] Initialize array to zero? In-Reply-To: <4988995E.4040605@bellsouth.net> References: <4988995E.4040605@bellsouth.net> Message-ID: <49889EC8.8060103@bellsouth.net> Martin Bishop wrote: > Quick question, is it possible to initialize an array to all zeros? > > I tried: > > VAR a := ARRAY [1..10] OF INTEGER {0 .. 0}; > > but I get errors...I also tried just {0} but that errors too. > Never mind, I figured it out, it's {0, ..} :) From jay.krell at cornell.edu Tue Feb 3 23:05:51 2009 From: jay.krell at cornell.edu (Jay) Date: Tue, 3 Feb 2009 22:05:51 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: > Hmm, yes, you are right that there is a possible alignment issue. I > am used to pthread_mutext_t being a simple reference. But surely in C > the type of the pthread_mutex_t struct would have appropriate > alignment padding anyway so as to allow allocation using malloc(sizeof > pthread_mutex_t)? So, it all should just work right? I think "the other way around" and same conclusion. malloc should return something "maximally aligned" so that pthread_mutex_t* x = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t)); works. pthread_mutex_t doesn't need the padding, malloc does, so to speak. Just as long as we don't have TYPE Foo = RECORD a: pthread_mutex_t; b: pthread_mutex_t; c: pthread_t; d: pthread_t; e: pthread_cond_t; f: pthread_cond_t; END; and such, ok. malloc on NT returns something with 2 * sizeof(void*) alignment. I think on Win9x only 4 alignment, thus there is _malloc_aligned for dealing with SSE stuff. Something like that. I didn't realize untraced allocations were basically just malloc but indeed they are. I'm still mulling over the possible deoptimizations here. I'm reluctant to increase heap allocations. - Jay From hosking at cs.purdue.edu Tue Feb 3 23:54:01 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 09:54:01 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> Message-ID: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> I suggest you come up with a proposal for us to look over before you change the code base for this. On 4 Feb 2009, at 09:05, Jay wrote: > >> Hmm, yes, you are right that there is a possible alignment issue. I >> am used to pthread_mutext_t being a simple reference. But surely in C >> the type of the pthread_mutex_t struct would have appropriate >> alignment padding anyway so as to allow allocation using >> malloc(sizeof >> pthread_mutex_t)? So, it all should just work right? > > > I think "the other way around" and same conclusion. > malloc should return something "maximally aligned" so that > > pthread_mutex_t* x = (pthread_mutex_t*) > malloc(sizeof(pthread_mutex_t)); > > > works. pthread_mutex_t doesn't need the padding, malloc does, so to > speak. > > > Just as long as we don't have > > > TYPE Foo = RECORD > a: pthread_mutex_t; > b: pthread_mutex_t; > c: pthread_t; > d: pthread_t; > e: pthread_cond_t; > f: pthread_cond_t; > END; > > > and such, ok. > > > malloc on NT returns something with 2 * sizeof(void*) alignment. > I think on Win9x only 4 alignment, thus there is _malloc_aligned for > dealing with SSE stuff. > Something like that. > > > I didn't realize untraced allocations were basically just malloc but > indeed they are. > > > I'm still mulling over the possible deoptimizations here. > I'm reluctant to increase heap allocations. > > > > - Jay From jay.krell at cornell.edu Wed Feb 4 01:06:24 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:06:24 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: There are a few possibilities: Roughly: Where there is INTERFACE Upthread; TYPE pthread_t = ... system specific ... pthread_cond_t = ... system specific ... pthread_mutex_t = ... system specific ... PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); MODULE PThread; VAR a: pthread_t; b: pthread_cond_t; c: pthread_mutex_t; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; change to: INTERFACE Upthread; TYPE pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type pthread_cond_t = RECORD END; ditto pthread_mutex_t = RECORD END; ditto PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); INTERFACE PThreadC.i3 PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; or possibly extern VAR PThreadC.c static pthread_t a = PTHREAD_INIT; static pthread_cond_t b = PTHREAD_COND_INIT; static pthread_mutex_t c = PTHREAD_MUTEX_INIT; pthread_t* GetA() { return &a; } pthread_cond_t* GetB() { return &b; } pthread_mutex_t* GetC() { return &c; } MODULE PThread; VAR a := PThreadC.GetA(); b := PThreadC.GetB(); c := PThreadC.GetA(); PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a^); Upthread.pthread_cond_init_or_whatever(b^); Upthread.pthread_mutex_init_or_whatever(c^); END Foo; or, again, possibly they are variables and it goes a little smaller/quicker: FROM UPthreadC IMPORT a, b, c; PROCEDURE Foo() = BEGIN Upthread.pthread_thread_init_or_whatever(a); Upthread.pthread_cond_init_or_whatever(b); Upthread.pthread_mutex_init_or_whatever(c); END Foo; I think that is pretty cut and dry, no controversy. What is less clear is what to do with non-statically allocated variables. Let's say: MODULE PThread; TYPE T = RECORD a:int; b:pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T) BEGIN Upthread.init_or_whatever(t.b); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b); DISPOSE(t); END; The desire is something that does not know the size of pthread_t, something like: TYPE T = RECORD a:int; b:UNTRACED REF pthread_t; END; PROCEDURE CreateT():T= VAR t := NEW(T); BEGIN t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) Upthread.init_or_whatever(t.b^); RETURN t; END; PROCEDURE DisposeT(t:T)= BEGIN IF t = NIL THEN RETURN END; Upthread.pthread_cleanup_or_whatever(t.b^); DISPOSE(t.b); DISPOSE(t); END; However that incurs an extra heap allocation, which is not great. In at least one place, the pointer-indirection-and-heap-allocation is already there so this isn't a deoptimization. However "reoptimizing" it might be nice. What I would prefer a pattern I often use in C -- merging allocations, something like, /assuming/ t is untraced, which I grant it might not be. And ensuring that BYTESIZE(T) is properly aligned: PROCEDURE CreateT():UNTRACED REF T= VAR p : ADDRESS; t : UNTRACED REF T; BEGIN (* Again I would prefer RTAllocator.MallocZeroed *) p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); t := LOOPHOLE(UNTRACED REF T, p); t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); Upthread.init_or_whatever(t.b^); RETURN t; END; That is -- opaque types, size not known at compile-time, but size known at runtime, and do not incur an extra heap allocation for lack of knowing sizes at compile-time. For the statically allocated variables I think there is no controversy. There might a tiny bit of overhead in the use, but it'd be very small, and possibly even removable in the future. I'd rather avoid the variables, as all writable data is to be avoided. Read only pages are better and all that, but ok.. However the value is mainly realized only if statically and dynamically allocated variables are handled. The result of this would be further reduction in platform-specificity when cloning C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 09:54:01 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I suggest you come up with a proposal for us to look over before you > change the code base for this. > > On 4 Feb 2009, at 09:05, Jay wrote: > >> >>> Hmm, yes, you are right that there is a possible alignment issue. I >>> am used to pthread_mutext_t being a simple reference. But surely in C >>> the type of the pthread_mutex_t struct would have appropriate >>> alignment padding anyway so as to allow allocation using >>> malloc(sizeof >>> pthread_mutex_t)? So, it all should just work right? >> >> >> I think "the other way around" and same conclusion. >> malloc should return something "maximally aligned" so that >> >> pthread_mutex_t* x = (pthread_mutex_t*) >> malloc(sizeof(pthread_mutex_t)); >> >> >> works. pthread_mutex_t doesn't need the padding, malloc does, so to >> speak. >> >> >> Just as long as we don't have >> >> >> TYPE Foo = RECORD >> a: pthread_mutex_t; >> b: pthread_mutex_t; >> c: pthread_t; >> d: pthread_t; >> e: pthread_cond_t; >> f: pthread_cond_t; >> END; >> >> >> and such, ok. >> >> >> malloc on NT returns something with 2 * sizeof(void*) alignment. >> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >> dealing with SSE stuff. >> Something like that. >> >> >> I didn't realize untraced allocations were basically just malloc but >> indeed they are. >> >> >> I'm still mulling over the possible deoptimizations here. >> I'm reluctant to increase heap allocations. >> >> >> >> - Jay > From jay.krell at cornell.edu Wed Feb 4 01:35:04 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 00:35:04 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: Addendum: if size <= BYTESIZE(ADDRESS), which is common, it is desirable to avoid the extra heap allocation and just use the space for the pointer. You end up with like: TYPE T = RECORD ... pthread: UNTRACED REF pthread_t END; PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t BEGIN IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); ELSE RETURN t.pthread; END GetPThread; - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 00:06:24 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation is already there > so this isn't a deoptimization. However "reoptimizing" it might be nice. > > > What I would prefer a pattern I often use in C -- merging allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at compile-time. > > > For the statically allocated variables I think there is no controversy. > There might a tiny bit of overhead in the use, but it'd be very small, and possibly > even removable in the future. I'd rather avoid the variables, as all writable > data is to be avoided. Read only pages are better and all that, but ok.. > > > However the value is mainly realized only if statically and dynamically allocated variables are handled. > > The result of this would be further reduction in platform-specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From hosking at cs.purdue.edu Wed Feb 4 02:50:41 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:50:41 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: You need to be careful here w.r. to traced heap allocation, since objects can move. It is not safe to return the address of any field of a traced object. On 4 Feb 2009, at 11:35, Jay wrote: > > Addendum: > if size <= BYTESIZE(ADDRESS), which is common, it is desirable to > avoid the extra heap allocation and just use the space for the > pointer. > > You end up with like: > > TYPE T = RECORD > ... > pthread: UNTRACED REF pthread_t > END; > > > PROCEDURE GetPThread(T:t):UNTRACED REF pthread_t > BEGIN > IF Upthread.pthread_t_size <= BYTESIZE(ADDRES) > RETURN LOOPHOLE(UNTRACED REF pthread_t, ADR(t.pthread)); > ELSE > RETURN t.pthread; > END GetPThread; > > > - Jay > > > > > > > > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 00:06:24 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, but >> ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment >>>>> issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned >>>> for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc >>>> but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> From hosking at cs.purdue.edu Wed Feb 4 02:53:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 12:53:54 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: I am very leery of this proposal -- the code will be inherently opaque and unmaintainable. I don't see any advantage to it. On 4 Feb 2009, at 11:06, Jay wrote: > > There are a few possibilities: > > > Roughly: > > Where there is > > INTERFACE Upthread; > > TYPE > pthread_t = ... system specific ... > pthread_cond_t = ... system specific ... > pthread_mutex_t = ... system specific ... > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > MODULE PThread; > VAR > a: pthread_t; > b: pthread_cond_t; > c: pthread_mutex_t; > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > change to: > > INTERFACE Upthread; > > TYPE > pthread_t = RECORD END; or whatever is correct for an opaque > preferably unique type > pthread_cond_t = RECORD END; ditto > pthread_mutex_t = RECORD END; ditto > > PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); > PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); > PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); > > > INTERFACE PThreadC.i3 > > PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; > PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; > PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; > > or possibly extern VAR > > PThreadC.c > > static pthread_t a = PTHREAD_INIT; > static pthread_cond_t b = PTHREAD_COND_INIT; > static pthread_mutex_t c = PTHREAD_MUTEX_INIT; > > pthread_t* GetA() { return &a; } > > pthread_cond_t* GetB() { return &b; } > > pthread_mutex_t* GetC() { return &c; } > > MODULE PThread; > VAR > a := PThreadC.GetA(); > b := PThreadC.GetB(); > c := PThreadC.GetA(); > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a^); > Upthread.pthread_cond_init_or_whatever(b^); > Upthread.pthread_mutex_init_or_whatever(c^); > END Foo; > > or, again, possibly they are variables and it goes a little smaller/ > quicker: > > FROM UPthreadC IMPORT a, b, c; > > > PROCEDURE Foo() = > BEGIN > Upthread.pthread_thread_init_or_whatever(a); > Upthread.pthread_cond_init_or_whatever(b); > Upthread.pthread_mutex_init_or_whatever(c); > END Foo; > > I think that is pretty cut and dry, no controversy. > > What is less clear is what to do with non-statically allocated > variables. > > Let's say: > > MODULE PThread; > > TYPE T = RECORD > a:int; > b:pthread_t; > END; > > PROCEDURE CreateT():T= > VAR > t := NEW(T) > BEGIN > Upthread.init_or_whatever(t.b); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b); > DISPOSE(t); > END; > > The desire is something that does not know the size of pthread_t, > something like: > > TYPE T = RECORD > a:int; > b:UNTRACED REF pthread_t; > END; > > > PROCEDURE CreateT():T= > VAR > t := NEW(T); > BEGIN > t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF > CHAR, Upthread.pthread_t_size)); > (* Though I really wanted t.b := > RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > PROCEDURE DisposeT(t:T)= > BEGIN > IF t = NIL THEN RETURN END; > Upthread.pthread_cleanup_or_whatever(t.b^); > DISPOSE(t.b); > DISPOSE(t); > END; > > > However that incurs an extra heap allocation, which is not great. > In at least one place, the pointer-indirection-and-heap-allocation > is already there > so this isn't a deoptimization. However "reoptimizing" it might be > nice. > > > What I would prefer a pattern I often use in C -- merging > allocations, something like, > /assuming/ t is untraced, which I grant it might not be. > > > And ensuring that BYTESIZE(T) is properly aligned: > > > PROCEDURE CreateT():UNTRACED REF T= > VAR > p : ADDRESS; > t : UNTRACED REF T; > BEGIN > (* Again I would prefer RTAllocator.MallocZeroed *) > p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + > BYTESIZE(T))); > t := LOOPHOLE(UNTRACED REF T, p); > t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); > Upthread.init_or_whatever(t.b^); > RETURN t; > END; > > > That is -- opaque types, size not known at compile-time, but size > known at runtime, and > do not incur an extra heap allocation for lack of knowing sizes at > compile-time. > > > For the statically allocated variables I think there is no > controversy. > There might a tiny bit of overhead in the use, but it'd be very > small, and possibly > even removable in the future. I'd rather avoid the variables, as > all writable > data is to be avoided. Read only pages are better and all that, > but ok.. > > > However the value is mainly realized only if statically and > dynamically allocated variables are handled. > > The result of this would be further reduction in platform- > specificity when cloning > C headers into Modula-3 interfaces. i.e. less work to bring up new > platforms. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 09:54:01 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I suggest you come up with a proposal for us to look over before you >> change the code base for this. >> >> On 4 Feb 2009, at 09:05, Jay wrote: >> >>> >>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>> am used to pthread_mutext_t being a simple reference. But surely >>>> in C >>>> the type of the pthread_mutex_t struct would have appropriate >>>> alignment padding anyway so as to allow allocation using >>>> malloc(sizeof >>>> pthread_mutex_t)? So, it all should just work right? >>> >>> >>> I think "the other way around" and same conclusion. >>> malloc should return something "maximally aligned" so that >>> >>> pthread_mutex_t* x = (pthread_mutex_t*) >>> malloc(sizeof(pthread_mutex_t)); >>> >>> >>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>> speak. >>> >>> >>> Just as long as we don't have >>> >>> >>> TYPE Foo = RECORD >>> a: pthread_mutex_t; >>> b: pthread_mutex_t; >>> c: pthread_t; >>> d: pthread_t; >>> e: pthread_cond_t; >>> f: pthread_cond_t; >>> END; >>> >>> >>> and such, ok. >>> >>> >>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>> dealing with SSE stuff. >>> Something like that. >>> >>> >>> I didn't realize untraced allocations were basically just malloc but >>> indeed they are. >>> >>> >>> I'm still mulling over the possible deoptimizations here. >>> I'm reluctant to increase heap allocations. >>> >>> >>> >>> - Jay >> From martinbishop at bellsouth.net Wed Feb 4 04:51:33 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 03 Feb 2009 21:51:33 -0600 Subject: [M3devel] opencm3 favicon Message-ID: <498910C5.6050902@bellsouth.net> A little off-topic maybe, but I though opencm3.net needed a favicon. I made 2 different ones: http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue square with a white 3, nice and simple. http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by giving the Modula-3 logo to some online favicon generator. Same as the first one really, only "zoomed in" looking. Feel free to use either one if you want. From wagner at elegosoft.com Wed Feb 4 08:05:07 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 08:05:07 +0100 Subject: [M3devel] tinderbox regression Message-ID: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> The build on LINUXLIBC6 fails: /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command not found ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory Fatal Error: incomplete program *** execution of cm3 -build -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? failed *** Mike, anything changed on birch since yesterday? Or a real M3 problem? One more test fails since yesterday: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 e020 e026 +e029 >>> 13 in test_m3tests 2009-02-03-02-31-01 today: >>> test_m3tests error extract: >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 r004 e020 e026 e029 >>> 14 in test_m3tests 2009-02-04-02-31-17 /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 It seems to be a runtest checking an error: r_test ("r0", "r004", "negative size for an open array") It's just the diff that fails because the line has changed: --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 @@ -3,6 +3,6 @@ *** *** runtime error: *** An enumeration or subrange value was out of range. -*** file "../src/runtime/common/RTAllocator.m3", line 309 +*** file "../src/runtime/common/RTAllocator.m3", line 307 *** Can anybody have a look? Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From michael.anderson at elego.de Wed Feb 4 09:33:56 2009 From: michael.anderson at elego.de (Michael Anderson) Date: Wed, 04 Feb 2009 09:33:56 +0100 Subject: [M3devel] tinderbox regression In-Reply-To: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> References: <20090204080507.da8fevmxw4ggog0w@mail.elegosoft.com> Message-ID: <20090204093356.r1r472b21sgkw4so@mail.elegosoft.com> Quoting Olaf Wagner : > The build on LINUXLIBC6 fails: > > /home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3/m3-sys/m3cc/gcc/mpfr/missing: line 52: aclocal-1.9: command > not > found > ../../gcc/mpfr/get_patches.sh: line 33: PATCHES: No such file or directory > Fatal Error: incomplete program > *** execution of cm3 -build > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship > -DROOT=?/home/m3/work/cm3-ws/birch.elegosoft.com-2009-02-04-03-00-04/cm3? > -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? > -DCM3_LAST_CHANGED=?2009-01-21? failed *** > > Mike, anything changed on birch since yesterday? Or a real M3 problem? Nothing that I'm aware of, except an apache redirect for the Subversion 1.6 news article, which just redirects a google link to the english page... I'll have a look around. > > One more test fails since yesterday: > > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > e020 e026 +e029 > >>> 13 in test_m3tests 2009-02-03-02-31-01 > > today: > >>> test_m3tests error extract: > >>> failed tests: p116b p172 p185 p204 p206 p207 p209 p210 p211 r001 > r004 e020 e026 e029 > >>> 14 in test_m3tests 2009-02-04-02-31-17 > /home/wagner/work/cm3-ws/luthien-2009-02-04-02-31-17 > > It seems to be a runtest checking an error: > r_test ("r0", "r004", "negative size for an open array") > > It's just the diff that fails because the line has changed: > > --- ../src/r0/r004/stderr.pgm Wed Jan 9 02:15:48 2008 > +++ ../src/r0/r004/FreeBSD4/stderr.pgm Wed Feb 4 06:16:22 2009 > @@ -3,6 +3,6 @@ > *** > *** runtime error: > *** An enumeration or subrange value was out of range. > -*** file "../src/runtime/common/RTAllocator.m3", line 309 > +*** file "../src/runtime/common/RTAllocator.m3", line 307 > *** > > Can anybody have a look? > > Olaf > -- > Olaf Wagner -- elego Software Solutions GmbH > Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany > phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 > http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin > Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 -- Michael Anderson IT Services & Support elego Software Solutions GmbH Gustav-Meyer-Allee 25 Building 12.3 (BIG) room 227 13355 Berlin, Germany phone +49 30 23 45 86 96 michael.anderson at elegosoft.com fax +49 30 23 45 86 95 http://www.elegosoft.com Geschaeftsfuehrer: Olaf Wagner, Sitz Berlin Amtsgericht Berlin-Charlottenburg, HRB 77719, USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 10:42:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 09:42:12 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: It gains something, but maybe it isn't enough to be worthwhile. The issue is in the subjectivity. It would remove e.g. the following system-dependent lines: Linux: pthread_t = ADDRESS; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Linux/32: pthread_attr_t = ARRAY[1..9] OF INTEGER; pthread_mutex_t = ARRAY[1..6] OF INTEGER; Linux/64: pthread_attr_t = ARRAY[1..7] OF INTEGER; pthread_mutex_t = ARRAY[1..5] OF INTEGER; FreeBSD: pthread_t = ADDRESS; pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; HP-UX: (* trick from darwin-generic/Upthread.i3 *) X32 = ORD(BITSIZE(INTEGER) = 32); X64 = ORD(BITSIZE(INTEGER) = 64); pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Cygwin: pthread_t = ADDRESS; (* opaque *) pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Solaris: pthread_t = int32_t; (* opaque *) pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) Darwin: (only ppc32 currently) pthread_t = INTEGER; (* opaque *) pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (plus AIX, Irix, VMS, Tru64.) Another approach would be make them all ADDRESS and introduce a portable C layer of "varything thickness", using the same logic. It would look just like the native pthreads, but there'd be extra allocate/cleanup calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. The two layers would be clear and simple, the cost would be the same, but there would be the conceptual cost of two simple layers instead of one just one slightly complicated layer. Another approach is maybe make them all addresses on new platforms and introduce the C layer only on new platforms. Again, about the only change in the Modula-3 code is extra alloc/cleanup calls. And again, some/all of the code already has the indirection/heap allocation unconditionally. And again, maybe not worth it. I show all the system-dependent code, attempting to portray in its worst light by showing all of it, but maybe it's really not a lot. For the attr type, we can do something specific to its use. There is just one use, and we can address it with the following function written in C.. eh..I'll send a diff later tonight/this week I think. pthread_t and pthread_key_t always happen to be address-sized or smaller. Maybe just declare them both to be address and assert their size in some C code. That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. For example, we have: TYPE Activation = UNTRACED REF RECORD (* global doubly-linked, circular list of all active threads *) next, prev: Activation := NIL; (* LL = activeMu *) (* thread handle *) handle: pthread_t; (* LL = activeMu *) (* base of thread stack for use by GC *) stackbase: ADDRESS := NIL; (* LL = activeMu *) so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. Leaving only cond and mutex. Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. rwlock is a useful type though. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 12:53:54 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > I am very leery of this proposal -- the code will be inherently opaque > and unmaintainable. I don't see any advantage to it. > > On 4 Feb 2009, at 11:06, Jay wrote: > >> >> There are a few possibilities: >> >> >> Roughly: >> >> Where there is >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = ... system specific ... >> pthread_cond_t = ... system specific ... >> pthread_mutex_t = ... system specific ... >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> MODULE PThread; >> VAR >> a: pthread_t; >> b: pthread_cond_t; >> c: pthread_mutex_t; >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> change to: >> >> INTERFACE Upthread; >> >> TYPE >> pthread_t = RECORD END; or whatever is correct for an opaque >> preferably unique type >> pthread_cond_t = RECORD END; ditto >> pthread_mutex_t = RECORD END; ditto >> >> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >> >> >> INTERFACE PThreadC.i3 >> >> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >> >> or possibly extern VAR >> >> PThreadC.c >> >> static pthread_t a = PTHREAD_INIT; >> static pthread_cond_t b = PTHREAD_COND_INIT; >> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >> >> pthread_t* GetA() { return &a; } >> >> pthread_cond_t* GetB() { return &b; } >> >> pthread_mutex_t* GetC() { return &c; } >> >> MODULE PThread; >> VAR >> a := PThreadC.GetA(); >> b := PThreadC.GetB(); >> c := PThreadC.GetA(); >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a^); >> Upthread.pthread_cond_init_or_whatever(b^); >> Upthread.pthread_mutex_init_or_whatever(c^); >> END Foo; >> >> or, again, possibly they are variables and it goes a little smaller/ >> quicker: >> >> FROM UPthreadC IMPORT a, b, c; >> >> >> PROCEDURE Foo() = >> BEGIN >> Upthread.pthread_thread_init_or_whatever(a); >> Upthread.pthread_cond_init_or_whatever(b); >> Upthread.pthread_mutex_init_or_whatever(c); >> END Foo; >> >> I think that is pretty cut and dry, no controversy. >> >> What is less clear is what to do with non-statically allocated >> variables. >> >> Let's say: >> >> MODULE PThread; >> >> TYPE T = RECORD >> a:int; >> b:pthread_t; >> END; >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T) >> BEGIN >> Upthread.init_or_whatever(t.b); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b); >> DISPOSE(t); >> END; >> >> The desire is something that does not know the size of pthread_t, >> something like: >> >> TYPE T = RECORD >> a:int; >> b:UNTRACED REF pthread_t; >> END; >> >> >> PROCEDURE CreateT():T= >> VAR >> t := NEW(T); >> BEGIN >> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >> CHAR, Upthread.pthread_t_size)); >> (* Though I really wanted t.b := >> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> PROCEDURE DisposeT(t:T)= >> BEGIN >> IF t = NIL THEN RETURN END; >> Upthread.pthread_cleanup_or_whatever(t.b^); >> DISPOSE(t.b); >> DISPOSE(t); >> END; >> >> >> However that incurs an extra heap allocation, which is not great. >> In at least one place, the pointer-indirection-and-heap-allocation >> is already there >> so this isn't a deoptimization. However "reoptimizing" it might be >> nice. >> >> >> What I would prefer a pattern I often use in C -- merging >> allocations, something like, >> /assuming/ t is untraced, which I grant it might not be. >> >> >> And ensuring that BYTESIZE(T) is properly aligned: >> >> >> PROCEDURE CreateT():UNTRACED REF T= >> VAR >> p : ADDRESS; >> t : UNTRACED REF T; >> BEGIN >> (* Again I would prefer RTAllocator.MallocZeroed *) >> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >> BYTESIZE(T))); >> t := LOOPHOLE(UNTRACED REF T, p); >> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >> Upthread.init_or_whatever(t.b^); >> RETURN t; >> END; >> >> >> That is -- opaque types, size not known at compile-time, but size >> known at runtime, and >> do not incur an extra heap allocation for lack of knowing sizes at >> compile-time. >> >> >> For the statically allocated variables I think there is no >> controversy. >> There might a tiny bit of overhead in the use, but it'd be very >> small, and possibly >> even removable in the future. I'd rather avoid the variables, as >> all writable >> data is to be avoided. Read only pages are better and all that, >> but ok.. >> >> >> However the value is mainly realized only if statically and >> dynamically allocated variables are handled. >> >> The result of this would be further reduction in platform- >> specificity when cloning >> C headers into Modula-3 interfaces. i.e. less work to bring up new >> platforms. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I suggest you come up with a proposal for us to look over before you >>> change the code base for this. >>> >>> On 4 Feb 2009, at 09:05, Jay wrote: >>> >>>> >>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>> in C >>>>> the type of the pthread_mutex_t struct would have appropriate >>>>> alignment padding anyway so as to allow allocation using >>>>> malloc(sizeof >>>>> pthread_mutex_t)? So, it all should just work right? >>>> >>>> >>>> I think "the other way around" and same conclusion. >>>> malloc should return something "maximally aligned" so that >>>> >>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>> malloc(sizeof(pthread_mutex_t)); >>>> >>>> >>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>> speak. >>>> >>>> >>>> Just as long as we don't have >>>> >>>> >>>> TYPE Foo = RECORD >>>> a: pthread_mutex_t; >>>> b: pthread_mutex_t; >>>> c: pthread_t; >>>> d: pthread_t; >>>> e: pthread_cond_t; >>>> f: pthread_cond_t; >>>> END; >>>> >>>> >>>> and such, ok. >>>> >>>> >>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>> dealing with SSE stuff. >>>> Something like that. >>>> >>>> >>>> I didn't realize untraced allocations were basically just malloc but >>>> indeed they are. >>>> >>>> >>>> I'm still mulling over the possible deoptimizations here. >>>> I'm reluctant to increase heap allocations. >>>> >>>> >>>> >>>> - Jay >>> > From jay.krell at cornell.edu Wed Feb 4 11:14:12 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 10:14:12 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers Message-ID: The following eliminates the only use of pthread_attr_t from the cloned headers, slightly reducing the work to port to new platforms. It introduces a "small" "portable" C wrapper to encompass the files lines of Modula-3 that use pthread_attr_t. ok? Index: ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.89 diff -u -r1.89 ThreadPThread.m3 --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 @@ -11,11 +11,10 @@ Unix, Utime, Word, Upthread, Usched, Uerror, ThreadPThreadC, Uexec; FROM Upthread -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, pthread_mutex_t, +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; FROM Compiler IMPORT ThisFile, ThisLine; FROM Ctypes IMPORT int; -FROM Utypes IMPORT size_t; FROM ThreadPThreadC IMPORT SIG_SUSPEND; (*----------------------------------------------------- types and globals ---*) @@ -561,9 +560,7 @@ VAR act := NEW(Activation); t := CreateT(act); - attr: pthread_attr_t; size := defaultStackSize; - bytes: size_t; BEGIN (* determine the initial size of the stack for this thread *) TYPECASE closure OF @@ -576,17 +573,12 @@ t.id := nextId; INC(nextId); IF perfOn THEN PerfChanged(t.id, State.alive) END; - WITH r = Upthread.attr_init(attr) DO END; - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; - bytes := MAX(bytes, size * ADRSIZE(Word.T)); - EVAL Upthread.attr_setstacksize(attr, bytes); act.next := allThreads; act.prev := allThreads.prev; act.size := size; allThreads.prev.next := act; allThreads.prev := act; - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO - EVAL Upthread.attr_destroy(attr); + WITH r = ThreadPThreadC.thread_create(act.handle, size * ADRSIZE(Word.T), ThreadBase, act) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: Fork failed with error: ", r); Index: ThreadPThreadC.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.c,v retrieving revision 1.8 diff -u -r1.8 ThreadPThreadC.c --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 @@ -14,6 +14,7 @@ #include #include #endif +#include #ifdef __cplusplus extern "C" { @@ -145,6 +146,32 @@ #endif } +#define VAR(t) t* +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) +typedef void* (*start_routine_t)(void*); + +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t stackSize, start_routine_t start_routine, void* arg) +{ + int r; + size_t bytes; + pthread_attr_t attr; + + r = pthread_attr_init(&attr); + assert(r == 0); + + r = pthread_attr_getstacksize(&attr, &bytes); + assert(r == 0); + + bytes = MAX(bytes, stackSize); + pthread_attr_setstacksize(&attr, bytes); + + r = pthread_create(pthread, &attr, start_routine, arg); + + pthread_attr_destroy(&attr); + + return r; +} + #ifdef __cplusplus } /* extern "C" */ #endif Index: ThreadPThreadC.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.i3,v retrieving revision 1.5 diff -u -r1.5 ThreadPThreadC.i3 --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 @@ -7,6 +7,8 @@ UNSAFE INTERFACE ThreadPThreadC; FROM Ctypes IMPORT int; +FROM Cstddef IMPORT size_t; +FROM Upthread IMPORT pthread_t, start_routine_t; (*---------------------------------------------------------------------------*) @@ -38,4 +40,11 @@ (*---------------------------------------------------------------------------*) +(* pthread_create but replace attr with stackSize so that attr need not be known to Modula-3 *) + + +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; start_routine: start_routine_t; arg: ADDRESS): int; + +(*---------------------------------------------------------------------------*) + END ThreadPThreadC. The corrolary then, ignoring the "cloned headers" that I leave alone, is: Index: Common/Upthread.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v retrieving revision 1.3 diff -u -r1.3 Upthread.i3 --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 @@ -10,7 +10,6 @@ TYPE pthread_t = Usysdep.pthread_t; - pthread_attr_t = Usysdep.pthread_attr_t; pthread_mutex_t = Usysdep.pthread_mutex_t; pthread_cond_t = Usysdep.pthread_cond_t; pthread_key_t = Usysdep.pthread_key_t; @@ -21,14 +20,9 @@ VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; PROCEDURE detach (thread: pthread_t): int; PROCEDURE self (): pthread_t; PROCEDURE equal (t1, t2: pthread_t): int; - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR stacksize: size_t): int; - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: size_t): int; PROCEDURE yield (): int; PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := NIL): int; PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; Index: cygwin/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v retrieving revision 1.12 diff -u -r1.12 Usysdep.i3 --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -28,7 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *) - pthread_attr_t = ADDRESS; (* opaque *) pthread_mutex_t = ADDRESS; (* opaque *) pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) Index: darwin-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,v retrieving revision 1.2 diff -u -r1.2 Usysdep.i3 --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -20,7 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *) - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) Index: freebsd-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,v retrieving revision 1.5 diff -u -r1.5 Usysdep.i3 --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -22,7 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = ADDRESS; pthread_mutex_t = ADDRESS; pthread_cond_t = ADDRESS; pthread_key_t = int; Index: hpux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/Usysdep.i3,v retrieving revision 1.4 diff -u -r1.4 Usysdep.i3 --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -25,7 +25,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) pthread_key_t = int32_t; (* opaque *) Index: linux-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,v retrieving revision 1.10 diff -u -r1.10 Usysdep.i3 --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -21,7 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; - pthread_attr_t = Upthreadtypes.pthread_attr_t; pthread_mutex_t = Upthreadtypes.pthread_mutex_t; pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; Index: solaris-common/Usysdep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,v retrieving revision 1.3 diff -u -r1.3 Usysdep.i3 --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 @@ -24,7 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *) - pthread_attr_t = int32_t; (* opaque *) pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) From hosking at cs.purdue.edu Wed Feb 4 11:24:19 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Wed, 4 Feb 2009 21:24:19 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: Message-ID: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> ok On 4 Feb 2009, at 21:14, Jay wrote: > > The following eliminates the only use of pthread_attr_t from the > cloned headers, slightly reducing the work to port to new platforms. > It introduces a "small" "portable" C wrapper to encompass the files > lines of Modula-3 that use pthread_attr_t. ok? > > > Index: ThreadPThread.m3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThread.m3,v > retrieving revision 1.89 > diff -u -r1.89 ThreadPThread.m3 > --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 > +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 > @@ -11,11 +11,10 @@ > Unix, Utime, Word, Upthread, Usched, > Uerror, ThreadPThreadC, Uexec; > FROM Upthread > -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, > pthread_mutex_t, > +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, > PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; > FROM Compiler IMPORT ThisFile, ThisLine; > FROM Ctypes IMPORT int; > -FROM Utypes IMPORT size_t; > FROM ThreadPThreadC IMPORT SIG_SUSPEND; > > (*----------------------------------------------------- types and > globals ---*) > @@ -561,9 +560,7 @@ > VAR > act := NEW(Activation); > t := CreateT(act); > - attr: pthread_attr_t; > size := defaultStackSize; > - bytes: size_t; > BEGIN > (* determine the initial size of the stack for this thread *) > TYPECASE closure OF > @@ -576,17 +573,12 @@ > t.id := nextId; INC(nextId); > IF perfOn THEN PerfChanged(t.id, State.alive) END; > > - WITH r = Upthread.attr_init(attr) DO END; > - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; > - bytes := MAX(bytes, size * ADRSIZE(Word.T)); > - EVAL Upthread.attr_setstacksize(attr, bytes); > act.next := allThreads; > act.prev := allThreads.prev; > act.size := size; > allThreads.prev.next := act; > allThreads.prev := act; > - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO > - EVAL Upthread.attr_destroy(attr); > + WITH r = ThreadPThreadC.thread_create(act.handle, size * > ADRSIZE(Word.T), ThreadBase, act) DO > IF r # 0 THEN > RTError.MsgI(ThisFile(), ThisLine(), > "Thread client error: Fork failed with error: > ", r); > Index: ThreadPThreadC.c > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.c,v > retrieving revision 1.8 > diff -u -r1.8 ThreadPThreadC.c > --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 > +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 > @@ -14,6 +14,7 @@ > #include > #include > #endif > +#include > > #ifdef __cplusplus > extern "C" { > @@ -145,6 +146,32 @@ > #endif > } > > +#define VAR(t) t* > +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) > +typedef void* (*start_routine_t)(void*); > + > +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t > stackSize, start_routine_t start_routine, void* arg) > +{ > + int r; > + size_t bytes; > + pthread_attr_t attr; > + > + r = pthread_attr_init(&attr); > + assert(r == 0); > + > + r = pthread_attr_getstacksize(&attr, &bytes); > + assert(r == 0); > + > + bytes = MAX(bytes, stackSize); > + pthread_attr_setstacksize(&attr, bytes); > + > + r = pthread_create(pthread, &attr, start_routine, arg); > + > + pthread_attr_destroy(&attr); > + > + return r; > +} > + > #ifdef __cplusplus > } /* extern "C" */ > #endif > Index: ThreadPThreadC.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ > ThreadPThreadC.i3,v > retrieving revision 1.5 > diff -u -r1.5 ThreadPThreadC.i3 > --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 > +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 > @@ -7,6 +7,8 @@ > UNSAFE INTERFACE ThreadPThreadC; > > FROM Ctypes IMPORT int; > +FROM Cstddef IMPORT size_t; > +FROM Upthread IMPORT pthread_t, start_routine_t; > > (*---------------------------------------------------------------------------*) > > @@ -38,4 +40,11 @@ > > (*---------------------------------------------------------------------------*) > > +(* pthread_create but replace attr with stackSize so that attr need > not be known to Modula-3 *) > + > + > +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; > start_routine: start_routine_t; arg: ADDRESS): int; > + > + > (*---------------------------------------------------------------------------*) > + > END ThreadPThreadC. > > > > > > The corrolary then, ignoring the "cloned headers" that I leave > alone, is: > > > Index: Common/Upthread.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v > retrieving revision 1.3 > diff -u -r1.3 Upthread.i3 > --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 > +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 > @@ -10,7 +10,6 @@ > > TYPE > pthread_t = Usysdep.pthread_t; > - pthread_attr_t = Usysdep.pthread_attr_t; > pthread_mutex_t = Usysdep.pthread_mutex_t; > pthread_cond_t = Usysdep.pthread_cond_t; > pthread_key_t = Usysdep.pthread_key_t; > @@ -21,14 +20,9 @@ > VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; > VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; > > - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: > pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; > PROCEDURE detach (thread: pthread_t): int; > PROCEDURE self (): pthread_t; > PROCEDURE equal (t1, t2: pthread_t): int; > - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; > - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR > stacksize: size_t): int; > - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: > size_t): int; > PROCEDURE yield (): int; > PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := > NIL): int; > PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; > Index: cygwin/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v > retrieving revision 1.12 > diff -u -r1.12 Usysdep.i3 > --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 > +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -28,7 +28,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; (* opaque *) > - pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > Index: darwin-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ > Usysdep.i3,v > retrieving revision 1.2 > diff -u -r1.2 Usysdep.i3 > --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 > +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -20,7 +20,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = INTEGER; (* opaque *) > - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > Index: freebsd-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ > Usysdep.i3,v > retrieving revision 1.5 > diff -u -r1.5 Usysdep.i3 > --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 > +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -22,7 +22,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > Index: hpux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ > Usysdep.i3,v > retrieving revision 1.4 > diff -u -r1.4 Usysdep.i3 > --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 > +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -25,7 +25,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] > OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF > INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > Index: linux-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ > Usysdep.i3,v > retrieving revision 1.10 > diff -u -r1.10 Usysdep.i3 > --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 > +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -21,7 +21,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = ADDRESS; > - pthread_attr_t = Upthreadtypes.pthread_attr_t; > pthread_mutex_t = Upthreadtypes.pthread_mutex_t; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > Index: solaris-common/Usysdep.i3 > =================================================================== > RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ > Usysdep.i3,v > retrieving revision 1.3 > diff -u -r1.3 Usysdep.i3 > --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 > +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 > @@ -24,7 +24,6 @@ > (* INTERFACE Upthread; *) > > pthread_t = int32_t; (* opaque *) > - pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; > (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* > 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) From wagner at elegosoft.com Wed Feb 4 17:38:11 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Wed, 04 Feb 2009 17:38:11 +0100 Subject: [M3devel] opencm3 favicon In-Reply-To: <498910C5.6050902@bellsouth.net> References: <498910C5.6050902@bellsouth.net> Message-ID: <20090204173811.6g9osjhs4go8sokw@mail.elegosoft.com> Quoting Martin Bishop : > A little off-topic maybe, but I though opencm3.net needed a favicon. > > I made 2 different ones: > > http://mbishop.esoteriq.org/mod3.ico - My favorite, the sideways blue > square with a white 3, nice and simple. > > http://mbishop.esoteriq.org/mod3gen.ico - This one was generated by > giving the Modula-3 logo to some online favicon generator. Same as the > first one really, only "zoomed in" looking. > > Feel free to use either one if you want. If there are no objections or strong feelings about this or one or the other icon, we can simply place one (the first?) onto our web server. I'd suggest to wait for replies one more day, and then Mike can install it. So speak up now, or be silent forever :-) Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Wed Feb 4 23:01:58 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:01:58 +0000 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html can fail for lack of memory. The use should probably be modified somewhat therefore. e.g. at least: C code: r = pthread_attr_init(...) if (r == ENOMEM) return r; assert(r == 0); Modula-3 code: r = ... IF r = Cerrno.ENOMEM raise out of memory or more generally probably: C: r = pthread_attr_init(...) if (r != 0) return r; Modula-3: r = ... IF r # 0 raise it as is done for errno, whatever or even C: void thread_create(...) { r = pthread_attr_init(...) if (r != 0) raise it as errno, whatever just that I'm a little leary of "certain Modula-3 constructs in C". I'll maybe review more code along these lines. I gather the general gist of things in Modula-3 though is that out of memory is fatal anyway. Raising an exception vs. failing an assertion probably not significantly different if the exception is not meant to be caught and isn't ever caught. (Strange though then the gymnastics I pointed out elsewhere converting one form of out of memory to another form..) The docs also point out that pthread_attr can be reused. It might be reasonable to try to do that somewhat, though of course there are the usual caveats: - how many reusable objects to keep around I suggest 1, for the common case of either using the default or repeatedly using the same non-default. - how to lookup, insert, delete in the cache, in an efficient and thread-safe manner cache size = 1 helps, but doesn't address all questions. I'll leave it alone, unless someone "vehemently agrees". Expect the original change fairly soon.. - Jay ---------------------------------------- > From: hosking at cs.purdue.edu > To: jay.krell at cornell.edu > Date: Wed, 4 Feb 2009 21:24:19 +1100 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers > > ok > > On 4 Feb 2009, at 21:14, Jay wrote: > >> >> The following eliminates the only use of pthread_attr_t from the >> cloned headers, slightly reducing the work to port to new platforms. >> It introduces a "small" "portable" C wrapper to encompass the files >> lines of Modula-3 that use pthread_attr_t. ok? >> >> >> Index: ThreadPThread.m3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThread.m3,v >> retrieving revision 1.89 >> diff -u -r1.89 ThreadPThread.m3 >> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >> @@ -11,11 +11,10 @@ >> Unix, Utime, Word, Upthread, Usched, >> Uerror, ThreadPThreadC, Uexec; >> FROM Upthread >> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >> pthread_mutex_t, >> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >> FROM Compiler IMPORT ThisFile, ThisLine; >> FROM Ctypes IMPORT int; >> -FROM Utypes IMPORT size_t; >> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >> >> (*----------------------------------------------------- types and >> globals ---*) >> @@ -561,9 +560,7 @@ >> VAR >> act := NEW(Activation); >> t := CreateT(act); >> - attr: pthread_attr_t; >> size := defaultStackSize; >> - bytes: size_t; >> BEGIN >> (* determine the initial size of the stack for this thread *) >> TYPECASE closure OF >> @@ -576,17 +573,12 @@ >> t.id := nextId; INC(nextId); >> IF perfOn THEN PerfChanged(t.id, State.alive) END; >> >> - WITH r = Upthread.attr_init(attr) DO END; >> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >> - EVAL Upthread.attr_setstacksize(attr, bytes); >> act.next := allThreads; >> act.prev := allThreads.prev; >> act.size := size; >> allThreads.prev.next := act; >> allThreads.prev := act; >> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >> - EVAL Upthread.attr_destroy(attr); >> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >> ADRSIZE(Word.T), ThreadBase, act) DO >> IF r # 0 THEN >> RTError.MsgI(ThisFile(), ThisLine(), >> "Thread client error: Fork failed with error: >> ", r); >> Index: ThreadPThreadC.c >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.c,v >> retrieving revision 1.8 >> diff -u -r1.8 ThreadPThreadC.c >> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >> @@ -14,6 +14,7 @@ >> #include >> #include >> #endif >> +#include >> >> #ifdef __cplusplus >> extern "C" { >> @@ -145,6 +146,32 @@ >> #endif >> } >> >> +#define VAR(t) t* >> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >> +typedef void* (*start_routine_t)(void*); >> + >> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >> stackSize, start_routine_t start_routine, void* arg) >> +{ >> + int r; >> + size_t bytes; >> + pthread_attr_t attr; >> + >> + r = pthread_attr_init(&attr); >> + assert(r == 0); >> + >> + r = pthread_attr_getstacksize(&attr, &bytes); >> + assert(r == 0); >> + >> + bytes = MAX(bytes, stackSize); >> + pthread_attr_setstacksize(&attr, bytes); >> + >> + r = pthread_create(pthread, &attr, start_routine, arg); >> + >> + pthread_attr_destroy(&attr); >> + >> + return r; >> +} >> + >> #ifdef __cplusplus >> } /* extern "C" */ >> #endif >> Index: ThreadPThreadC.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >> ThreadPThreadC.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 ThreadPThreadC.i3 >> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >> @@ -7,6 +7,8 @@ >> UNSAFE INTERFACE ThreadPThreadC; >> >> FROM Ctypes IMPORT int; >> +FROM Cstddef IMPORT size_t; >> +FROM Upthread IMPORT pthread_t, start_routine_t; >> >> (*---------------------------------------------------------------------------*) >> >> @@ -38,4 +40,11 @@ >> >> (*---------------------------------------------------------------------------*) >> >> +(* pthread_create but replace attr with stackSize so that attr need >> not be known to Modula-3 *) >> + >> + >> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >> start_routine: start_routine_t; arg: ADDRESS): int; >> + >> + >> (*---------------------------------------------------------------------------*) >> + >> END ThreadPThreadC. >> >> >> >> >> >> The corrolary then, ignoring the "cloned headers" that I leave >> alone, is: >> >> >> Index: Common/Upthread.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Upthread.i3 >> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >> @@ -10,7 +10,6 @@ >> >> TYPE >> pthread_t = Usysdep.pthread_t; >> - pthread_attr_t = Usysdep.pthread_attr_t; >> pthread_mutex_t = Usysdep.pthread_mutex_t; >> pthread_cond_t = Usysdep.pthread_cond_t; >> pthread_key_t = Usysdep.pthread_key_t; >> @@ -21,14 +20,9 @@ >> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >> >> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >> PROCEDURE detach (thread: pthread_t): int; >> PROCEDURE self (): pthread_t; >> PROCEDURE equal (t1, t2: pthread_t): int; >> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >> stacksize: size_t): int; >> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >> size_t): int; >> PROCEDURE yield (): int; >> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >> NIL): int; >> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >> Index: cygwin/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >> retrieving revision 1.12 >> diff -u -r1.12 Usysdep.i3 >> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -28,7 +28,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; (* opaque *) >> - pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> Index: darwin-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >> Usysdep.i3,v >> retrieving revision 1.2 >> diff -u -r1.2 Usysdep.i3 >> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -20,7 +20,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = INTEGER; (* opaque *) >> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> Index: freebsd-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >> Usysdep.i3,v >> retrieving revision 1.5 >> diff -u -r1.5 Usysdep.i3 >> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -22,7 +22,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> Index: hpux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >> Usysdep.i3,v >> retrieving revision 1.4 >> diff -u -r1.4 Usysdep.i3 >> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -25,7 +25,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> Index: linux-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >> Usysdep.i3,v >> retrieving revision 1.10 >> diff -u -r1.10 Usysdep.i3 >> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -21,7 +21,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = ADDRESS; >> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> Index: solaris-common/Usysdep.i3 >> =================================================================== >> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >> Usysdep.i3,v >> retrieving revision 1.3 >> diff -u -r1.3 Usysdep.i3 >> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >> @@ -24,7 +24,6 @@ >> (* INTERFACE Upthread; *) >> >> pthread_t = int32_t; (* opaque *) >> - pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >> (* 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >> 16 bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) > From jay.krell at cornell.edu Wed Feb 4 23:11:52 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 4 Feb 2009 22:11:52 +0000 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. The entire proposal or the optimizations? The original unoptimized proposal seems like a small change mostly. I checked and the indirection/heap allocation is already there for cond and mutex, but not for pthread_t itself. Factoring out the size I think is a small change. On the other hand, we can also optimize it, pretty much locking in the platform-specificity. It's a tough decision to me. I don't mind the deoptimizations of const-to-var, or adding some function calls, but heap allocs imho are among the things to definitely avoid if not needed. These are untraced as well, so the argument that Modula-3 heap alloc is efficient doesn't apply. One caveat that bothers me though is, like with sem_t, I don't want to have types that are declared "incorrectly". I'd like types that you can only have references too. Probably in that case "give up", declare them as ADDRESS, losing the type safety -- pthread_cond_foo could take a mutex_t and no compilation error. The idea of making them all ADDRESS and adding C functions to alloc/cleanup is also good imho. That allows for one of the optimized forms -- not where the space is at the end of the Thread.T, but where the ADDRESS field is the data itself. I got hung up on pthread_attr_t here because it was efficiently stack allocated and this proposal would have really deoptimized that. The C code I showed avoids that though. Albeit only in the face of creating a thread -- an extra heap allocation per thread create probably not a big deal. Clearly I'm ambivalent. Later, - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: hosking at cs.purdue.edu > Date: Wed, 4 Feb 2009 09:42:12 +0000 > CC: m3devel at elegosoft.com > Subject: Re: [M3devel] further reducing cloned headers wrt pthread? > > > It gains something, but maybe it isn't enough > to be worthwhile. The issue is in the subjectivity. > > > It would remove e.g. the following system-dependent lines: > > > Linux: > pthread_t = ADDRESS; > pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; > pthread_key_t = uint32_t; > > > Linux/32: > pthread_attr_t = ARRAY[1..9] OF INTEGER; > pthread_mutex_t = ARRAY[1..6] OF INTEGER; > > > Linux/64: > pthread_attr_t = ARRAY[1..7] OF INTEGER; > pthread_mutex_t = ARRAY[1..5] OF INTEGER; > > > FreeBSD: > pthread_t = ADDRESS; > pthread_attr_t = ADDRESS; > pthread_mutex_t = ADDRESS; > pthread_cond_t = ADDRESS; > pthread_key_t = int; > > > HP-UX: > (* trick from darwin-generic/Upthread.i3 *) > X32 = ORD(BITSIZE(INTEGER) = 32); > X64 = ORD(BITSIZE(INTEGER) = 64); > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF INTEGER; END; (* 56 opaque bytes with size_t alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Cygwin: > pthread_t = ADDRESS; (* opaque *) > pthread_attr_t = ADDRESS; (* opaque *) > pthread_mutex_t = ADDRESS; (* opaque *) > pthread_cond_t = ADDRESS; (* opaque *) > pthread_key_t = ADDRESS; (* opaque *) > > > Solaris: > pthread_t = int32_t; (* opaque *) > pthread_attr_t = int32_t; (* opaque *) > pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *) > pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) > pthread_key_t = int32_t; (* opaque *) > > > Darwin: (only ppc32 currently) > pthread_t = INTEGER; (* opaque *) > pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; > pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; > pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; > pthread_key_t = INTEGER; (* opaque *) > > > (plus AIX, Irix, VMS, Tru64.) > > > Another approach would be make them all ADDRESS and introduce a portable > C layer of "varything thickness", using the same logic. > It would look just like the native pthreads, but there'd be extra allocate/cleanup > calls -- to do the heap alloc/cleanup when the underlying types are larger than addresses. > The two layers would be clear and simple, the cost would be the same, > but there would be the conceptual cost of two simple layers instead of one > just one slightly complicated layer. > > > Another approach is maybe make them all addresses on new platforms and introduce > the C layer only on new platforms. Again, about the only change in the Modula-3 > code is extra alloc/cleanup calls. > > > And again, some/all of the code already has the indirection/heap allocation unconditionally. > > > And again, maybe not worth it. I show all the system-dependent code, attempting > to portray in its worst light by showing all of it, but maybe it's really not a lot. > > > For the attr type, we can do something specific to its use. > There is just one use, and we can address it with the following function written in C.. > eh..I'll send a diff later tonight/this week I think. > > > pthread_t and pthread_key_t always happen to be address-sized or smaller. > Maybe just declare them both to be address and assert their size in some C code. > That might waste a few bytes esp. on 64 bit platforms, or it might merely fill in the padding-for-alignment. > > For example, we have: > > > TYPE > Activation = UNTRACED REF RECORD > (* global doubly-linked, circular list of all active threads *) > next, prev: Activation := NIL; (* LL = activeMu *) > (* thread handle *) > handle: pthread_t; (* LL = activeMu *) > (* base of thread stack for use by GC *) > stackbase: ADDRESS := NIL; (* LL = activeMu *) > > > so on 64 bit platforms where pthread_t is a 32bit integer, it is taking up 64 bits anyway. > There are two static pthread_key_ts, so making them address would waste 8 bytes on some/many 64bit platforms. > > > Leaving only cond and mutex. > Some of the platforms declare more types such as rwlock, rwlockattr, but they are never used. > rwlock is a useful type though. > > > - Jay > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 12:53:54 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> I am very leery of this proposal -- the code will be inherently opaque >> and unmaintainable. I don't see any advantage to it. >> >> On 4 Feb 2009, at 11:06, Jay wrote: >> >>> >>> There are a few possibilities: >>> >>> >>> Roughly: >>> >>> Where there is >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = ... system specific ... >>> pthread_cond_t = ... system specific ... >>> pthread_mutex_t = ... system specific ... >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> MODULE PThread; >>> VAR >>> a: pthread_t; >>> b: pthread_cond_t; >>> c: pthread_mutex_t; >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> change to: >>> >>> INTERFACE Upthread; >>> >>> TYPE >>> pthread_t = RECORD END; or whatever is correct for an opaque >>> preferably unique type >>> pthread_cond_t = RECORD END; ditto >>> pthread_mutex_t = RECORD END; ditto >>> >>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>> >>> >>> INTERFACE PThreadC.i3 >>> >>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>> >>> or possibly extern VAR >>> >>> PThreadC.c >>> >>> static pthread_t a = PTHREAD_INIT; >>> static pthread_cond_t b = PTHREAD_COND_INIT; >>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>> >>> pthread_t* GetA() { return &a; } >>> >>> pthread_cond_t* GetB() { return &b; } >>> >>> pthread_mutex_t* GetC() { return &c; } >>> >>> MODULE PThread; >>> VAR >>> a := PThreadC.GetA(); >>> b := PThreadC.GetB(); >>> c := PThreadC.GetA(); >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a^); >>> Upthread.pthread_cond_init_or_whatever(b^); >>> Upthread.pthread_mutex_init_or_whatever(c^); >>> END Foo; >>> >>> or, again, possibly they are variables and it goes a little smaller/ >>> quicker: >>> >>> FROM UPthreadC IMPORT a, b, c; >>> >>> >>> PROCEDURE Foo() = >>> BEGIN >>> Upthread.pthread_thread_init_or_whatever(a); >>> Upthread.pthread_cond_init_or_whatever(b); >>> Upthread.pthread_mutex_init_or_whatever(c); >>> END Foo; >>> >>> I think that is pretty cut and dry, no controversy. >>> >>> What is less clear is what to do with non-statically allocated >>> variables. >>> >>> Let's say: >>> >>> MODULE PThread; >>> >>> TYPE T = RECORD >>> a:int; >>> b:pthread_t; >>> END; >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T) >>> BEGIN >>> Upthread.init_or_whatever(t.b); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b); >>> DISPOSE(t); >>> END; >>> >>> The desire is something that does not know the size of pthread_t, >>> something like: >>> >>> TYPE T = RECORD >>> a:int; >>> b:UNTRACED REF pthread_t; >>> END; >>> >>> >>> PROCEDURE CreateT():T= >>> VAR >>> t := NEW(T); >>> BEGIN >>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>> CHAR, Upthread.pthread_t_size)); >>> (* Though I really wanted t.b := >>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> PROCEDURE DisposeT(t:T)= >>> BEGIN >>> IF t = NIL THEN RETURN END; >>> Upthread.pthread_cleanup_or_whatever(t.b^); >>> DISPOSE(t.b); >>> DISPOSE(t); >>> END; >>> >>> >>> However that incurs an extra heap allocation, which is not great. >>> In at least one place, the pointer-indirection-and-heap-allocation >>> is already there >>> so this isn't a deoptimization. However "reoptimizing" it might be >>> nice. >>> >>> >>> What I would prefer a pattern I often use in C -- merging >>> allocations, something like, >>> /assuming/ t is untraced, which I grant it might not be. >>> >>> >>> And ensuring that BYTESIZE(T) is properly aligned: >>> >>> >>> PROCEDURE CreateT():UNTRACED REF T= >>> VAR >>> p : ADDRESS; >>> t : UNTRACED REF T; >>> BEGIN >>> (* Again I would prefer RTAllocator.MallocZeroed *) >>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>> BYTESIZE(T))); >>> t := LOOPHOLE(UNTRACED REF T, p); >>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>> Upthread.init_or_whatever(t.b^); >>> RETURN t; >>> END; >>> >>> >>> That is -- opaque types, size not known at compile-time, but size >>> known at runtime, and >>> do not incur an extra heap allocation for lack of knowing sizes at >>> compile-time. >>> >>> >>> For the statically allocated variables I think there is no >>> controversy. >>> There might a tiny bit of overhead in the use, but it'd be very >>> small, and possibly >>> even removable in the future. I'd rather avoid the variables, as >>> all writable >>> data is to be avoided. Read only pages are better and all that, >>> but ok.. >>> >>> >>> However the value is mainly realized only if statically and >>> dynamically allocated variables are handled. >>> >>> The result of this would be further reduction in platform- >>> specificity when cloning >>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>> platforms. >>> >>> >>> - Jay >>> >>> >>> ---------------------------------------- >>>> From: hosking at cs.purdue.edu >>>> To: jay.krell at cornell.edu >>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>> CC: m3devel at elegosoft.com >>>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>>> >>>> I suggest you come up with a proposal for us to look over before you >>>> change the code base for this. >>>> >>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>> >>>>> >>>>>> Hmm, yes, you are right that there is a possible alignment issue. I >>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>> in C >>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>> alignment padding anyway so as to allow allocation using >>>>>> malloc(sizeof >>>>>> pthread_mutex_t)? So, it all should just work right? >>>>> >>>>> >>>>> I think "the other way around" and same conclusion. >>>>> malloc should return something "maximally aligned" so that >>>>> >>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>> malloc(sizeof(pthread_mutex_t)); >>>>> >>>>> >>>>> works. pthread_mutex_t doesn't need the padding, malloc does, so to >>>>> speak. >>>>> >>>>> >>>>> Just as long as we don't have >>>>> >>>>> >>>>> TYPE Foo = RECORD >>>>> a: pthread_mutex_t; >>>>> b: pthread_mutex_t; >>>>> c: pthread_t; >>>>> d: pthread_t; >>>>> e: pthread_cond_t; >>>>> f: pthread_cond_t; >>>>> END; >>>>> >>>>> >>>>> and such, ok. >>>>> >>>>> >>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>> I think on Win9x only 4 alignment, thus there is _malloc_aligned for >>>>> dealing with SSE stuff. >>>>> Something like that. >>>>> >>>>> >>>>> I didn't realize untraced allocations were basically just malloc but >>>>> indeed they are. >>>>> >>>>> >>>>> I'm still mulling over the possible deoptimizations here. >>>>> I'm reluctant to increase heap allocations. >>>>> >>>>> >>>>> >>>>> - Jay >>>> >> From hosking at cs.purdue.edu Thu Feb 5 00:12:18 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:12:18 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: References: <6A532E6E-2379-4502-842E-00F1133C3307@cs.purdue.edu> Message-ID: I don't mind if low-level C calls abort rather than raising an exception. Especially, OutOfMemory, which it is unlikely one can recover from with an untraced allocation, unless perhaps a GC can be called to free up space. However, right now, the GC does not return pages to the OS, so the whole question is moot for now. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 On 5 Feb 2009, at 09:01, Jay wrote: > > http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_attr_init.html > > > can fail for lack of memory. > > > The use should probably be modified somewhat therefore. > > > e.g. at least: > > > C code: > > > r = pthread_attr_init(...) > if (r == ENOMEM) > return r; > assert(r == 0); > > > Modula-3 code: > r = ... > IF r = Cerrno.ENOMEM > raise out of memory > > > or more generally probably: > > > C: > > > r = pthread_attr_init(...) > if (r != 0) > return r; > > > Modula-3: > r = ... > IF r # 0 > raise it as is done for errno, whatever > > > or even C: > > > void thread_create(...) > { > r = pthread_attr_init(...) > if (r != 0) > raise it as errno, whatever > > > just that I'm a little leary of "certain Modula-3 constructs in C". > > > I'll maybe review more code along these lines. > I gather the general gist of things in Modula-3 though > is that out of memory is fatal anyway. Raising an exception > vs. failing an assertion probably not significantly different > if the exception is not meant to be caught and isn't ever caught. > (Strange though then the gymnastics I pointed out elsewhere > converting one form of out of memory to another form..) > > > The docs also point out that pthread_attr can be reused. > It might be reasonable to try to do that somewhat, though > of course there are the usual caveats: > > > - how many reusable objects to keep around > I suggest 1, for the common case of either using the default > or repeatedly using the same non-default. > - how to lookup, insert, delete in the cache, in an efficient > and thread-safe manner > cache size = 1 helps, but doesn't address all questions. > > > I'll leave it alone, unless someone "vehemently agrees". > > > Expect the original change fairly soon.. > > > - Jay > > > > > > > > > > > ---------------------------------------- >> From: hosking at cs.purdue.edu >> To: jay.krell at cornell.edu >> Date: Wed, 4 Feb 2009 21:24:19 +1100 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] elminating pthread_attr_t from cloned headers >> >> ok >> >> On 4 Feb 2009, at 21:14, Jay wrote: >> >>> >>> The following eliminates the only use of pthread_attr_t from the >>> cloned headers, slightly reducing the work to port to new platforms. >>> It introduces a "small" "portable" C wrapper to encompass the files >>> lines of Modula-3 that use pthread_attr_t. ok? >>> >>> >>> Index: ThreadPThread.m3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThread.m3,v >>> retrieving revision 1.89 >>> diff -u -r1.89 ThreadPThread.m3 >>> --- ThreadPThread.m3 21 Jan 2009 15:25:03 -0000 1.89 >>> +++ ThreadPThread.m3 4 Feb 2009 10:07:59 -0000 >>> @@ -11,11 +11,10 @@ >>> Unix, Utime, Word, Upthread, Usched, >>> Uerror, ThreadPThreadC, Uexec; >>> FROM Upthread >>> -IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_attr_t, >>> pthread_mutex_t, >>> +IMPORT pthread_t, pthread_cond_t, pthread_key_t, pthread_mutex_t, >>> PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER; >>> FROM Compiler IMPORT ThisFile, ThisLine; >>> FROM Ctypes IMPORT int; >>> -FROM Utypes IMPORT size_t; >>> FROM ThreadPThreadC IMPORT SIG_SUSPEND; >>> >>> (*----------------------------------------------------- types and >>> globals ---*) >>> @@ -561,9 +560,7 @@ >>> VAR >>> act := NEW(Activation); >>> t := CreateT(act); >>> - attr: pthread_attr_t; >>> size := defaultStackSize; >>> - bytes: size_t; >>> BEGIN >>> (* determine the initial size of the stack for this thread *) >>> TYPECASE closure OF >>> @@ -576,17 +573,12 @@ >>> t.id := nextId; INC(nextId); >>> IF perfOn THEN PerfChanged(t.id, State.alive) END; >>> >>> - WITH r = Upthread.attr_init(attr) DO END; >>> - WITH r = Upthread.attr_getstacksize(attr, bytes) DO END; >>> - bytes := MAX(bytes, size * ADRSIZE(Word.T)); >>> - EVAL Upthread.attr_setstacksize(attr, bytes); >>> act.next := allThreads; >>> act.prev := allThreads.prev; >>> act.size := size; >>> allThreads.prev.next := act; >>> allThreads.prev := act; >>> - WITH r = Upthread.create(act.handle, attr, ThreadBase, act) DO >>> - EVAL Upthread.attr_destroy(attr); >>> + WITH r = ThreadPThreadC.thread_create(act.handle, size * >>> ADRSIZE(Word.T), ThreadBase, act) DO >>> IF r # 0 THEN >>> RTError.MsgI(ThisFile(), ThisLine(), >>> "Thread client error: Fork failed with error: >>> ", r); >>> Index: ThreadPThreadC.c >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.c,v >>> retrieving revision 1.8 >>> diff -u -r1.8 ThreadPThreadC.c >>> --- ThreadPThreadC.c 21 Jan 2009 15:25:03 -0000 1.8 >>> +++ ThreadPThreadC.c 4 Feb 2009 10:07:59 -0000 >>> @@ -14,6 +14,7 @@ >>> #include >>> #include >>> #endif >>> +#include >>> >>> #ifdef __cplusplus >>> extern "C" { >>> @@ -145,6 +146,32 @@ >>> #endif >>> } >>> >>> +#define VAR(t) t* >>> +#define MAX(x, y) (((x)> (y)) ? (x) : (y)) >>> +typedef void* (*start_routine_t)(void*); >>> + >>> +int ThreadPThreadC_thread_create(VAR(pthread_t) pthread, size_t >>> stackSize, start_routine_t start_routine, void* arg) >>> +{ >>> + int r; >>> + size_t bytes; >>> + pthread_attr_t attr; >>> + >>> + r = pthread_attr_init(&attr); >>> + assert(r == 0); >>> + >>> + r = pthread_attr_getstacksize(&attr, &bytes); >>> + assert(r == 0); >>> + >>> + bytes = MAX(bytes, stackSize); >>> + pthread_attr_setstacksize(&attr, bytes); >>> + >>> + r = pthread_create(pthread, &attr, start_routine, arg); >>> + >>> + pthread_attr_destroy(&attr); >>> + >>> + return r; >>> +} >>> + >>> #ifdef __cplusplus >>> } /* extern "C" */ >>> #endif >>> Index: ThreadPThreadC.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ >>> ThreadPThreadC.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 ThreadPThreadC.i3 >>> --- ThreadPThreadC.i3 21 Jan 2009 15:25:03 -0000 1.5 >>> +++ ThreadPThreadC.i3 4 Feb 2009 10:07:59 -0000 >>> @@ -7,6 +7,8 @@ >>> UNSAFE INTERFACE ThreadPThreadC; >>> >>> FROM Ctypes IMPORT int; >>> +FROM Cstddef IMPORT size_t; >>> +FROM Upthread IMPORT pthread_t, start_routine_t; >>> >>> (*---------------------------------------------------------------------------*) >>> >>> @@ -38,4 +40,11 @@ >>> >>> (*---------------------------------------------------------------------------*) >>> >>> +(* pthread_create but replace attr with stackSize so that attr need >>> not be known to Modula-3 *) >>> + >>> + >>> +PROCEDURE thread_create(VAR pthread: pthread_t; stackSize: size_t; >>> start_routine: start_routine_t; arg: ADDRESS): int; >>> + >>> + >>> (*---------------------------------------------------------------------------*) >>> + >>> END ThreadPThreadC. >>> >>> >>> >>> >>> >>> The corrolary then, ignoring the "cloned headers" that I leave >>> alone, is: >>> >>> >>> Index: Common/Upthread.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Upthread.i3 >>> --- Common/Upthread.i3 19 Jan 2009 15:57:20 -0000 1.3 >>> +++ Common/Upthread.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -10,7 +10,6 @@ >>> >>> TYPE >>> pthread_t = Usysdep.pthread_t; >>> - pthread_attr_t = Usysdep.pthread_attr_t; >>> pthread_mutex_t = Usysdep.pthread_mutex_t; >>> pthread_cond_t = Usysdep.pthread_cond_t; >>> pthread_key_t = Usysdep.pthread_key_t; >>> @@ -21,14 +20,9 @@ >>> VAR PTHREAD_MUTEX_INITIALIZER : pthread_mutex_t; >>> VAR PTHREAD_COND_INITIALIZER : pthread_cond_t; >>> >>> - PROCEDURE create (VAR pthread: pthread_t; READONLY attr: >>> pthread_attr_t; start_routine: start_routine_t; arg: ADDRESS): int; >>> PROCEDURE detach (thread: pthread_t): int; >>> PROCEDURE self (): pthread_t; >>> PROCEDURE equal (t1, t2: pthread_t): int; >>> - PROCEDURE attr_init (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_destroy (VAR attr: pthread_attr_t): int; >>> - PROCEDURE attr_getstacksize (READONLY attr: pthread_attr_t; VAR >>> stacksize: size_t): int; >>> - PROCEDURE attr_setstacksize (VAR attr: pthread_attr_t; stacksize: >>> size_t): int; >>> PROCEDURE yield (): int; >>> PROCEDURE mutex_init (VAR mutex: pthread_mutex_t; attr: ADDRESS := >>> NIL): int; >>> PROCEDURE mutex_destroy (VAR mutex: pthread_mutex_t): int; >>> Index: cygwin/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v >>> retrieving revision 1.12 >>> diff -u -r1.12 Usysdep.i3 >>> --- cygwin/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.12 >>> +++ cygwin/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -28,7 +28,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; (* opaque *) >>> - pthread_attr_t = ADDRESS; (* opaque *) >>> pthread_mutex_t = ADDRESS; (* opaque *) >>> pthread_cond_t = ADDRESS; (* opaque *) >>> pthread_key_t = ADDRESS; (* opaque *) >>> Index: darwin-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/ >>> Usysdep.i3,v >>> retrieving revision 1.2 >>> diff -u -r1.2 Usysdep.i3 >>> --- darwin-common/Usysdep.i3 29 Jan 2009 07:43:23 -0000 1.2 >>> +++ darwin-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -20,7 +20,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = INTEGER; (* opaque *) >>> - pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >>> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >>> pthread_key_t = INTEGER; (* opaque *) >>> Index: freebsd-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/ >>> Usysdep.i3,v >>> retrieving revision 1.5 >>> diff -u -r1.5 Usysdep.i3 >>> --- freebsd-common/Usysdep.i3 21 Jan 2009 15:25:09 -0000 1.5 >>> +++ freebsd-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -22,7 +22,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = ADDRESS; >>> pthread_mutex_t = ADDRESS; >>> pthread_cond_t = ADDRESS; >>> pthread_key_t = int; >>> Index: hpux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/hpux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.4 >>> diff -u -r1.4 Usysdep.i3 >>> --- hpux-common/Usysdep.i3 21 Jan 2009 15:25:11 -0000 1.4 >>> +++ hpux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -25,7 +25,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] >>> OF INTEGER; END; (* 88 opaque bytes with size_t alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >>> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >>> pthread_key_t = int32_t; (* opaque *) >>> Index: linux-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/ >>> Usysdep.i3,v >>> retrieving revision 1.10 >>> diff -u -r1.10 Usysdep.i3 >>> --- linux-common/Usysdep.i3 21 Jan 2009 15:25:12 -0000 1.10 >>> +++ linux-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -21,7 +21,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = ADDRESS; >>> - pthread_attr_t = Upthreadtypes.pthread_attr_t; >>> pthread_mutex_t = Upthreadtypes.pthread_mutex_t; >>> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >>> pthread_key_t = uint32_t; >>> Index: solaris-common/Usysdep.i3 >>> =================================================================== >>> RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/ >>> Usysdep.i3,v >>> retrieving revision 1.3 >>> diff -u -r1.3 Usysdep.i3 >>> --- solaris-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.3 >>> +++ solaris-common/Usysdep.i3 4 Feb 2009 10:12:18 -0000 >>> @@ -24,7 +24,6 @@ >>> (* INTERFACE Upthread; *) >>> >>> pthread_t = int32_t; (* opaque *) >>> - pthread_attr_t = int32_t; (* opaque *) >>> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; >>> (* 32 bytes with 64 bit alignment *) >>> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* >>> 16 bytes with 64 bit alignment *) >>> pthread_key_t = int32_t; (* opaque *) >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 02:19:58 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 01:19:58 +0000 Subject: [M3devel] cygwin jmp_buf size incorrect In-Reply-To: <495B901F.1E75.00D7.1@scires.com> References: <20081231105208.9CF4710D5DDE@birch.elegosoft.com> <495B4846.1E75.00D7.1@scires.com> <495B901F.1E75.00D7.1@scires.com> Message-ID: > Cygwin's setjmp.h incorrectly typedefs jmp_buf confirmed fyi/fwiw, unfortunate: http://cygwin.com/ml/cygwin/2009-01/msg00863.html - Jay ---------------------------------------- > From: jay.krell at cornell.edu > To: rcoleburn at scires.com; m3devel at elegosoft.com > Subject: RE: [M3devel] [M3commit] CVS Update: cm3 > Date: Thu, 29 Jan 2009 17:10:53 +0000 > > >> In reading your post, you state that you deoptimized the native implementation >> to make it match Cygwin. Now, I'm not sure how > > > I was wrong on this point. > Cygwin's setjmp.h incorrectly typedefs jmp_buf, indeed, to be much larger than "native", but the header is incorrect. Cygwin actually has a slightly smaller jmp_buf than native (13 ints vs. 16 ints), but we use the native size always, deoptimizing the Cygwin case. > > - Jay > > ________________________________ >> Date: Wed, 31 Dec 2008 15:30:40 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> >> >> >> >> >> >> Jay: >> >> >> >> First, I do want to say thanks for all you are doing for the cause of Modula-3. I don't think we say thanks enough for what others do for us. THANK YOU! >> >> >> >> I don't want to be perceived as "complaining", rather I am trying to voice my opinion in the hopes of influencing future direction. Of course, since I'm not doing the work, I can only make suggestions. >> >> >> >> In reading your post, you state that you deoptimized the native implementation to make it match Cygwin. Now, I'm not sure how much effect this deoptimization has (maybe little), but it is clear that in this case your implementation choice has favored the non-native implementation over the native one. IMO, tradeoffs of this type are not good. If one is trying to convince someone to use Modula-3, why would you want to give them a "deoptimized" version just to make it easier to support a non-native environment---indeed, one that they may not even want/use? If we have to make a trade-off, I say favor the native implementation always over the non-native one. >> >> >> >> What I'm trying to say here is that my experience as a software, systems, and program engineer is that I've always been forced to justify the cost/benefit of development tools for any project. Many times I've had to go head to head with folks higher up in my own organization or in the customer's organization whose preconceived opinions were based on rumor and what they've heard rather than actual factual hands-on experience. I want to pick the best tool for the job instead of being forced to pick an inferior tool because someone higher in the food chain demanded it based on faulty preconceived opinion. I like Modula-3. I've found that I am more productive using it. But, if the compiler doesn't produce efficient code, I lose ground in arguing with the higher-ups. >> >> >> >> As for Python, I've never ventured to learn it, so for me, it is something of a mystery. But you miss the point. I'm not arguing the merits of Python, I'm just saying that anything Modula-3 requires on top of what is provided by the standard host platform represents a potential obstacle or barrier to ease of use/implementation. It also sends the message that somehow Modula-3 is not complete on its own, we have get Python just to install and oh yes we need a C compiler and a linker and a ...? IMO, ultimately we need a turn-key download and install routine for Modula-3 that just works, out-of-the-box. If you give me an EXE, a CMD, or a BAT, for the install, I can run it on Windows, but if you give me an install routine that requires I first install something else, e.g. Python, then that becomes a barrier to the folks who don't know Python or already have it installed. >> >> >> >> Am I alone in this line of thought? If so, I'll just be quiet. >> >> >> >> BTW, I can certainly help in maintaining the CMD/BAT install routines or in making a better CMINSTALL. My problem is that right now, it is hard to understand all the dependencies for proper building of cm3 from scratch. Indeed, I've contributed some CMD/BAT install stuff in the past, but it is now out of date. Perhaps if there is a way we could better document the proper build order and dependencies, it would be easier for folks in the community to help in this area. I certainly would volunteer to do the CMD files as long as I had enough information to do it right. At one point, I thought we had a file that showed the package build order and dependencies. Not sure if the format of this file is well-documented or if the file is kept up-to-date. >> >> >> >> Regards, >> >> Randy >> >> >>>>> Jay 12/31/2008 1:34 PM>>> >>> you've made the CYGWIN implementation "appear" >>> be the same as the native Windows implementation. >>> But they are not the same. >> >> >> But they mostly are, from the front end's point of view. >> They are both little endian, x86, use the same jump_buf size (I grew it to match Cygwin's, which is a deoptimization of stack use on native NT386), the same type sizes and alignments..er..not sure about LONGINT. >> They might vary in newline and one uses the internal backend and one the external, however which backend they use is actually minor to the front end, though I think it affects if the front end "deals with" calling conventions, particularly left-to-right vs. right-to-left and struct returns. >> Object code produced by one can generally be linked with object code produced by the other. >> >> >> SOLgnu and SOLsun are a better example of this, though they do go ahead and duplicate tons of stuff that if I had implemented them, I would have avoided. >> They are truly identical in every respect in the front end and back end. >> They only vary in the config file. >> This is wasteful, because, "by default", if I'm put together a comprehensive cross build system without being a little smarter, I end up building two identical m3cgs. My config files are willing to "probe across" SOLsun and SOLgnu though, so I need only one m3cg for the two of them. >> >> >> Given that "NT386" can describe a combinatorial explosion of configurations, it makes some sense to keep it just one if possible. The compiler mostly doesn't care. >> >> >> >>> "- BUILD_DIR does not necessarily equal HOST or TARGET, >>> because of how I structured I386_CYGWIN to be a "configuration" >>> where TARGET is still NT386." >> >>> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". >> >> BUILD_DIR also does not equal HOST or TARGET when doing profiled builds, which admittedly I never have. >> Therefore, BUILD_DIR is arbitrary. >> I might be confusing something here though -- since I have never built a profiled build, I also haven't shipped one. It could be that "shipped BUILD_DIR" does equal TARGET, for profiled builds, in which case I did set a precedent. But the "override" code isn't using shipped files, so.. >> I have to check. >> >>> as long as it does not compromise the native Windows implementation >> >> Agreed and it basically doesn't. >> Show me where it does. >> The only thing I can think of is the jmpbuf size. >> >>> I don't want to have to install CYGWIN either in order to make >>> the native implementation work on Windows. >> >> Please don't complain about stuff that isn't true or without being more specific. >> I know of no dependency by the native implementation on Cygwin. >> >> In fact, installing Cygwin does tend to break the native implementation, depending on $PATH, because it has a link.exe that is a completely different program (ie: ln.exe). >> I tried experimenting with using cl to drive link.exe but couldn't quite get it to work, for stupid reasons related to response files, which surely is fixable by extending response file support in cm3... >> >> As it is, I usually delete \cygwin\bin\link.exe, or remove cygwin from $PATH. >> True, I don't ever uninstall Cygwin for testing, so the dependency could creep in by accident. >> >> >>> I also still prefer the CMINSTALL, CMD, or BAT files >>> for install as opposed to having to get Python or something else. Just my 2 cents. >> >> Once built and installed, there is no dependency on cmd, bat, cminstall, or python. >> cminstall is pretty worthless imho, as long as you set PATH, INCLUDE, and LIB. >> That is also a competing workaround for paths with spaces. >> And allows moving around among different versions of Visual C++, which is good and bad. >> Either you can have n installs of cm3, each configured tightly for one specific Visual C++, >> or you can have 1 install of cm3, that is flexibly configured, that you "reconfigure" by altering the environment. I do the second. >> >> If you want to build the system, in a well automated way, with cmd and bat, you are welcome to write them. >> Maybe the ones I left in the tree work, but i never use them any longer. >> I use the Python all the time. >> >> Or you can manually cd around (as I suspect Tony does). >> Personally I find cmd/bat among the worst programming languages ever and would rather not write it. >> jscript via cscript.exe would be a good alternative, it is always there at least as of Windows 2000 or perhaps with IE installed on older versions, but then you have to duplicate work across Unix and Windows. >> That is, for Windows-only no-cmd, no-install command line automation, JScript and VBScript are good choices, but Windows-only rules them out. The install is worth it. >> Python is a very decent programming language that is very portable across "all" systems. >> Perl would be the next best choice, though..I just don't like much. >> sh/bash requires an install on Windows, so its built-inness on Posix I claim isn't a conclusive win. >> I strongly encourage you to try out Python. >> >> Another avenue is to merge the sh/cmd/python into cm3 itself. >> It shouldn't be all that hard. >> >> Modula-3 still needs a C linker. >> And there is C code that I didn't put in -- hand.c and dtoa.c. >> If someone writes a linker in Modula-3, or gets the .obj loader working, I'll be more open to eliminating C. >> >> But using C is much less error prone and much more portable, in some parts of the system. >> >> You may label C as "evil", but the other "evil" I am battling is tedious error prone "header cloning". >> You pretty much must chose one. >> The header cloning can be reduced, and its error proned-ness and difficulty various per system, depending on how gnarled up the headers are with ifdefs, compatibility hacks, processor-specificty, "cleansing" (where the installed headers are processor specific, deriving from #ifdef'ed or somesuch other files, but now I argue both sides, #ifdef is hard to read, but removing them removes information unless you track further back), etc. For example the OpenBSD headers are much more readable. I suspect NetBSD are too but haven't looked yet. The Linux headers contain a lot of #ifdef and they are also processor-specific I think -- you know, my /usr/include/errno.h on one system I think didn't show that x86 and SPARC use different values. >> >> >> - Jay >> >> >> >> ________________________________ >> >> >> Date: Wed, 31 Dec 2008 10:28:37 -0500 >> From: rcoleburn at scires.com >> To: m3devel at elegosoft.com >> Subject: Re: [M3devel] [M3commit] CVS Update: cm3 >> >> >> >> Jay: >> >> >> >> Please explain what you mean by: >> >> >> >> "- BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386." >> >> >> >> IMO, it would be wrong to change the meaning of things like "BUILD_DIR", "HOST", and "TARGET". Indeed, I have stuff that depends on the meaning of these things. Your statement seems to imply that "under the covers" you've made the CYGWIN implementation "appear" to be the same as the native Windows implementation. But they are not the same. >> >> >> >> On another note, All this CYGWIN stuff may be a nice way for die-hard Unix fans to run Modula-3 on Windows, and I have no objection to providing it, as long as it does not compromise the native Windows implementation. My main concern is the native implementation of Modula-3 on Windows. My preference would be to keep the NT386 implementation's dependencies on other stuff to a bare minimum, i.e., don't introduce anything that would require someone to have to acquire something besides what comes in the standard Windows OS in order to make Modula-3 run. As it is now, we already have to get a C compiler and linker. Fortunately, Microsoft has made the Visual Studio Express editions a free download, so this is not too bad. I don't want to have to install CYGWIN either in order to make the native implementation work on Windows. I also still prefer the CMINSTALL, CMD, or BAT files for install as opposed to having to get Python or something else. Just my 2 cents. >> >> >> >> Finally, I would go a step further and suggest that the Modula-3 implementation on every platform should strive to require minimal dependencies on anything not provided standard with that platform's operating system. >> >> >> >> Call me an idealist, but it just galls me that I have to have a C compiler/linker to build Modula-3. Modula-3 is a systems programming language. It should stand on its own. From a purely economical viewpoint, why should I have to buy something I don't want (C language development environment) in order to have the privilege of using what I do want (Modula-3 language development environment). >> >> >> >> Regards, >> >> Randy >> >>>>> Jay Krell 12/31/2008 11:52 AM>>> >> CVSROOT:/usr/cvs >> Changes by:jkrell at birch.08/12/31 11:52:08 >> >> Modified files: >> cm3/m3-comm/netobj/src/: netobj-ov.tmpl >> cm3/m3-comm/sharedobj/src/: sharedobj-ov.tmpl >> cm3/m3-libs/libm3/src/bundleintf/: bundle-ov.tmpl >> cm3/m3-ui/zeus/src/: m3zume-ov.tmpl >> cm3/m3-ui/juno-2/juno-app/src/: m3makefile >> >> Log message: >> Partly kinda sorta fix some cross build scenarios, without >> affecting native builds. >> >> It's a larger more general problem though. >> >> - BUILD_DIR does not necessarily equal HOST or TARGET, >> because of how I structured I386_CYGWIN to be a "configuration" >> where TARGET is still NT386. >> >> - a cross build can run the shipped binary anyway, >> and probably should (I didn't have the unshipped binaries around) >> >> - There should probably be automation to ensure all the tools are build. >> ie: do-cm3-tools or do-cm3-crosstools. ie: build just the needed packages, >> for the sniffed native platform. >> >> Cross builds have other problems. >> >> I keep hitting the following annoyances: >> >> ignoring foo/bar override when foo\bar already overridden >> override paths should either be canonicalized to one slash type >> or at least when there is a duplicate, canonicalize then and only >> complain if canonicals vary >> This is due to mixing I386_NT and I386_CYGWIN. >> Similarly the problem demonstrated regarding m3unix.h in Uwaitpid.quake. >> >> Perhaps the change I made to allow forward slashes on Win32 was not good, esp. due to >> its apparent inadequacy. >> >> The "lib" directory, specifically \cm3\lib\hand.obj is target..er, configuration dependent >> the gcc hand.obj cannot be directly linked by Visual C++, for reasons to do with libgcc >> >> lib should probably have "target" or "build_dir" under it >> >> and/or hand.obj specifically should be merged into m3core.lib >> >> The mentor quake code generally fails in cross environments, probably due to slashes. >> >> host=NT386 (GNU?), target=LINUXLIBC6 m3zume is access violating >> >> I'm also highly suspicious of all this "override" stuff. >> It clearly causes too much duplication and distribution of information. >> I shouldn't have to know the directory structure of my dependencies, >> and even if I do, I should be able to share that knowledge with their many >> other dependents. The "scripts" directory also figures this sort of stuff out automatically.. >> Being able to have multiple package stores is well and good. >> I'm not sure they need to ever be used in an "unshipped" form, but instead just >> use alternate roots and create new empty roots as needed. ? >> >> From hosking at cs.purdue.edu Thu Feb 5 00:04:47 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 10:04:47 +1100 Subject: [M3devel] further reducing cloned headers wrt pthread? In-Reply-To: References: <6F809BD6-0A57-4A21-9AF8-530081FB1014@cs.purdue.edu> <44783E5A-F0BC-4351-8EB0-D9CA581EF7B1@cs.purdue.edu> <2550C4A0-A7D7-4F09-A928-61EB3E7F44E2@cs.purdue.edu> Message-ID: On 5 Feb 2009, at 09:11, Jay wrote: > >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. > > > The entire proposal or the optimizations? The C allocation of M3 objects, without going through NEW. There are a whole slew of reasons why I'd like to avoid that. > The original unoptimized proposal seems like a small change mostly. > I checked and the indirection/heap allocation is already there > for cond and mutex, but not for pthread_t itself. > Factoring out the size I think is a small change. Yes, possibly. Let me look at it. > On the other hand, we can also optimize it, pretty much > locking in the platform-specificity. It's a tough decision to me. > I don't mind the deoptimizations of const-to-var, or adding > some function calls, but heap allocs imho are among the things > to definitely avoid if not needed. These are untraced as well, > so the argument that Modula-3 heap alloc is efficient doesn't apply. Right, just that you lose some compiler knowledge of where allocations occur. I have some work I am doing where I analyse code for allocation sites. > One caveat that bothers me though is, like with sem_t, > I don't want to have types that are declared "incorrectly". > I'd like types that you can only have references too. > Probably in that case "give up", declare them as ADDRESS, > losing the type safety -- pthread_cond_foo could take a mutex_t > and no compilation error. Sure. > The idea of making them all ADDRESS and adding C functions to alloc/ > cleanup > is also good imho. That allows for one of the optimized forms -- > not where the space is at the end of the Thread.T, but where the > ADDRESS field is the data itself. Possibly. > I got hung up on pthread_attr_t here because it was efficiently > stack allocated and this proposal would have really deoptimized that. > The C code I showed avoids that though. > Albeit only in the face of creating a thread -- an extra heap > allocation > per thread create probably not a big deal. Hmm. > Clearly I'm ambivalent. OK, let me think on it. > Later, > > - Jay > > > > > > > > ---------------------------------------- >> From: jay.krell at cornell.edu >> To: hosking at cs.purdue.edu >> Date: Wed, 4 Feb 2009 09:42:12 +0000 >> CC: m3devel at elegosoft.com >> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >> >> >> It gains something, but maybe it isn't enough >> to be worthwhile. The issue is in the subjectivity. >> >> >> It would remove e.g. the following system-dependent lines: >> >> >> Linux: >> pthread_t = ADDRESS; >> pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; >> pthread_key_t = uint32_t; >> >> >> Linux/32: >> pthread_attr_t = ARRAY[1..9] OF INTEGER; >> pthread_mutex_t = ARRAY[1..6] OF INTEGER; >> >> >> Linux/64: >> pthread_attr_t = ARRAY[1..7] OF INTEGER; >> pthread_mutex_t = ARRAY[1..5] OF INTEGER; >> >> >> FreeBSD: >> pthread_t = ADDRESS; >> pthread_attr_t = ADDRESS; >> pthread_mutex_t = ADDRESS; >> pthread_cond_t = ADDRESS; >> pthread_key_t = int; >> >> >> HP-UX: >> (* trick from darwin-generic/Upthread.i3 *) >> X32 = ORD(BITSIZE(INTEGER) = 32); >> X64 = ORD(BITSIZE(INTEGER) = 64); >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..11 * X64 + 22 * X32] OF >> INTEGER; END; (* 88 opaque bytes with size_t alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..7 * X64 + 14 * X32] OF >> INTEGER; END; (* 56 opaque bytes with size_t alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Cygwin: >> pthread_t = ADDRESS; (* opaque *) >> pthread_attr_t = ADDRESS; (* opaque *) >> pthread_mutex_t = ADDRESS; (* opaque *) >> pthread_cond_t = ADDRESS; (* opaque *) >> pthread_key_t = ADDRESS; (* opaque *) >> >> >> Solaris: >> pthread_t = int32_t; (* opaque *) >> pthread_attr_t = int32_t; (* opaque *) >> pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* >> 32 bytes with 64 bit alignment *) >> pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 >> bytes with 64 bit alignment *) >> pthread_key_t = int32_t; (* opaque *) >> >> >> Darwin: (only ppc32 currently) >> pthread_t = INTEGER; (* opaque *) >> pthread_attr_t = RECORD opaque: ARRAY [1..10] OF INTEGER; END; >> pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END; >> pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; >> pthread_key_t = INTEGER; (* opaque *) >> >> >> (plus AIX, Irix, VMS, Tru64.) >> >> >> Another approach would be make them all ADDRESS and introduce a >> portable >> C layer of "varything thickness", using the same logic. >> It would look just like the native pthreads, but there'd be extra >> allocate/cleanup >> calls -- to do the heap alloc/cleanup when the underlying types are >> larger than addresses. >> The two layers would be clear and simple, the cost would be the same, >> but there would be the conceptual cost of two simple layers instead >> of one >> just one slightly complicated layer. >> >> >> Another approach is maybe make them all addresses on new platforms >> and introduce >> the C layer only on new platforms. Again, about the only change in >> the Modula-3 >> code is extra alloc/cleanup calls. >> >> >> And again, some/all of the code already has the indirection/heap >> allocation unconditionally. >> >> >> And again, maybe not worth it. I show all the system-dependent >> code, attempting >> to portray in its worst light by showing all of it, but maybe it's >> really not a lot. >> >> >> For the attr type, we can do something specific to its use. >> There is just one use, and we can address it with the following >> function written in C.. >> eh..I'll send a diff later tonight/this week I think. >> >> >> pthread_t and pthread_key_t always happen to be address-sized or >> smaller. >> Maybe just declare them both to be address and assert their size in >> some C code. >> That might waste a few bytes esp. on 64 bit platforms, or it might >> merely fill in the padding-for-alignment. >> >> For example, we have: >> >> >> TYPE >> Activation = UNTRACED REF RECORD >> (* global doubly-linked, circular list of all active threads *) >> next, prev: Activation := NIL; (* LL = activeMu *) >> (* thread handle *) >> handle: pthread_t; (* LL = activeMu *) >> (* base of thread stack for use by GC *) >> stackbase: ADDRESS := NIL; (* LL = activeMu *) >> >> >> so on 64 bit platforms where pthread_t is a 32bit integer, it is >> taking up 64 bits anyway. >> There are two static pthread_key_ts, so making them address would >> waste 8 bytes on some/many 64bit platforms. >> >> >> Leaving only cond and mutex. >> Some of the platforms declare more types such as rwlock, >> rwlockattr, but they are never used. >> rwlock is a useful type though. >> >> >> - Jay >> >> >> ---------------------------------------- >>> From: hosking at cs.purdue.edu >>> To: jay.krell at cornell.edu >>> Date: Wed, 4 Feb 2009 12:53:54 +1100 >>> CC: m3devel at elegosoft.com >>> Subject: Re: [M3devel] further reducing cloned headers wrt pthread? >>> >>> I am very leery of this proposal -- the code will be inherently >>> opaque >>> and unmaintainable. I don't see any advantage to it. >>> >>> On 4 Feb 2009, at 11:06, Jay wrote: >>> >>>> >>>> There are a few possibilities: >>>> >>>> >>>> Roughly: >>>> >>>> Where there is >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = ... system specific ... >>>> pthread_cond_t = ... system specific ... >>>> pthread_mutex_t = ... system specific ... >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> MODULE PThread; >>>> VAR >>>> a: pthread_t; >>>> b: pthread_cond_t; >>>> c: pthread_mutex_t; >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> change to: >>>> >>>> INTERFACE Upthread; >>>> >>>> TYPE >>>> pthread_t = RECORD END; or whatever is correct for an opaque >>>> preferably unique type >>>> pthread_cond_t = RECORD END; ditto >>>> pthread_mutex_t = RECORD END; ditto >>>> >>>> PROCEDURE pthread_thread_init_or_whatever(VAR pthread_t); >>>> PROCEDURE pthread_mutex_init_or_whatever(VAR pthread_mutex_t); >>>> PROCEDURE pthread_cond_init_or_whatever(VAR pthread_cond_t); >>>> >>>> >>>> INTERFACE PThreadC.i3 >>>> >>>> PROCEDURE GetA(): UNTRACED REF Upthread.thread_t; >>>> PROCEDURE GetB(): UNTRACED REF Upthread.thread_cond_t; >>>> PROCEDURE GetC(): UNTRACED REF Upthread.thread_mutex_t; >>>> >>>> or possibly extern VAR >>>> >>>> PThreadC.c >>>> >>>> static pthread_t a = PTHREAD_INIT; >>>> static pthread_cond_t b = PTHREAD_COND_INIT; >>>> static pthread_mutex_t c = PTHREAD_MUTEX_INIT; >>>> >>>> pthread_t* GetA() { return &a; } >>>> >>>> pthread_cond_t* GetB() { return &b; } >>>> >>>> pthread_mutex_t* GetC() { return &c; } >>>> >>>> MODULE PThread; >>>> VAR >>>> a := PThreadC.GetA(); >>>> b := PThreadC.GetB(); >>>> c := PThreadC.GetA(); >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a^); >>>> Upthread.pthread_cond_init_or_whatever(b^); >>>> Upthread.pthread_mutex_init_or_whatever(c^); >>>> END Foo; >>>> >>>> or, again, possibly they are variables and it goes a little >>>> smaller/ >>>> quicker: >>>> >>>> FROM UPthreadC IMPORT a, b, c; >>>> >>>> >>>> PROCEDURE Foo() = >>>> BEGIN >>>> Upthread.pthread_thread_init_or_whatever(a); >>>> Upthread.pthread_cond_init_or_whatever(b); >>>> Upthread.pthread_mutex_init_or_whatever(c); >>>> END Foo; >>>> >>>> I think that is pretty cut and dry, no controversy. >>>> >>>> What is less clear is what to do with non-statically allocated >>>> variables. >>>> >>>> Let's say: >>>> >>>> MODULE PThread; >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:pthread_t; >>>> END; >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T) >>>> BEGIN >>>> Upthread.init_or_whatever(t.b); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> The desire is something that does not know the size of pthread_t, >>>> something like: >>>> >>>> TYPE T = RECORD >>>> a:int; >>>> b:UNTRACED REF pthread_t; >>>> END; >>>> >>>> >>>> PROCEDURE CreateT():T= >>>> VAR >>>> t := NEW(T); >>>> BEGIN >>>> t.b := LOOPHOLE(UNTRACED REF pthread_t, NEW(UNTRACED REF ARRAY OF >>>> CHAR, Upthread.pthread_t_size)); >>>> (* Though I really wanted t.b := >>>> RTAllocator.MallocZeroed(Upthread.pthread_t_size); *) >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> PROCEDURE DisposeT(t:T)= >>>> BEGIN >>>> IF t = NIL THEN RETURN END; >>>> Upthread.pthread_cleanup_or_whatever(t.b^); >>>> DISPOSE(t.b); >>>> DISPOSE(t); >>>> END; >>>> >>>> >>>> However that incurs an extra heap allocation, which is not great. >>>> In at least one place, the pointer-indirection-and-heap-allocation >>>> is already there >>>> so this isn't a deoptimization. However "reoptimizing" it might be >>>> nice. >>>> >>>> >>>> What I would prefer a pattern I often use in C -- merging >>>> allocations, something like, >>>> /assuming/ t is untraced, which I grant it might not be. >>>> >>>> >>>> And ensuring that BYTESIZE(T) is properly aligned: >>>> >>>> >>>> PROCEDURE CreateT():UNTRACED REF T= >>>> VAR >>>> p : ADDRESS; >>>> t : UNTRACED REF T; >>>> BEGIN >>>> (* Again I would prefer RTAllocator.MallocZeroed *) >>>> p := NEW(UNTRACED REF ARRAY OF CHAR, Upthread.pthread_t_size + >>>> BYTESIZE(T))); >>>> t := LOOPHOLE(UNTRACED REF T, p); >>>> t.b := LOOPHOLE(UNTRACED REF Upthread.pthread_t, p + BYTESIZE(T)); >>>> Upthread.init_or_whatever(t.b^); >>>> RETURN t; >>>> END; >>>> >>>> >>>> That is -- opaque types, size not known at compile-time, but size >>>> known at runtime, and >>>> do not incur an extra heap allocation for lack of knowing sizes at >>>> compile-time. >>>> >>>> >>>> For the statically allocated variables I think there is no >>>> controversy. >>>> There might a tiny bit of overhead in the use, but it'd be very >>>> small, and possibly >>>> even removable in the future. I'd rather avoid the variables, as >>>> all writable >>>> data is to be avoided. Read only pages are better and all that, >>>> but ok.. >>>> >>>> >>>> However the value is mainly realized only if statically and >>>> dynamically allocated variables are handled. >>>> >>>> The result of this would be further reduction in platform- >>>> specificity when cloning >>>> C headers into Modula-3 interfaces. i.e. less work to bring up new >>>> platforms. >>>> >>>> >>>> - Jay >>>> >>>> >>>> ---------------------------------------- >>>>> From: hosking at cs.purdue.edu >>>>> To: jay.krell at cornell.edu >>>>> Date: Wed, 4 Feb 2009 09:54:01 +1100 >>>>> CC: m3devel at elegosoft.com >>>>> Subject: Re: [M3devel] further reducing cloned headers wrt >>>>> pthread? >>>>> >>>>> I suggest you come up with a proposal for us to look over before >>>>> you >>>>> change the code base for this. >>>>> >>>>> On 4 Feb 2009, at 09:05, Jay wrote: >>>>> >>>>>> >>>>>>> Hmm, yes, you are right that there is a possible alignment >>>>>>> issue. I >>>>>>> am used to pthread_mutext_t being a simple reference. But surely >>>>>>> in C >>>>>>> the type of the pthread_mutex_t struct would have appropriate >>>>>>> alignment padding anyway so as to allow allocation using >>>>>>> malloc(sizeof >>>>>>> pthread_mutex_t)? So, it all should just work right? >>>>>> >>>>>> >>>>>> I think "the other way around" and same conclusion. >>>>>> malloc should return something "maximally aligned" so that >>>>>> >>>>>> pthread_mutex_t* x = (pthread_mutex_t*) >>>>>> malloc(sizeof(pthread_mutex_t)); >>>>>> >>>>>> >>>>>> works. pthread_mutex_t doesn't need the padding, malloc does, >>>>>> so to >>>>>> speak. >>>>>> >>>>>> >>>>>> Just as long as we don't have >>>>>> >>>>>> >>>>>> TYPE Foo = RECORD >>>>>> a: pthread_mutex_t; >>>>>> b: pthread_mutex_t; >>>>>> c: pthread_t; >>>>>> d: pthread_t; >>>>>> e: pthread_cond_t; >>>>>> f: pthread_cond_t; >>>>>> END; >>>>>> >>>>>> >>>>>> and such, ok. >>>>>> >>>>>> >>>>>> malloc on NT returns something with 2 * sizeof(void*) alignment. >>>>>> I think on Win9x only 4 alignment, thus there is >>>>>> _malloc_aligned for >>>>>> dealing with SSE stuff. >>>>>> Something like that. >>>>>> >>>>>> >>>>>> I didn't realize untraced allocations were basically just >>>>>> malloc but >>>>>> indeed they are. >>>>>> >>>>>> >>>>>> I'm still mulling over the possible deoptimizations here. >>>>>> I'm reluctant to increase heap allocations. >>>>>> >>>>>> >>>>>> >>>>>> - Jay >>>>> >>> From mika at async.caltech.edu Thu Feb 5 05:33:09 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Wed, 04 Feb 2009 20:33:09 -0800 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: Your message of "Wed, 04 Feb 2009 22:01:58 GMT." Message-ID: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Jay writes: ... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) ... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika From hosking at cs.purdue.edu Thu Feb 5 05:45:46 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Thu, 5 Feb 2009 15:45:46 +1100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. On that count, does anyone know what happened to the CM Java VM? Is it available anywhere? On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > Jay writes: > ... >> I'll maybe review more code along these lines. >> I gather the general gist of things in Modula-3 though >> is that out of memory is fatal anyway. Raising an exception >> vs. failing an assertion probably not significantly different >> if the exception is not meant to be caught and isn't ever caught. >> (Strange though then the gymnastics I pointed out elsewhere >> converting one form of out of memory to another form..) > ... > > Back in SRC days I remember there was a discussion at some length > about what to do in case of running out of memory. I think the > project was abandoned as people realized it was quite a tricky > problem... > > I don't believe PM3 has out of memory exceptions, nor did SRC > M3...? It's a wild guess but maybe this has something to do with > the Critical Mass modifications for their JVM? > > Mika From dabenavidesd at yahoo.es Thu Feb 5 18:56:06 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Thu, 5 Feb 2009 09:56:06 -0800 (PST) Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <200902050433.n154X9lu007418@camembert.async.caltech.edu> Message-ID: <519119.97354.qm@web24711.mail.ird.yahoo.com> Hi all; I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at: ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/ Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps. Thanks --- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headers Para: "Jay" CC: m3devel at elegosoft.com Fecha: mi?rcoles, 4 febrero, 2009 11:33 Jay writes: .... >I'll maybe review more code along these lines. >I gather the general gist of things in Modula-3 though >is that out of memory is fatal anyway. Raising an exception >vs. failing an assertion probably not significantly different >if the exception is not meant to be caught and isn't ever caught. >(Strange though then the gymnastics I pointed out elsewhere >converting one form of out of memory to another form..) .... Back in SRC days I remember there was a discussion at some length about what to do in case of running out of memory. I think the project was abandoned as people realized it was quite a tricky problem... I don't believe PM3 has out of memory exceptions, nor did SRC M3...? It's a wild guess but maybe this has something to do with the Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:11:37 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:11:37 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Does this make sense? It is pushing my Modula-3 knowledge. I didn't yet check the number of bytes requested by malloc/calloc. All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 7.txt URL: From jay.krell at cornell.edu Thu Feb 5 19:29:59 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:29:59 +0000 Subject: [M3devel] out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: Here are some ideas that contribute to handling out of memory being useful/good: "stress" Stress a system.Things start going slow and failing, ok. You can't succeed against all odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion" A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources. Assuming that important state is managed well, like in a transactional database. And that most state is expendable. As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/ "malicious", as well as insulating "important" server processes (daemons) from run away/malicious clients. Guard against "denial of service attacks". Some people like to put hard limits on things. "I will reject any strings longer than 2gig". However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it. Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:39:09 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:39:09 +0000 Subject: [M3devel] FW: out of memory philosophy In-Reply-To: <519119.97354.qm@web24711.mail.ird.yahoo.com> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <519119.97354.qm@web24711.mail.ird.yahoo.com> Message-ID: (truncated..) From: jay.krell at cornell.eduTo: dabenavidesd at yahoo.es; m3devel at elegosoft.comSubject: RE: out of memory philosophyDate: Thu, 5 Feb 2009 18:29:59 +0000 Here are some ideas that contribute to handling out of memory being useful/good: "stress"Stress a system.Things start going slow and failing, ok. You can't succeed againstall odds, you can only try.Remove the stress.System should go back to normal, as if the stress was never applied.System should not require reboot, should not have leaked, etc. (I see a lot of "leaks in error paths" in traditional codethat tries lamely to be right: p = malloc(); q = malloc(); if (q == NULL) return error; /* p leaked */ ) "running at the edge of resource exhaustion"A system is "dedicated" to a certain task.It should make the most use of the resources it has.That is, it should use all the memory and/or cpu available.Diskspace is a different matter -- so much of it generally, hard to exhaust,and hard to consume more than one resource.Using it all means it will occasionally go too far,which should gracefully fail and use a little less.If you don't aim to use it all, you won't, and you will under-utilize. You could perhaps modify this and say "aim for 90% utilization". Certain "applications" might not strive to be this way,but if "the system" is not, then no application can be.The whole can only be as good as all the parts, etc.One bad apple spoils the bunch, etc.(Possible cultural-ism there.) Another approach though is to kill processes that are low on resources.Assuming that important state is managed well, like in a transactional database.And that most state is expendable.As well, resource hungry processes might be "run away" and/or "malicious". Trick of course is to discern the "important non-malicious" from the "run away"/"malicious", as well as insulating "important" server processes (daemons)from run away/malicious clients. Guard against "denial of service attacks".Some people like to put hard limits on things. "I will reject any strings longer than 2gig".However that has the affect of imposing arbitrary capacity limits where larger capacity might just work and there might be legitimate clients for it.Lately I'm using Windows findstr against text files with very long lines. It fails, it says "line too long". Darn. - Jay Date: Thu, 5 Feb 2009 09:56:06 -0800From: dabenavidesd at yahoo.esTo: m3devel at elegosoft.comSubject: Re: [M3devel] elminating pthread_attr_t from cloned headers Hi all;I guess there was a 1995 try to change that Runtime error into an exception (not sure if they succeed). Take a look at:ftp://ftp.u-aizu.ac.jp/pub/lang/Modula/m3/pkg/contrib/whenNEWfails/src/Please be patient if the files don't appear when loading the web page (I tried 2 times to open that url with the source files). Hope this helps.Thanks--- El mi?, 4/2/09, Mika Nystrom escribi?: De: Mika Nystrom Asunto: Re: [M3devel] elminating pthread_attr_t from cloned headersPara: "Jay" CC: m3devel at elegosoft.comFecha: mi?rcoles, 4 febrero, 2009 11:33Jay writes:...>I'll maybe review more code along these lines.>I gather the general gist of things in Modula-3 though>is that out of memory is fatal anyway. Raising an exception>vs. failing an assertion probably not significantly different>if the exception is not meant to be caught and isn't ever caught.>(Strange though then the gymnastics I pointed out elsewhere>converting one form of out of memory to another form..)...Back in SRC days I remember there was a discussion at some lengthabout what to do in case of running out of memory. I think theproject was abandoned as people realized it was quite a trickyproblem...I don't believe PM3 has out of memory exceptions, nor did SRCM3...? It's a wild guess but maybe this has something to do withthe Critical Mass modifications for their JVM? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Thu Feb 5 19:57:17 2009 From: jay.krell at cornell.edu (Jay) Date: Thu, 5 Feb 2009 18:57:17 +0000 Subject: [M3devel] reducing system-dependence in Upthread.i3? Message-ID: Hm, nevermind that. More later. I think either wrapping it up more in C would be cleaner or even Modula-3 ("Upthread.m3"), than this sort of "split", or at least changing it to ADDRESS and if size <= BYTESIZE(ADDRESS), just use that space and save the heap alloc. On systems that already have either a small object or an indirection, save the heap alloc. Later, - Jay From: jay.krell at cornell.eduTo: m3devel at elegosoft.comSubject: reducing system-dependence in Upthread.i3?Date: Thu, 5 Feb 2009 18:11:37 +0000 Does this make sense?It is pushing my Modula-3 knowledge.I didn't yet check the number of bytes requested by malloc/calloc.All platforms would have to be changed, not just what is shown here. UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right? Don't need to resort to ADDRESS? OR should we go the other way and remove the heap allocs? (attached and inline)Index: src/thread/PTHREAD/ThreadPThread.m3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,vretrieving revision 1.90diff -u -r1.90 ThreadPThread.m3--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000@@ -24,20 +24,20 @@ nextId: CARDINAL := 1; - activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)- slotMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)- initMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)+ activeMu := NewMutex(); (* global lock for list of active threads *)+ slotMu := NewMutex(); (* global lock for thread slot table *)+ initMu := NewMutex(); (* global lock for initializers *) REVEAL Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; OVERRIDES acquire := Acquire; release := Release; END; Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT- mutex: UNTRACED REF pthread_mutex_t := NIL;+ mutex: pthread_mutex_t := NIL; waiters: T := NIL; (* LL = mutex *) END; @@ -58,7 +58,7 @@ nextWaiter: T := NIL; (* LL = waitingOn.mutex *) (* condition for blocking during "Wait" *)- waitCond: UNTRACED REF pthread_cond_t;+ waitCond: pthread_cond_t; (* the alert flag *) alerted : BOOLEAN := FALSE; (* LL = mutex *)@@ -94,6 +94,8 @@ heapState : RTHeapRep.ThreadState; END; +(*---------------------------------------------------------------------------*)+ PROCEDURE SetState (act: Activation; state: ActState) = CONST text = ARRAY ActState OF TEXT { "Starting", "Started", "Stopping", "Stopped" };@@ -108,24 +110,41 @@ END; END SetState; +(*---------------------------------------------------------------------------*)++(* probably move this to Upthread.m3 *)+PROCEDURE NewMutex(): pthread_mutex_t =+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);+ r := Upthread.mutex_init(m);+BEGIN+ <*ASSERT r=0*>+ RETURN m;+END NewMutex;++(* probably move this to Upthread.m3 *)+PROCEDURE NewCond(): pthread_cond_t =+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);+ r := Upthread.cond_init(c);+BEGIN+ <*ASSERT r=0*>+ RETURN c;+END NewCond;+ (*----------------------------------------------------------------- Mutex ---*) PROCEDURE CleanMutex (r: REFANY) = VAR m := NARROW(r, Mutex); BEGIN- WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END; DISPOSE(m.mutex); END CleanMutex; PROCEDURE InitMutex (m: Mutex) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF m.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- m.mutex := mutex;+ m.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -140,7 +159,7 @@ END; IF m.mutex = NIL THEN InitMutex(m) END; IF perfOn THEN PerfChanged(self.id, State.locking) END;- WITH r = Upthread.mutex_lock(m.mutex^) DO+ WITH r = Upthread.mutex_lock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_lock error: ", r);@@ -156,7 +175,7 @@ IF self = NIL THEN Die(ThisLine(), "Release called from a non-Modula-3 thread"); END;- WITH r = Upthread.mutex_unlock(m.mutex^) DO+ WITH r = Upthread.mutex_unlock(m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_mutex_unlock error: ", r);@@ -169,19 +188,16 @@ PROCEDURE CleanCondition (r: REFANY) = VAR c := NARROW(r, Condition); BEGIN- WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END; DISPOSE(c.mutex); END CleanCondition; PROCEDURE InitCondition (c: Condition) =- VAR mutex: UNTRACED REF pthread_mutex_t; BEGIN TRY WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END; IF c.mutex # NIL THEN RETURN END;- mutex := NEW(UNTRACED REF pthread_mutex_t);- WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;- c.mutex := mutex;+ c.mutex := NewMutex(); FINALLY WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END; END;@@ -198,7 +214,7 @@ <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*> IF perfOn THEN PerfChanged(self.id, State.waiting) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; BEGIN self.waitingOn := c; next := c.waiters;@@ -211,10 +227,10 @@ prev.nextWaiter := self; END; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF alertable AND XTestAlert(self) THEN RAISE Alerted; END; LOOP- WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO+ WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO IF r # 0 THEN RTError.MsgI(ThisFile(), ThisLine(), "Thread client error: pthread_cond_wait error ", r);@@ -224,7 +240,7 @@ IF self.waitingOn = NIL THEN RETURN END; END; FINALLY- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF self.waitingOn # NIL THEN <*ASSERT self.waitingOn = c*> (* alerted: dequeue from condition *)@@ -240,7 +256,7 @@ self.nextWaiter := NIL; self.waitingOn := NIL; END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; IF perfOn THEN PerfRunning(self.id) END; <*ASSERT self.waitingOn = NIL*> <*ASSERT self.nextWaiter = NIL*>@@ -275,23 +291,23 @@ t := c.waiters; c.waiters := t.nextWaiter; t.nextWaiter := NIL; t.waitingOn := NIL;- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END DequeueHead; PROCEDURE Signal (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; IF c.waiters # NIL THEN DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Signal; PROCEDURE Broadcast (c: Condition) = BEGIN IF c.mutex = NIL THEN InitCondition(c) END;- WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END; WHILE c.waiters # NIL DO DequeueHead(c) END;- WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END; END Broadcast; PROCEDURE Alert (t: T) =@@ -299,7 +315,7 @@ LOCK t DO t.alerted := TRUE; IF t.waitCond # NIL THEN- WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END; END; END; END Alert;@@ -480,8 +496,7 @@ which will try to acquire "activeMu". *) VAR t := NEW(T, act := act); BEGIN- t.waitCond := NEW(UNTRACED REF pthread_cond_t);- WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;+ t.waitCond := NewCond(); t.cond := NEW(Condition); FloatMode.InitThread (act.floatState); AssignSlot (t);@@ -533,7 +548,7 @@ (* mark "self" done and clean it up a bit *) self.completed := TRUE; Broadcast(self.cond); (* let everybody know that "self" is done *)- WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;+ WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END; DISPOSE(self.waitCond); END; Index: src/unix/Common/Uconstants.c===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,vretrieving revision 1.15diff -u -r1.15 Uconstants.c--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000@@ -105,10 +105,14 @@ #undef X #define X(type, x) const type Upthread_##x = x;+#undef Y+#define Y(x, y) const size_t Upthread_##x = y; X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER) X(pthread_cond_t, PTHREAD_COND_INITIALIZER)-++Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))+Y(pthread_cond_t_size, sizeof(pthread_cond_t)) #undef X #define X(x) const int Usocket_##x = x;Index: src/unix/Common/Upthread.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,vretrieving revision 1.4diff -u -r1.4 Upthread.i3--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000@@ -7,11 +7,15 @@ FROM Ctypes IMPORT int; FROM Utypes IMPORT size_t; IMPORT Usysdep;++(*CONST*)+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t; TYPE pthread_t = Usysdep.pthread_t;- pthread_mutex_t = Usysdep.pthread_mutex_t;- pthread_cond_t = Usysdep.pthread_cond_t;+ pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;+ pthread_cond_t = UNTRACED REF ARRAY OF CHAR; pthread_key_t = Usysdep.pthread_key_t; destructor_t = PROCEDURE(arg: ADDRESS);Index: src/unix/cygwin/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,vretrieving revision 1.13diff -u -r1.13 Usysdep.i3--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -28,8 +28,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS; (* opaque *)- pthread_mutex_t = ADDRESS; (* opaque *)- pthread_cond_t = ADDRESS; (* opaque *) pthread_key_t = ADDRESS; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/darwin-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,vretrieving revision 1.3diff -u -r1.3 Usysdep.i3--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -20,8 +20,6 @@ (* INTERFACE Upthread; *) pthread_t = INTEGER; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;- pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END; pthread_key_t = INTEGER; (* opaque *) (* INTERFACE Usocket; *)Index: src/unix/freebsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,vretrieving revision 1.6diff -u -r1.6 Usysdep.i3--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -22,8 +22,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/linux-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,vretrieving revision 1.11diff -u -r1.11 Usysdep.i3--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ (* INTERFACE Upthread; *) pthread_t = ADDRESS;- pthread_mutex_t = Upthreadtypes.pthread_mutex_t;- pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END; pthread_key_t = uint32_t; (* INTERFACE Usocket; *)Index: src/unix/openbsd-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,vretrieving revision 1.12diff -u -r1.12 Usysdep.i3--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -21,8 +21,6 @@ pthread_t = ADDRESS; pthread_attr_t = ADDRESS;- pthread_mutex_t = ADDRESS;- pthread_cond_t = ADDRESS; pthread_key_t = int; (* INTERFACE Usocket; *)Index: src/unix/solaris-common/Usysdep.i3===================================================================RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,vretrieving revision 1.4diff -u -r1.4 Usysdep.i3--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000@@ -24,8 +24,6 @@ (* INTERFACE Upthread; *) pthread_t = int32_t; (* opaque *)- pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)- pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *) pthread_key_t = int32_t; (* opaque *) (* INTERFACE Usocket; *) -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Fri Feb 6 16:12:00 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Fri, 06 Feb 2009 16:12:00 +0100 Subject: [M3devel] elminating pthread_attr_t from cloned headers In-Reply-To: <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> References: <200902050433.n154X9lu007418@camembert.async.caltech.edu> <9782839F-760D-4236-BD20-5ED54C7F5CF0@cs.purdue.edu> Message-ID: <20090206161200.em81i2uh44sg8koo@mail.elegosoft.com> Quoting Tony Hosking : > Yes, OOMEs were added to CM3, as I understand it for the CM Java VM. > > On that count, does anyone know what happened to the CM Java VM? Is it > available anywhere? AFAIK it is not. I think I asked Farshad Nayeri some years ago, but got no answer. Maybe it's still in commercial use, or there are some other legal problems with the code (as Sun was probably involved). Nonetheless, it cannot harm to ask again... Olaf > On 5 Feb 2009, at 15:33, Mika Nystrom wrote: > >> Jay writes: >> ... >>> I'll maybe review more code along these lines. >>> I gather the general gist of things in Modula-3 though >>> is that out of memory is fatal anyway. Raising an exception >>> vs. failing an assertion probably not significantly different >>> if the exception is not meant to be caught and isn't ever caught. >>> (Strange though then the gymnastics I pointed out elsewhere >>> converting one form of out of memory to another form..) >> ... >> >> Back in SRC days I remember there was a discussion at some length >> about what to do in case of running out of memory. I think the >> project was abandoned as people realized it was quite a tricky >> problem... >> >> I don't believe PM3 has out of memory exceptions, nor did SRC >> M3...? It's a wild guess but maybe this has something to do with >> the Critical Mass modifications for their JVM? >> >> Mika -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From martinbishop at bellsouth.net Wed Feb 11 05:01:38 2009 From: martinbishop at bellsouth.net (Martin Bishop) Date: Tue, 10 Feb 2009 22:01:38 -0600 Subject: [M3devel] modula3.org updated links Message-ID: <49924DA2.6090607@bellsouth.net> A while back I said it would be nice if modula3.org could get it's links updated, as quite a few of them were dead. Well I went through the links on the front page of modula3.org (as well as the separate "Links" page) and updated them. I only removed one link, and replaced all the dead ones with either mirrors or just better links. (NOTE: They look bad because they aren't using the CSS, but I'm just putting these up so someone (Olaf?) can save the source and push to the modula3.org CVS.) http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html (Main page) http://mbishop.esoteriq.org/modula3.org/index.html (Links page) From jay.krell at cornell.edu Wed Feb 11 07:07:20 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 06:07:20 +0000 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: I must say, I find the design of the various web sites terrible. The stuff i want is far buried, not just deep, but sometimes under odd sounding links. The offenders include: "www service" is one of the worst named but most useful links, it is a link to one of the main Modula-3 pages. Given that this is already on a web page, "www service" adds no meaning. It is slightly a pain to find the CVS browsing page, the tinderbox status, and something else I forget. And it is annoying how the CVS pages opens doubly nested. Gotta run, - Jay> Date: Tue, 10 Feb 2009 22:01:38 -0600> From: martinbishop at bellsouth.net> To: m3devel at elegosoft.com> Subject: [M3devel] modula3.org updated links> > A while back I said it would be nice if modula3.org could get it's links> updated, as quite a few of them were dead. Well I went through the> links on the front page of modula3.org (as well as the separate "Links"> page) and updated them.> > I only removed one link, and replaced all the dead ones with either> mirrors or just better links.> > (NOTE: They look bad because they aren't using the CSS, but I'm just> putting these up so someone (Olaf?) can save the source and push to the> modula3.org CVS.)> > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html> (Main page)> > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Wed Feb 11 09:28:06 2009 From: jay.krell at cornell.edu (Jay) Date: Wed, 11 Feb 2009 08:28:06 +0000 Subject: [M3devel] apsl? (Apple source license?) Message-ID: Can we add Apple APSL-licensed code into the Modula-3 libraries? In particular, like, _setjmp.h? Or maybe even the get/set/make/swapcontext code? It looks me like ASPL is: "not viral" -- it does not impact the code it is linked to, mostly It carries with it an "advertising clause", which is somewhat viral. That is, you have to state you are using APSL code, and you might have to reveal that specific code (unknown) but there are no additional restrictions on code it is linked with. Upon further reading.. The license discusses "original code" and "modified code". If code is modified, it must be clearly marked as such. Reasonable, but annoying. If you modify the code, you do have to distribute it with binaries. Mildly viral. If you don't modify the code, you don't have to distribute any source. Good. http://www.opensource.apple.com/apsl/ http://www.gnu.org/philosophy/apsl.html (I wish everyone would just use the BSD license...but oh well..) - Jay -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Fri Feb 13 19:22:33 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:22:33 -0600 Subject: [M3devel] More on new Text package Message-ID: <4995BA69.6080705@wichita.edu> I neglected to mention that the new package, by default, uses the old algorithms, although there will be constant-time slowdown, because it decides dynamically on every call to do this. Also, there is a lot of instrumentation being executed. To get the new algorithms, set TextClass.Old to FALSE. You can change this between any two calls into the package. Rodney Bates From rodney.bates at wichita.edu Fri Feb 13 19:05:30 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Fri, 13 Feb 2009 12:05:30 -0600 Subject: [M3devel] New experimental Text module Message-ID: <4995B66A.8000906@wichita.edu> There is an experimental replacement for the various library code involving the type TEXT, now checked in the CVS repository, in cm3/m3-libs/m3core/src/text, under branch devel_m3core_text_newtext_branch. There is a test program for it in cm3/m3-libs/m3core/tests/newtext. Approach: I tried to see how much I could improve the performance of CM3 TEXT operations by changing the algorithms only, leaving the data structure, both declarations and invariants, unchanged. This presents minimum disruption elsewhere. Both the pickle code and existing pickle files will be unaffected, along with other things that use pickles. Changes: I eliminated as much recursion as possible, converting some instances of recursion to tail-recursions, and then converting all tail-recursion instances to iteration. Recursion remains when: 1) There is true nonlinear recursion. This happens in only one place in concatenation. Here, I did the recursion on the shorter (and thus hopefully shallower) side of the tree. 2) Where necessary to avoid the chance of creating an identical copy of a known, already existing TextCat.T node. 3) The recursion needs to go through a method dispatch. In concatenations, I "flattened" concatenation results that do not exceed a length cutoff. By "flattening", I mean copying into a single node of type Text8.T, Text8Short.T, Text16, or Text16Short.T. I experimentally tuned the length cutoff to 32 bytes, for best compromise among speed and time and in various use cases. In concatenations, I did some heuristic rebalancing. I used the relative lengths of strings as a crude approximation for the relative depths of trees. Actual depths are not cached in the nodes, and computing them would have been O(n) for each concatenation operation. I postponed rebalancing flat strings into a tree, keeping them at the top, where they are available for further flattening, until there is no chance of this happening. Most of the existing operations were sometimes unnecessarily converting strings from CHAR to WIDECHAR arrays, involving character-at-a-time conversion. This was a likely very common case, and I eliminated it when easily detectable. Bugs: I fixed (I hope!) a few bugs I discovered in the existing code. Find[Wide]CharR had an off-by-one bug in the where the search started. String[8|16].FindCharR was doing an address computation too early, in a local variable declaration, before a needed NIL check, making the check fail to work. HasWideChars was only computing whether the representation had the capability to hold wide characters, not whether any were actually there. This was not a useful meaning for the result. TextCat.MultiCat (and NewMulti, which calls it) were not checking for NILs. Assuming the result was ever used, these would eventually cause runtime errors, but not until it was more difficult to diagnose them. Testing: The modified code can be dynamically switched between the old and new algorithms. It is also loaded with instrumentation. All of this will slow it down, but the old/new comparisons should not have significant bias. TextClass.i3 has a lot of new stuff to allow clients to control the algorithms and collect results from the instrumentation. If people decide they like this package, I will produce a version with all this extra stuff stripped out. I wrote an elaborate test driver, both for bug-testing and for experimenting and gathering performance comparisons with the old code. It runs large numbers of randomly-generated test cases, typically 50000 flat strings, 100000 string-producing operations, heavily biased to concatenations (substring is the only other one), and 100000 text querying operations, roughly equally distributed. Concatenations can be built randomly from previous strings or "linearly", i.e., strictly left-to-right, or strictly right-to-left. The latter two cases are symmetrical, and once the symmetry bugs were gone, they give virtually identical performance. In the linear construction cases, there are no substring operations done. The old and new algorithms can be run side-by-side on pairs of strings that have identical abstract values (but often different internal representations). The results can be mechanically compared this way, for correctness testing. Performance summary: In a number of different situations, the new algorithms give improvements in total time spent in the operations, ranging from 17% to 60%, the latter for linear concatenations, which are much slower than random, using both the old and new algorithms. Tree balance improves dramatically in the linear cases (the random case is well-balanced even by the old algorithms) and recursion depth decreases even more dramatically. The new algorithms allocate 27% (random) to 79% (linear) more heap memory, but a lot is garbage. After collection, the new algorithms retain 20% more (random) to 2% less (linear). Total space runs somewhat larger in the linear case, for both algorithms. The old algorithms toss no garbage. In the special case of linear concatentations with all leaf strings having length one, the new algorithms allocate over twice as much heap storage but retain 63% less. Rodney M. Bates From mika at async.caltech.edu Sat Feb 14 19:10:51 2009 From: mika at async.caltech.edu (Mika Nystrom) Date: Sat, 14 Feb 2009 10:10:51 -0800 Subject: [M3devel] Question about PM3 Message-ID: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika From rodney.bates at wichita.edu Sat Feb 14 21:30:23 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sat, 14 Feb 2009 14:30:23 -0600 Subject: [M3devel] Question about PM3 In-Reply-To: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> Message-ID: <499729DF.3000800@wichita.edu> I have no immediate ideas, but a few questions and thoughts. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. How recent is your m3gdb? For a long time, it has been putting out much better demangled names that what you are getting. You can use the m3gdb in the CM3 distribution and build just it with 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically adapts to PM3-compiled code (unless there is a bug :-). Which code generator did you use, the integrated i386 backend or the gcc-derived one? (If you aren't sure, the latest m3gdb will tell you this and other things about what language implementation it uses with the 'info m3' command, entered after the M3 runtime has initialized.) If there is a code generation problem, it could also go away after just changing backends. However, I'm not sure if there would be trouble without rebuilding all the libraries with the same backend as your application. Consider the possibility that the segfault is something other than dereferencing i, and the line number is misleading. I don't have any specific theories right off hand, but I would try (m3gdb) disass to see the machine code and (m3gdb) info reg to see the registers, including the instruction pointer. Relying on hardware traps to detect runtime errors does make the checks fast, but it gives poorer explanations when something goes wrong. Mika Nystrom wrote: > Dear Modula-3-ers: > > I'm going to ask a question about an old, obsolete piece of software, and > don't expect anybody knows the answer, but would be grateful for any > insight: > > I have a Modula-3 program compiled with one of the last releases of PM3 > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code > that looks like this: > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = > VAR seq : FIXFieldSeq.T; > BEGIN > LOOP > (* update seq *) > seq := i.t.data[i.part]; > > (* first see if we are at end or pointing to an uninteresting part *) > (* seq can be NIL on certain error conditions *) > IF seq # NIL THEN > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN > IF i.part = LAST(Part) THEN (* at bitter end *) > RETURN FALSE > ELSE > INC(i.part); i.nextI := 0 > END > ELSE (* not at end, but in the middle of an interesting Part *) > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO > TRY > IF cur.type() IN i.fields THEN (* nteresting field? *) > f := cur; RETURN TRUE > END > FINALLY > INC(i.nextI) (* in any case, advance to next *) > END > END > END > END > END > END UINext; > > What I am seeing is the following > > Program received signal SIGSEGV, Segmentation fault. > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > 893 INC(i.nextI) (* in any case, advance to next *) > (m3gdb) list > 888 TRY > 889 IF cur.type() IN i.fields THEN (* nteresting field? *) > 890 f := cur; RETURN TRUE > 891 END > 892 FINALLY > 893 INC(i.nextI) (* in any case, advance to next *) > 894 END > 895 END > 896 END > 897 END > > The crash makes no sense, because "i" has already been dereferenced > several times before this, without problem. > > (m3gdb) where > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 > > We're in some sort of "fake" stack frame, and... > > (m3gdb) up > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 > 890 f := cur; RETURN TRUE > (m3gdb) print i > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > nextI = 0; END > (m3gdb) > > everything looks OK with i. > > Is it possible there is some sort of problem with TRY .. FINALLY under > PM3? And of course, if so, might it go away with CM3? > > Mika > > From wagner at elegosoft.com Sat Feb 14 23:55:19 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sat, 14 Feb 2009 23:55:19 +0100 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <4995B9A8.5020403@wichita.edu> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> Message-ID: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Quoting "Rodney M. Bates" : > Well, I can work on compilers, debuggers, and functional text packages, but > I can never operate CVS correctly. > > As far as I can tell, I think I got these checkins done in the trunk, rather > than the branch I created for them. I created a tag on the trunk, > "devel_m3core_text_2009_02_13", then created a branch with tag > "devel_m3core_text_newtext_branch". Apparently I got that much right. > > But I am not sure whether the changed files went into the branch. My > CVS book reads as if just a cvs tag -b ..., followed by a cvs commit > will do the commits in the branch, but the commit message doesn't look > like that happened. > > Can anybody help me with: > 1) What really happened? > 2) How should I have done this? You probably forgot to update your workspace to the branch: cvs up -r devel_m3core_text_newtext_branch After that, the branch tag will be `sticky' in your workspace, until you use cvs up -A, which clears it again (and transports you to the trunk). > 3) How can I fix the damage? Well, you can easily revert the changes on the main trunk by checking out the latest version and using -j old-version -j current version, and then commit it. This should put the old-version at the head of the trunk again. Before you do that, you should probably commit everything to the branch, thus you don't need to checkout your version again. I think the version before yours was tagged devel_m3core_d2_4_0. But perhaps it is not necessary to do this? Have tou had feedback from others about the new sources? If nothing breaks and performance gets better, I won't complain ;-) Thanks for all the work, Olaf > PS: I believe that if you use the new files with no additional action, > that you > will get the same behavior as before, except that there will be considerable > constant-time slowdown due to lots of instrumentation and dynamic deciding to > use the original algorithms. But I have not tested this. So probably some improvements are needed before a release. -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From jay.krell at cornell.edu Sun Feb 15 00:04:12 2009 From: jay.krell at cornell.edu (Jay) Date: Sat, 14 Feb 2009 23:04:12 +0000 Subject: [M3devel] Question about PM3 In-Reply-To: <499729DF.3000800@wichita.edu> References: <200902141810.n1EIApEs014841@camembert.async.caltech.edu> <499729DF.3000800@wichita.edu> Message-ID: I agree with Rodney's sentiment to double check whatever you can. If you can rebuild the compiler/runtime, try growing the jmpbuf. Or see what size is being used and write one line of C to see what it should be. (#include #include int main() { printf("%u\n", (unsigned) sizeof(jmpbuf)); }) If you are using user threads, try kernel threads and/or DisableSwitching/EnableSwitching around the crashing code. Read the generated code to try to confirm correctness. If you are optimizing the code, try not. If the loop only runs "a few" times, print out the address as it is dereferenced. See if the failing address is the same as one of the successful ones. Nag me and I'll set up FreeBSD/x86/5.5, send me instructions to build pm3 and send me your code. :) Try any other configuration. pm3 on Linux. cm3 on FreeBSD. cm3 on Linux. etc. - Jay> Date: Sat, 14 Feb 2009 14:30:23 -0600> From: rodney.bates at wichita.edu> To: mika at async.caltech.edu> CC: m3devel at elegosoft.com> Subject: Re: [M3devel] Question about PM3> > I have no immediate ideas, but a few questions and thoughts.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > How recent is your m3gdb? For a long time, it has been putting out> much better demangled names that what you are getting. You can use> the m3gdb in the CM3 distribution and build just it with> 'cm3/scripts/do-cm3-m3gdb.sh build' to get the latest. The executable> will be in cm3/m3-sys/m3gdb/FREEBSD/gdb/gdb'. It dynamically> adapts to PM3-compiled code (unless there is a bug :-).> > Which code generator did you use, the integrated i386 backend or> the gcc-derived one? (If you aren't sure, the latest m3gdb will> tell you this and other things about what language implementation> it uses with the 'info m3' command, entered after the M3 runtime> has initialized.)> > If there is a code generation problem, it could also go away after> just changing backends. However, I'm not sure if there would be> trouble without rebuilding all the libraries with the same backend> as your application.> > Consider the possibility that the segfault is something other> than dereferencing i, and the line number is misleading. I don't> have any specific theories right off hand, but I would try> (m3gdb) disass to see the machine code and (m3gdb) info reg> to see the registers, including the instruction pointer.> > Relying on hardware traps to detect runtime errors does make> the checks fast, but it gives poorer explanations when something> goes wrong.> > Mika Nystrom wrote:> > Dear Modula-3-ers:> > > > I'm going to ask a question about an old, obsolete piece of software, and> > don't expect anybody knows the answer, but would be grateful for any> > insight:> > > > I have a Modula-3 program compiled with one of the last releases of PM3> > "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code> > that looks like this:> > > > PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN => > VAR seq : FIXFieldSeq.T;> > BEGIN> > LOOP> > (* update seq *)> > seq := i.t.data[i.part];> > > > (* first see if we are at end or pointing to an uninteresting part *)> > (* seq can be NIL on certain error conditions *)> > IF seq # NIL THEN> > IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN> > IF i.part = LAST(Part) THEN (* at bitter end *)> > RETURN FALSE> > ELSE> > INC(i.part); i.nextI := 0> > END> > ELSE (* not at end, but in the middle of an interesting Part *)> > WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO> > TRY> > IF cur.type() IN i.fields THEN (* nteresting field? *)> > f := cur; RETURN TRUE> > END> > FINALLY> > INC(i.nextI) (* in any case, advance to next *)> > END> > END> > END> > END> > END> > END UINext;> > > > What I am seeing is the following> > > > Program received signal SIGSEGV, Segmentation fault.> > 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > 893 INC(i.nextI) (* in any case, advance to next *)> > (m3gdb) list> > 888 TRY> > 889 IF cur.type() IN i.fields THEN (* nteresting field? *)> > 890 f := cur; RETURN TRUE> > 891 END> > 892 FINALLY> > 893 INC(i.nextI) (* in any case, advance to next *)> > 894 END> > 895 END> > 896 END> > 897 END> > > > The crash makes no sense, because "i" has already been dereferenced> > several times before this, without problem.> > > > (m3gdb) where> > #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846> > #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411> > #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321> > > > We're in some sort of "fake" stack frame, and...> > > > (m3gdb) up> > #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890> > 890 f := cur; RETURN TRUE> > (m3gdb) print i> > $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; > > nextI = 0; END> > (m3gdb) > > > > everything looks OK with i.> > > > Is it possible there is some sort of problem with TRY .. FINALLY under> > PM3? And of course, if so, might it go away with CM3?> > > > Mika> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dabenavidesd at yahoo.es Sun Feb 15 06:27:38 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sat, 14 Feb 2009 21:27:38 -0800 (PST) Subject: [M3devel] Question about PM3 Message-ID: <954132.49377.qm@web24715.mail.ird.yahoo.com> Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible that the assignment statement in line 890 is failing and because of the TRY-FINALLY you don't get a Runtime Error (which would be the ideal behaviour if the MODULE is safe and correspondent IMPORT Modules aren't? ill behaved ). 890 f := cur; RETURN TRUEYou could make a sanity check before that line with ?ISTYPE(cur, FIXField.T) (*is cur a member of f's type, FIXField.T *)? Please feel free to ask further questions. Hope this helps. Thanks. --- El s?b, 14/2/09, Mika Nystrom wrote: De: Mika Nystrom Asunto: [M3devel] Question about PM3 Para: m3devel at elegosoft.com Fecha: s?bado, 14 febrero, 2009 1:10 Dear Modula-3-ers: I'm going to ask a question about an old, obsolete piece of software, and don't expect anybody knows the answer, but would be grateful for any insight: I have a Modula-3 program compiled with one of the last releases of PM3 "FreeBSD4" running on a FreeBSD/i386 5.5 system. I have some code that looks like this: PROCEDURE UINext(i : UpIterator; VAR f : FIXField.T) : BOOLEAN = VAR seq : FIXFieldSeq.T; BEGIN LOOP (* update seq *) seq := i.t.data[i.part]; (* first see if we are at end or pointing to an uninteresting part *) (* seq can be NIL on certain error conditions *) IF seq # NIL THEN IF i.nextI = seq.size() OR NOT i.part IN i.parts THEN IF i.part = LAST(Part) THEN (* at bitter end *) RETURN FALSE ELSE INC(i.part); i.nextI := 0 END ELSE (* not at end, but in the middle of an interesting Part *) WITH cur = NARROW(seq.get(i.nextI),ProtocolFields.T) DO TRY IF cur.type() IN i.fields THEN (* nteresting field? *) f := cur; RETURN TRUE END FINALLY INC(i.nextI) (* in any case, advance to next *) END END END END END END UINext; What I am seeing is the following Program received signal SIGSEGV, Segmentation fault. 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 893 INC(i.nextI) (* in any case, advance to next *) (m3gdb) list 888 TRY 889 IF cur.type() IN i.fields THEN (* nteresting field? *) 890 f := cur; RETURN TRUE 891 END 892 FINALLY 893 INC(i.nextI) (* in any case, advance to next *) 894 END 895 END 896 END 897 END The crash makes no sense, because "i" has already been dereferenced several times before this, without problem. (m3gdb) where #0 0x080be11c in M_FIXMsgSuper4_1_LINE_893 () at FIXMsgSuper.mg:893 #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 #2 0x080be01c in FIXMsgSuper4_1__GetSingleField (t=16_09579ea8, ofType=SenderCompID) at FIXMsgSuper.mg:846 #3 0x081087f3 in FIXMsg4_1__T_GetOnlySenderCompIDProc (self=16_09579ea8) at FIXMsg4_1.m3:411 #4 0x080bef29 in FIXEngine4_1__SanityCheckFields (t=16_082a896c, msg=16_09579ea8) at FIXEngine.mg:321 We're in some sort of "fake" stack frame, and... (m3gdb) up #1 0x080be26f in FIXMsgSuper4_1__UINext (i=16_0957a0d4, f=NIL) at FIXMsgSuper.mg:890 890 f := cur; RETURN TRUE (m3gdb) print i $2 = (*16_0957a0d4*) OBJECT t = 16_09579ea8; parts = {Header, Body, Trailer}; fields = {SenderCompID}; part = Body; nextI = 0; END (m3gdb) everything looks OK with i. Is it possible there is some sort of problem with TRY .. FINALLY under PM3? And of course, if so, might it go away with CM3? Mika -------------- next part -------------- An HTML attachment was scrubbed... URL: From wagner at elegosoft.com Sun Feb 15 12:51:49 2009 From: wagner at elegosoft.com (Olaf Wagner) Date: Sun, 15 Feb 2009 12:51:49 +0100 Subject: [M3devel] modula3.org updated links In-Reply-To: <49924DA2.6090607@bellsouth.net> References: <49924DA2.6090607@bellsouth.net> Message-ID: <20090215125149.rgbaxncveok4okw4@mail.elegosoft.com> Quoting Martin Bishop : > A while back I said it would be nice if modula3.org could get it's links > updated, as quite a few of them were dead. Well I went through the > links on the front page of modula3.org (as well as the separate "Links" > page) and updated them. > > I only removed one link, and replaced all the dead ones with either > mirrors or just better links. > > (NOTE: They look bad because they aren't using the CSS, but I'm just > putting these up so someone (Olaf?) can save the source and push to the > modula3.org CVS.) > > http://mbishop.esoteriq.org/modula3.org/Modula-3 Resource Page.html > (Main page) > > http://mbishop.esoteriq.org/modula3.org/index.html (Links page) I've downloaded the pages, but I'm not able to get a meaningful diff listing, as there are so many arbitrary changes, even ignoring all blanks, newlines, and case, that I don't have the time to check them. I don't want to put them up without testing, as images seem to be broken, for example, and changes in the case of tags don't improve maintainability. There also seem to be some strange changes in the location of pages, like s/images/Modula-3%20Resource%20Page_files/, which simply don't look right. Couldn't you send a minimal diff with just the substitutions needed, without any unnecessary changes? Or simply a list like an sed script with s/old link/new link/? That would make it considerably easier to integrate them for me. Don't misunderstand me, I think it's great that you've checked and updated all the links, and would like to put the new information on the server, but I cannot spend too much time on it. As a general rule, changes in layout and style which don't affect the funtionality of a page should be separated from content changes, which need to be checked in a different way. Thanks in advance for your understanding and help, Olaf -- Olaf Wagner -- elego Software Solutions GmbH Gustav-Meyer-Allee 25 / Geb?ude 12, 13355 Berlin, Germany phone: +49 30 23 45 86 96 mobile: +49 177 2345 869 fax: +49 30 23 45 86 95 http://www.elegosoft.com | Gesch?ftsf?hrer: Olaf Wagner | Sitz: Berlin Handelregister: Amtsgericht Charlottenburg HRB 77719 | USt-IdNr: DE163214194 From hosking at cs.purdue.edu Mon Feb 16 00:31:54 2009 From: hosking at cs.purdue.edu (Tony Hosking) Date: Mon, 16 Feb 2009 10:31:54 +1100 Subject: [M3devel] Tinderbox failures Message-ID: Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 02:42:25 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 01:42:25 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From jay.krell at cornell.edu Mon Feb 16 03:15:02 2009 From: jay.krell at cornell.edu (Jay) Date: Mon, 16 Feb 2009 02:15:02 +0000 Subject: [M3devel] Tinderbox failures In-Reply-To: References: Message-ID: I think it depends on what cm3 you start with. I noticed the Tinderbox has "last-ok" runs and "last-release" runs. last-ok appears to be working. last-release has the error. Updating my current cygwin build seemed to work. Starting with 5.4 (which is what last release appears to be) on Linux/x86 gave me a cm3 that just seg faults. I'll try to dig more. - Jay From: jay.krell at cornell.eduTo: hosking at cs.purdue.edu; m3devel at elegosoft.com; m3commit at elegosoft.comSubject: RE: [M3devel] Tinderbox failuresDate: Mon, 16 Feb 2009 01:42:25 +0000 Linux/x86 and FreeBSD/x86 also (ie: I think all). http://tinderbox.elegosoft.com/tinderbox/cm3/status.html === package m3-libs/m3core ===12575 +++ cm3 -build -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? && cm3 -ship -DROOT=?/pub/users/m3/work/cm3-ws/new.elego.de-2009-02-15-02-46-59/cm3? -DCM3_VERSION_TEXT=?d5.7.1? -DCM3_VERSION_NUMBER=?050701? -DCM3_LAST_CHANGED=?2009-01-21? +++12576 --- building in FreeBSD4 ---12577 12578 ignoring ../src/m3overrides12579 12580 12581 12582 ***12583 NEXT *** runtime error:12584 *** An enumeration or subrange value was out of range.12585 *** file "../src/text/Text.m3", line 88212586 ***12587 12588 Abort trap (core dumped)I'll probably look shortly. - Jay From: hosking at cs.purdue.eduTo: m3devel at elegosoft.com; m3commit at elegosoft.comDate: Mon, 16 Feb 2009 10:31:54 +1100Subject: [M3devel] Tinderbox failures Solaris builds are failing with an enumeration/subrange bounds runtime error in Text.m3. This is since the alternative text implementation was checked in. Can someone look into what might be the problem? Or should we back out the new text code. Antony Hosking | Associate Professor | Computer Science | Purdue University 305 N. University Street | West Lafayette | IN 47907 | USA Office +1 765 494 6001 | Mobile +1 765 427 5484 -------------- next part -------------- An HTML attachment was scrubbed... URL: From rodney.bates at wichita.edu Mon Feb 16 04:16:27 2009 From: rodney.bates at wichita.edu (Rodney M. Bates) Date: Sun, 15 Feb 2009 21:16:27 -0600 Subject: [M3devel] [M3commit] CVS Update: cm3 In-Reply-To: <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> References: <20090213175057.0F14810D4300@birch.elegosoft.com> <4995B9A8.5020403@wichita.edu> <20090214235519.a7c4u89yv44swscw@mail.elegosoft.com> Message-ID: <4998DA8B.7000605@wichita.edu> I managed to get the trunk back to the original code, as I intended. The Tinderbox failure is undoubtedly a bug in the new stuff. But it leaves me with more CVS questions, see below. Olaf Wagner wrote: > Quoting "Rodney M. Bates" : > >> Well, I can work on compilers, debuggers, and functional text >> packages, but >> I can never operate CVS correctly. >> >> As far as I can tell, I think I got these checkins done in the trunk, >> rather >> than the branch I created for them. I created a tag on the trunk, >> "devel_m3core_text_2009_02_13", then created a branch with tag >> "devel_m3core_text_newtext_branch". Apparently I got that much right. >> >> But I am not sure whether the changed files went into the branch. My >> CVS book reads as if just a cvs tag -b ..., followed by a cvs commit >> will do the commits in the branch, but the commit message doesn't look >> like that happened. >> >> Can anybody help me with: >> 1) What really happened? >> 2) How should I have done this? > > You probably forgot to update your workspace to the branch: > > cvs up -r devel_m3core_text_newtext_branch This command is in the recipe in my book, but my book assumes you make a branch first, get a copy of the trunk code, edit that, then commit. I had done the coding first, naively thinking I could just create a branch when ready to commit it. So I deliberately left this step out, thinking (rightly, as it turned out) that it would overlay my work with the unmodified code. So today, I made safe copies in other directories of both versions and started trying to unravel things. Sure enough, the update -r promptly replaced my new code with the old. I used a different machine to do updates, and quickly found I now had the new code in the trunk and the old code in the branch. And of course, update -A first overlaid the old code I had now put in my text directory with what is in the repository trunk (the modified code), before clearing the sticky tag. By going through procedures doing CVS commands, interspersed with copying versions of the code from my backup directories to the text directory, I managed to get the trunk straightened out, (I think.) But it was convoluted. To do any of this reasonably, I need a command that changes the sticky tag CVS considers me to be working on (like the -r and -A options of update), but without the undesired side effect of also overlaying my local directory with what was in old tagged version, before changing the sticky tag. Is there such a command? I will worry about the getting the new code into the branch tomorrow. > > After that, the branch tag will be `sticky' in your workspace, until > you use cvs up -A, which clears it again (and transports you to the trunk). > >> 3) How can I fix the damage? > > Well, you can easily revert the changes on the main trunk by checking > out the latest version and using -j old-version -j current version, > and then commit it. This should put the old-version at the head of > the trunk again. Before you do that, you should probably commit everything > to the branch, thus you don't need to checkout your version again. > > I think the version before yours was tagged devel_m3core_d2_4_0. > > But perhaps it is not necessary to do this? Have tou had feedback > from others about the new sources? If nothing breaks and performance > gets better, I won't complain ;-) > > Thanks for all the work, > > Olaf > >> PS: I believe that if you use the new files with no additional action, >> that you >> will get the same behavior as before, except that there will be >> considerable >> constant-time slowdown due to lots of instrumentation and dynamic >> deciding to >> use the original algorithms. But I have not tested this. > > So probably some improvements are needed before a release. From dabenavidesd at yahoo.es Mon Feb 16 05:25:53 2009 From: dabenavidesd at yahoo.es (Daniel Alejandro Benavides D.) Date: Sun, 15 Feb 2009 20:25:53 -0800 (PST) Subject: [M3devel] Question about PM3 In-Reply-To: <954132.49377.qm@web24715.mail.ird.yahoo.com> Message-ID: <793526.97016.qm@web24715.mail.ird.yahoo.com> Hi all, Better more accurately to the language definition check before the mentioned line 890: ISTYPE(cur, FIXField.T) OR ISTYPE(f, ProtocolFields.T) (*is cur a member of f's type, FIXField.T or is f? a member of cur's type, ProtocolFields.T, that is ProtocolFields.T <: FIXField? OR FIXField.T <: ProtocolFields.T *)? Thanks and sorry about the forgot detail. --- El dom, 15/2/09, Daniel Alejandro Benavides D. escribi?: De: Daniel Alejandro Benavides D. Asunto: Re: [M3devel] Question about PM3 Para: "Mika Nystrom" CC: m3devel at elegosoft.com Fecha: domingo, 15 febrero, 2009 12:27 Hi Mika, cur should be type ProtocolFields.T if the NARROW doesn't crash the app, 887 cur = NARROW(seq.get(i.nextI),ProtocolFields.T)(that works if seq.get(i.nextI) is a member of ProtocolFields.T) however could be possible