From: Jarkko Hietaniemi Date: Thu, 20 Nov 1997 06:10:51 +0000 (-0800) Subject: AIX patch (including Configure support for {sched,pthread}_yield, X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=52e1cb5ebf5e5a8cd5d3d9673b540b0c0dfe20df;p=p5sagit%2Fp5-mst-13.2.git AIX patch (including Configure support for {sched,pthread}_yield, pthread initial detach state, renaming perl_thread to perl_os_thread and struct thread to struct perl_thread): Subject: Re: _54 on AIX p4raw-id: //depot/perl@290 --- diff --git a/Configure b/Configure index 1fce22d..b8618cb 100755 --- a/Configure +++ b/Configure @@ -465,6 +465,8 @@ usedl='' fpostype='' gidtype='' groupstype='' +d_sched_yield='' +d_pthread_yield='' h_fcntl='' h_sysfile='' db_hashtype='' @@ -601,6 +603,7 @@ installprivlib='' privlib='' privlibexp='' prototype='' +pthreads_created_joinable='' randbits='' installscript='' scriptdir='' @@ -8549,6 +8552,24 @@ EOM *) groupstype="$gidtype";; esac +case "$usethreads" in +$define) + + : see if sched_yield exists + set sched_yield d_sched_yield + eval $inlibc + + : see if pthread_yield exists + set pthread_yield d_pthread_yield + eval $inlibc + + ;; +*) + d_sched_yield=$undef + d_pthread_yield=$undef + ;; +esac + : see what type lseek is declared as in the kernel set off_t lseektype long stdio.h sys/types.h eval $typedef @@ -9896,6 +9917,53 @@ val="$t_gdbm" set i_gdbm eval $setvar +: test whether pthreads are created in joinable -- aka undetached -- state +if test "X$usethreads" != X; then +echo " " +echo 'Checking whether pthreads are created joinable.' >&4 + $cat >try.c < +#include +int main() { + pthread_attr_t attr; + int detachstate; + pthread_attr_init(&attr); + pthread_attr_getdetachstate(&attr, &detachstate); + printf("%s\n", + detachstate == PTHREAD_CREATE_DETACHED ? + "detached" : "joinable"); + exit(0); +} +EOCP + if $cc $ccflags $ldflags -o try try.c $libs >/dev/null 2>&1; then + yyy=`./try` + else + echo "(I can't seem to compile the test program--assuming they are.)" + yyy=joinable + fi + case "$yyy" in + joinable) + val="$define" + echo "Yup, they are." + ;; + *) + val="$undef" + echo "Nope, they aren't." + ;; + esac + set d_pthreads_created_joinable + eval $setvar + $rm -f try try.* +else + d_pthreads_created_joinable=$undef +fi + echo " " echo "Looking for extensions..." >&4 cd ../ext @@ -10271,6 +10339,7 @@ d_phostname='$d_phostname' d_pipe='$d_pipe' d_poll='$d_poll' d_portable='$d_portable' +d_pthread_yield='$d_pthread_yield' d_pwage='$d_pwage' d_pwchange='$d_pwchange' d_pwclass='$d_pwclass' @@ -10285,6 +10354,7 @@ d_rmdir='$d_rmdir' d_safebcpy='$d_safebcpy' d_safemcpy='$d_safemcpy' d_sanemcmp='$d_sanemcmp' +d_sched_yield='$d_sched_yield' d_seekdir='$d_seekdir' d_select='$d_select' d_sem='$d_sem' @@ -10538,6 +10608,7 @@ prefixexp='$prefixexp' privlib='$privlib' privlibexp='$privlibexp' prototype='$prototype' +pthreads_created_joinable='$pthreads_created_joinable' randbits='$randbits' ranlib='$ranlib' rd_nodata='$rd_nodata' diff --git a/config_h.SH b/config_h.SH index 7575143..7b625e3 100644 --- a/config_h.SH +++ b/config_h.SH @@ -566,6 +566,18 @@ sed <config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un- */ #$d_poll HAS_POLL /**/ +/* HAS_PTHREAD_YIELD: + * This symbol, if defined, indicates that the pthread_yield routine is + * available to yield the execution of the current thread. + */ +#$d_pthread_yield HAS_PTHREAD_YIELD + +/* HAS_SCHED_YIELD: + * This symbol, if defined, indicates that the sched_yield routine is + * available to yield the execution of the current thread. + */ +#$d_sched_yield HAS_SCHED_YIELD + /* HAS_READDIR: * This symbol, if defined, indicates that the readdir routine is * available to read directory entries. You may have to include @@ -1624,6 +1636,12 @@ sed <config.h -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un- */ #$d_sfio USE_SFIO /**/ +/* PTHREADS_CREATED_JOINABLE: + * This symbol, if defined, indicates that pthreads are created + * in the joinable (aka undetached) state. + */ +#$d_pthreads_created_joinable PTHREADS_CREATED_JOINABLE /**/ + /* Sigjmp_buf: * This is the buffer type to be used with Sigsetjmp and Siglongjmp. */ diff --git a/cv.h b/cv.h index d5ffdc2..0eeedfd 100644 --- a/cv.h +++ b/cv.h @@ -30,7 +30,7 @@ struct xpvcv { CV * xcv_outside; #ifdef USE_THREADS perl_mutex *xcv_mutexp; - struct thread *xcv_owner; /* current owner thread */ + struct perl_thread *xcv_owner; /* current owner thread */ #endif /* USE_THREADS */ cv_flags_t xcv_flags; }; diff --git a/ext/DB_File/DB_File.xs b/ext/DB_File/DB_File.xs index 959f342..b6e8a03 100644 --- a/ext/DB_File/DB_File.xs +++ b/ext/DB_File/DB_File.xs @@ -52,6 +52,11 @@ #include "perl.h" #include "XSUB.h" +/* Being the Berkeley DB we prefer the (which will be + * shortly #included by the ) __attribute__ to the possibly + * already defined __attribute__, for example by GNUC or by Perl. */ +#undef __attribute__ + #include /* #ifdef DB_VERSION_MAJOR */ /* #include */ diff --git a/ext/Thread/Makefile.PL b/ext/Thread/Makefile.PL index d699091..bed0db4 100644 --- a/ext/Thread/Makefile.PL +++ b/ext/Thread/Makefile.PL @@ -1,2 +1,6 @@ use ExtUtils::MakeMaker; -WriteMakefile(NAME => "Thread"); +WriteMakefile( + NAME => 'Thread', + VERSION_FROM => 'Thread.pm' + ); + diff --git a/ext/Thread/Thread.pm b/ext/Thread/Thread.pm index 1936142..48ca304 100644 --- a/ext/Thread/Thread.pm +++ b/ext/Thread/Thread.pm @@ -1,6 +1,10 @@ package Thread; require Exporter; require DynaLoader; +use vars qw($VERSION @ISA @EXPORT); + +$VERSION = "1.0"; + @ISA = qw(Exporter DynaLoader); @EXPORT_OK = qw(yield cond_signal cond_broadcast cond_wait async); diff --git a/ext/Thread/Thread.xs b/ext/Thread/Thread.xs index 0844312..17c724a 100644 --- a/ext/Thread/Thread.xs +++ b/ext/Thread/Thread.xs @@ -16,13 +16,13 @@ static U32 threadnum = 0; static int sig_pipe[2]; #ifndef THREAD_RET_TYPE -typedef struct thread *Thread; +typedef struct perl_thread *Thread; #define THREAD_RET_TYPE void * #define THREAD_RET_CAST(x) ((THREAD_RET_TYPE) x) #endif static void -remove_thread(struct thread *t) +remove_thread(struct perl_thread *t) { #ifdef USE_THREADS DEBUG_L(WITH_THR(PerlIO_printf(PerlIO_stderr(), @@ -106,8 +106,8 @@ threadstart(void *arg) /* * It's safe to wait until now to set the thread-specific pointer - * from our pthread_t structure to our struct thread, since we're - * the only thread who can get at it anyway. + * from our pthread_t structure to our struct perl_thread, since + * we're the only thread who can get at it anyway. */ SET_THR(thr); @@ -234,8 +234,27 @@ newthread (SV *startsv, AV *initargs, char *classname) sigfillset(&fullmask); if (sigprocmask(SIG_SETMASK, &fullmask, &oldmask) == -1) croak("panic: sigprocmask"); +#ifdef PTHREADS_CREATED_JOINABLE err = pthread_create(&thr->self, pthread_attr_default, threadstart, (void*) thr); +#else + { + pthread_attr_t attr; + + err = pthread_attr_init(&attr); + if (err == 0) { +#ifdef PTHREAD_CREATE_UNDETACHED + err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED); +#else + croak("panic: pthread_attr_setdetachstate"); +#endif + if (err == 0) + err = pthread_create(&thr->self, &attr, + threadstart, (void*) thr); + } + pthread_attr_destroy(&attr); + } +#endif /* Go */ MUTEX_UNLOCK(&thr->mutex); #endif diff --git a/fakethr.h b/fakethr.h index 596e8a9..8b1e76f 100644 --- a/fakethr.h +++ b/fakethr.h @@ -1,12 +1,12 @@ typedef int perl_mutex; typedef int perl_key; -typedef struct thread *perl_os_thread; +typedef struct perl_thread *perl_os_thread; /* With fake threads, thr is global(ish) so we don't need dTHR */ #define dTHR extern int errno struct perl_wait_queue { - struct thread * thread; + struct perl_thread * thread; struct perl_wait_queue * next; }; typedef struct perl_wait_queue *perl_cond; diff --git a/hints/aix.sh b/hints/aix.sh index 2c42151..8869a23 100644 --- a/hints/aix.sh +++ b/hints/aix.sh @@ -1,6 +1,8 @@ # hints/aix.sh # AIX 3.x.x hints thanks to Wayne Scott # AIX 4.1 hints thanks to Christopher Chan-Nui . +# AIX 4.1 pthreading by Christopher Chan-Nui and +# Jarkko Hietaniemi . # Merged on Mon Feb 6 10:22:35 EST 1995 by # Andy Dougherty @@ -74,3 +76,32 @@ lddlflags='-H512 -T512 -bhalt:4 -bM:SRE -bI:$(PERL_INC)/perl.exp -bE:$(BASEEXT). ;; esac + +if [ "X$usethreads" != "X" ]; then + ccflags="-DUSE_THREADS $ccflags" + cppflags="-DUSE_THREADS $cppflags" + case "$cc" in + xlc_r) + ;; + cc | '') + cc=xlc_r + ;; + *) + case "$cc" in + gcc) + echo >&4 "You cannot use POSIX threads from GNU cc in AIX." + ;; + *) + echo >&4 "Unknown C compiler." + ;; + esac + echo >&4 "You should use the AIX C compiler called xlc_r." + echo >&4 "Cannot continue, aborting." + exit 1 + ;; + esac + + # Add the POSIX threads library and use the re-entrant libc. + + lddlflags=`echo $lddlflags | sed 's/ -lc$/ -lpthreads -lc_r/'` +fi diff --git a/perl.c b/perl.c index 0ff9f4e..923eea5 100644 --- a/perl.c +++ b/perl.c @@ -70,7 +70,7 @@ static void init_debugger _((void)); static void init_lexer _((void)); static void init_main_stash _((void)); #ifdef USE_THREADS -static struct thread * init_main_thread _((void)); +static struct perl_thread * init_main_thread _((void)); #endif /* USE_THREADS */ static void init_perllib _((void)); static void init_postdump_symbols _((int, char **, char **)); @@ -112,7 +112,7 @@ perl_construct(register PerlInterpreter *sv_interp) #ifdef USE_THREADS int i; #ifndef FAKE_THREADS - struct thread *thr; + struct perl_thread *thr; #endif /* FAKE_THREADS */ #endif /* USE_THREADS */ @@ -2777,13 +2777,13 @@ incpush(char *p, int addsubdirs) } #ifdef USE_THREADS -static struct thread * +static struct perl_thread * init_main_thread() { - struct thread *thr; + struct perl_thread *thr; XPV *xpv; - Newz(53, thr, 1, struct thread); + Newz(53, thr, 1, struct perl_thread); curcop = &compiling; thr->cvcache = newHV(); thr->threadsv = newAV(); diff --git a/perl.h b/perl.h index b4e8865..ddeff99 100644 --- a/perl.h +++ b/perl.h @@ -1058,7 +1058,7 @@ union any { }; #ifdef USE_THREADS -#define ARGSproto struct thread *thr +#define ARGSproto struct perl_thread *thr #else #define ARGSproto void #endif /* USE_THREADS */ @@ -1362,18 +1362,18 @@ int runops_debug _((void)); /* global state */ EXT PerlInterpreter * curinterp; /* currently running interpreter */ #ifdef USE_THREADS -EXT perl_key thr_key; /* For per-thread struct thread ptr */ +EXT perl_key thr_key; /* For per-thread struct perl_thread* */ EXT perl_mutex sv_mutex; /* Mutex for allocating SVs in sv.c */ EXT perl_mutex malloc_mutex; /* Mutex for malloc */ EXT perl_mutex eval_mutex; /* Mutex for doeval */ EXT perl_cond eval_cond; /* Condition variable for doeval */ -EXT struct thread * eval_owner; /* Owner thread for doeval */ +EXT struct perl_thread * eval_owner; /* Owner thread for doeval */ EXT int nthreads; /* Number of threads currently */ EXT perl_mutex threads_mutex; /* Mutex for nthreads and thread list */ EXT perl_cond nthreads_cond; /* Condition variable for nthreads */ EXT char * threadsv_names INIT(THREADSV_NAMES); #ifdef FAKE_THREADS -EXT struct thread * thr; /* Currently executing (fake) thread */ +EXT struct perl_thread * thr; /* Currently executing (fake) thread */ #endif #endif /* USE_THREADS */ @@ -1959,7 +1959,7 @@ IEXT SV * Imess_sv; #ifdef USE_THREADS /* threads stuff */ -IEXT SV * Ithrsv; /* holds struct thread for main thread */ +IEXT SV * Ithrsv; /* holds struct perl_thread for main thread */ #endif /* USE_THREADS */ #undef IEXT diff --git a/pp.h b/pp.h index bc39f80..1914fcc 100644 --- a/pp.h +++ b/pp.h @@ -9,7 +9,7 @@ #ifdef USE_THREADS #define ARGS thr -#define dARGS struct thread *thr; +#define dARGS struct perl_thread *thr; #else #define ARGS #define dARGS diff --git a/proto.h b/proto.h index 35ef574..202331b 100644 --- a/proto.h +++ b/proto.h @@ -341,7 +341,7 @@ OP* newUNOP _((I32 type, I32 flags, OP* first)); OP* newWHILEOP _((I32 flags, I32 debuggable, LOOP* loop, I32 whileline, OP* expr, OP* block, OP* cont)); #ifdef USE_THREADS -struct thread * new_struct_thread _((struct thread *t)); +struct perl_thread * new_struct_thread _((struct perl_thread *t)); #endif PerlIO* nextargv _((GV* gv)); char* ninstr _((char* big, char* bigend, char* little, char* lend)); diff --git a/sv.h b/sv.h index fcf9297..2c47399 100644 --- a/sv.h +++ b/sv.h @@ -246,7 +246,7 @@ struct xpvfm { CV * xcv_outside; #ifdef USE_THREADS perl_mutex *xcv_mutexp; /* protects xcv_owner */ - struct thread *xcv_owner; /* current owner thread */ + struct perl_thread *xcv_owner; /* current owner thread */ #endif /* USE_THREADS */ cv_flags_t xcv_flags; diff --git a/thread.h b/thread.h index 5c78e7d..656a693 100644 --- a/thread.h +++ b/thread.h @@ -26,7 +26,11 @@ typedef pthread_t perl_os_thread; #endif #ifndef YIELD -# define YIELD sched_yield() +# ifdef HAS_PTHREAD_YIELD +# define YIELD pthread_yield() +# else +# define YIELD sched_yield() +# endif #endif #ifndef MUTEX_INIT @@ -109,15 +113,15 @@ typedef pthread_t perl_os_thread; #ifndef THR # ifdef OLD_PTHREADS_API -struct thread *getTHR _((void)); +struct perl_thread *getTHR _((void)); # define THR getTHR() # else -# define THR ((struct thread *) pthread_getspecific(thr_key)) +# define THR ((struct perl_thread *) pthread_getspecific(thr_key)) # endif /* OLD_PTHREADS_API */ #endif /* THR */ #ifndef dTHR -# define dTHR struct thread *thr = THR +# define dTHR struct perl_thread *thr = THR #endif /* dTHR */ #ifndef INIT_THREADS @@ -134,7 +138,7 @@ struct thread *getTHR _((void)); # define THREAD_RET_CAST(p) ((void *)(p)) #endif /* THREAD_RET */ -struct thread { +struct perl_thread { /* The fields that used to be global */ /* Important ones in the first cache line (if alignment is done right) */ SV ** Tstack_sp; @@ -224,7 +228,7 @@ struct thread { HV * errhv; /* HV for what was %@ in pp_ctl.c */ perl_mutex mutex; /* For the fields others can change */ U32 tid; - struct thread *next, *prev; /* Circular linked list of threads */ + struct perl_thread *next, *prev; /* Circular linked list of threads */ JMPENV Tstart_env; /* Top of top_env longjmp() chain */ #ifdef HAVE_THREAD_INTERN struct thread_intern i; /* Platform-dependent internals */ @@ -232,7 +236,7 @@ struct thread { char trailing_nul; /* For the sake of thrsv and oursv */ }; -typedef struct thread *Thread; +typedef struct perl_thread *Thread; /* Values and macros for thr->flags */ #define THRf_STATE_MASK 7 diff --git a/util.c b/util.c index 9bdea38..b86f6f5 100644 --- a/util.c +++ b/util.c @@ -2382,14 +2382,14 @@ perl_cond *cp; #endif /* FAKE_THREADS */ #ifdef OLD_PTHREADS_API -struct thread * +struct perl_thread * getTHR _((void)) { pthread_addr_t t; if (pthread_getspecific(thr_key, &t)) croak("panic: pthread_getspecific"); - return (struct thread *) t; + return (struct perl_thread *) t; } #endif /* OLD_PTHREADS_API */ @@ -2438,20 +2438,20 @@ condpair_magic(SV *sv) * called. The use by ext/Thread/Thread.xs in core perl (where t is the * thread calling new_struct_thread) clearly satisfies this constraint. */ -struct thread * -new_struct_thread(struct thread *t) +struct perl_thread * +new_struct_thread(struct perl_thread *t) { - struct thread *thr; + struct perl_thread *thr; SV *sv; SV **svp; I32 i; sv = newSVpv("", 0); - SvGROW(sv, sizeof(struct thread) + 1); - SvCUR_set(sv, sizeof(struct thread)); + SvGROW(sv, sizeof(struct perl_thread) + 1); + SvCUR_set(sv, sizeof(struct perl_thread)); thr = (Thread) SvPVX(sv); /* debug */ - memset(thr, 0xab, sizeof(struct thread)); + memset(thr, 0xab, sizeof(struct perl_thread)); markstack = 0; scopestack = 0; savestack = 0; diff --git a/win32/win32thread.c b/win32/win32thread.c index 4dbc750..922bef4 100644 --- a/win32/win32thread.c +++ b/win32/win32thread.c @@ -15,7 +15,7 @@ Perl_alloc_thread_key(void) } void -Perl_set_thread_self(struct thread *thr) +Perl_set_thread_self(struct perl_thread *thr) { #ifdef USE_THREADS /* Set thr->self. GetCurrentThread() retrurns a pseudo handle, need @@ -33,7 +33,7 @@ Perl_set_thread_self(struct thread *thr) #ifdef USE_THREADS int -Perl_thread_create(struct thread *thr, thread_func_t *fn) +Perl_thread_create(struct perl_thread *thr, thread_func_t *fn) { DWORD junk; diff --git a/win32/win32thread.h b/win32/win32thread.h index 76392cf..d2dfe42 100644 --- a/win32/win32thread.h +++ b/win32/win32thread.h @@ -97,7 +97,7 @@ typedef HANDLE perl_mutex; } \ } STMT_END -#define THR ((struct thread *) TlsGetValue(thr_key)) +#define THR ((struct perl_thread *) TlsGetValue(thr_key)) #define THREAD_CREATE(t, f) Perl_thread_create(t, f) #define THREAD_POST_CREATE(t) NOOP #define THREAD_RET_TYPE DWORD WINAPI @@ -107,8 +107,8 @@ typedef THREAD_RET_TYPE thread_func_t(void *); START_EXTERN_C void Perl_alloc_thread_key _((void)); -int Perl_thread_create _((struct thread *thr, thread_func_t *fn)); -void Perl_set_thread_self _((struct thread *thr)); +int Perl_thread_create _((struct perl_thread *thr, thread_func_t *fn)); +void Perl_set_thread_self _((struct perl_thread *thr)); END_EXTERN_C #define INIT_THREADS NOOP