[M3devel] elminating pthread_attr_t from cloned headers

Jay jay.krell at cornell.edu
Wed Feb 4 23:01:58 CET 2009


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 *)
>


More information about the M3devel mailing list