[M3devel] elminating pthread_attr_t from cloned headers

Tony Hosking hosking at cs.purdue.edu
Thu Feb 5 00:12:18 CET 2009


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: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090205/7fa57995/attachment-0002.html>


More information about the M3devel mailing list