diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 1997-11-19 22:10:51 -0800 |
---|---|---|
committer | Malcolm Beattie <mbeattie@sable.ox.ac.uk> | 1997-11-25 14:16:29 +0000 |
commit | 52e1cb5ebf5e5a8cd5d3d9673b540b0c0dfe20df (patch) | |
tree | 078676a210b97f20bbebc123cfe028728a29a04e | |
parent | 51dd5992be029393cb3f221313a1a6ec2a76c21a (diff) | |
download | perl-52e1cb5ebf5e5a8cd5d3d9673b540b0c0dfe20df.tar.gz |
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
-rwxr-xr-x | Configure | 71 | ||||
-rw-r--r-- | config_h.SH | 18 | ||||
-rw-r--r-- | cv.h | 2 | ||||
-rw-r--r-- | ext/DB_File/DB_File.xs | 5 | ||||
-rw-r--r-- | ext/Thread/Makefile.PL | 6 | ||||
-rw-r--r-- | ext/Thread/Thread.pm | 4 | ||||
-rw-r--r-- | ext/Thread/Thread.xs | 27 | ||||
-rw-r--r-- | fakethr.h | 4 | ||||
-rw-r--r-- | hints/aix.sh | 31 | ||||
-rw-r--r-- | perl.c | 10 | ||||
-rw-r--r-- | perl.h | 10 | ||||
-rw-r--r-- | pp.h | 2 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | sv.h | 2 | ||||
-rw-r--r-- | thread.h | 18 | ||||
-rw-r--r-- | util.c | 16 | ||||
-rw-r--r-- | win32/win32thread.c | 4 | ||||
-rw-r--r-- | win32/win32thread.h | 6 |
18 files changed, 197 insertions, 41 deletions
@@ -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 <<EOCP +/* Note: this program returns 1 if detached, 0 if not. + * Easier this way because the PTHREAD_CREATE_DETACHED is more + * portable than the obsolete PTHREAD_CREATE_UNDETACHED. + * Testing for joinable (aka undetached) as opposed to detached + * is then again logically more sensible because that's + * the more modern default state in the pthreads implementations. */ +#include <pthread.h> +#include <stdio.h> +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 75751439c6..7b625e3119 100644 --- a/config_h.SH +++ b/config_h.SH @@ -566,6 +566,18 @@ sed <<!GROK!THIS! >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 <<!GROK!THIS! >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. */ @@ -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 959f3425eb..b6e8a03792 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 <sys/cdefs.h> (which will be + * shortly #included by the <db.h>) __attribute__ to the possibly + * already defined __attribute__, for example by GNUC or by Perl. */ +#undef __attribute__ + #include <db.h> /* #ifdef DB_VERSION_MAJOR */ /* #include <db_185.h> */ diff --git a/ext/Thread/Makefile.PL b/ext/Thread/Makefile.PL index d699091cc1..bed0db43d7 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 1936142e52..48ca3047b9 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 0844312dd4..17c724ac9d 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 @@ -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 2c42151ea6..8869a23c5c 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 <wscott@ichips.intel.com> # AIX 4.1 hints thanks to Christopher Chan-Nui <channui@austin.ibm.com>. +# AIX 4.1 pthreading by Christopher Chan-Nui <channui@austin.ibm.com> and +# Jarkko Hietaniemi <jhi@iki.fi>. # Merged on Mon Feb 6 10:22:35 EST 1995 by # Andy Dougherty <doughera@lafcol.lafayette.edu> @@ -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 @@ -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(); @@ -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 @@ -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 @@ -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)); @@ -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; @@ -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 @@ -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 4dbc750b05..922bef4a5c 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 76392cff77..d2dfe4225c 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 |