Kaydet (Commit) b98b1b3d authored tarafından Guido van Rossum's avatar Guido van Rossum

Tim's changes; removed some remaining non-functional ifdefs

üst 2c8cb9f3
...@@ -38,10 +38,6 @@ static void _init_thread _P0() ...@@ -38,10 +38,6 @@ static void _init_thread _P0()
*/ */
int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
{ {
#if defined(SGI_THREADS) && defined(USE_DL)
long addr, size;
static int local_initialized = 0;
#endif /* SGI_THREADS and USE_DL */
int success = 0; /* init not needed when SOLARIS_THREADS and */ int success = 0; /* init not needed when SOLARIS_THREADS and */
/* C_THREADS implemented properly */ /* C_THREADS implemented properly */
......
...@@ -52,10 +52,6 @@ static void _init_thread _P0() ...@@ -52,10 +52,6 @@ static void _init_thread _P0()
int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
{ {
thread_t tid; thread_t tid;
#if defined(SGI_THREADS) && defined(USE_DL)
long addr, size;
static int local_initialized = 0;
#endif /* SGI_THREADS and USE_DL */
int success = 0; /* init not needed when SOLARIS_THREADS and */ int success = 0; /* init not needed when SOLARIS_THREADS and */
/* C_THREADS implemented properly */ /* C_THREADS implemented properly */
......
...@@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef FLORIDA_HACKS #ifdef FLORIDA_HACKS
/* Hacks for Florida State Posix threads implementation */ /* Hacks for Florida State Posix threads implementation */
#undef _POSIX_THREADS #undef _POSIX_THREADS
#include "/ufs/guido/src/python/Contrib/pthreads/pthreads/pthread.h" #include "/ufs/guido/src/python/Contrib/pthreads/src/pthread.h"
#define pthread_attr_default ((pthread_attr_t *)0) #define pthread_attr_default ((pthread_attr_t *)0)
#define pthread_mutexattr_default ((pthread_mutexattr_t *)0) #define pthread_mutexattr_default ((pthread_mutexattr_t *)0)
#define pthread_condattr_default ((pthread_condattr_t *)0) #define pthread_condattr_default ((pthread_condattr_t *)0)
...@@ -40,26 +40,30 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ...@@ -40,26 +40,30 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif /* FLORIDA_HACKS */ #endif /* FLORIDA_HACKS */
#include <stdlib.h> #include <stdlib.h>
/* A pthread mutex isn't sufficient to model the Python lock type (at /* A pthread mutex isn't sufficient to model the Python lock type
* least not the way KSR did 'em -- haven't dug thru the docs to verify), * because, according to Draft 5 of the docs (P1003.4a/D5), both of the
* because a thread that locks a mutex can't then do a pthread_mutex_lock * following are undefined:
* on it (to wait for another thread to unlock it). * -> a thread tries to lock a mutex it already has locked
* In any case, pthread mutexes are designed for serializing threads over * -> a thread tries to unlock a mutex locked by a different thread
* short pieces of code, so wouldn't be an appropriate implementation of * pthread mutexes are designed for serializing threads over short pieces
* of code anyway, so wouldn't be an appropriate implementation of
* Python's locks regardless. * Python's locks regardless.
* The pthread_lock struct below implements a Python lock as a pthread *
* mutex and a <condition, mutex> pair. In general, if the mutex can be * The pthread_lock struct implements a Python lock as a "locked?" bit
* be acquired instantly, it is, else the pair is used to block the * and a <condition, mutex> pair. In general, if the bit can be acquired
* thread until the mutex is released. 7 May 1994 tim@ksr.com * instantly, it is, else the pair is used to block the thread until the
* bit is cleared. 9 May 1994 tim@ksr.com
*/ */
typedef struct { typedef struct {
/* the lock */ char locked; /* 0=unlocked, 1=locked */
pthread_mutex_t mutex; /* a <cond, mutex> pair to handle an acquire of a locked lock */
/* a <cond, mutex> pair to handle an acquire of a locked mutex */ pthread_cond_t lock_released;
pthread_cond_t cond; pthread_mutex_t mut;
pthread_mutex_t cmutex;
} pthread_lock; } pthread_lock;
#define CHECK_STATUS(name) if (status < 0) { perror(name); error=1; }
/* /*
* Initialization. * Initialization.
*/ */
...@@ -70,6 +74,8 @@ static void _init_thread _P0() ...@@ -70,6 +74,8 @@ static void _init_thread _P0()
/* /*
* Thread support. * Thread support.
*/ */
int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
{ {
#if defined(SGI_THREADS) && defined(USE_DL) #if defined(SGI_THREADS) && defined(USE_DL)
...@@ -135,30 +141,25 @@ void _exit_prog _P1(status, int status) ...@@ -135,30 +141,25 @@ void _exit_prog _P1(status, int status)
type_lock allocate_lock _P0() type_lock allocate_lock _P0()
{ {
pthread_lock *lock; pthread_lock *lock;
int status, error = 0;
dprintf(("allocate_lock called\n")); dprintf(("allocate_lock called\n"));
if (!initialized) if (!initialized)
init_thread(); init_thread();
lock = (pthread_lock *) malloc(sizeof(pthread_lock)); lock = (pthread_lock *) malloc(sizeof(pthread_lock));
{ if (lock) {
int err = 0; lock->locked = 0;
if ( pthread_mutex_init(&lock->mutex,
pthread_mutexattr_default) ) { status = pthread_mutex_init(&lock->mut,
perror("pthread_mutex_init"); pthread_mutexattr_default);
err = 1; CHECK_STATUS("pthread_mutex_init");
}
if ( pthread_cond_init(&lock->cond, status = pthread_cond_init(&lock->lock_released,
pthread_condattr_default) ) { pthread_condattr_default);
perror("pthread_cond_init"); CHECK_STATUS("pthread_cond_init");
err = 1;
} if (error) {
if ( pthread_mutex_init(&lock->cmutex,
pthread_mutexattr_default)) {
perror("pthread_mutex_init");
err = 1;
}
if (err) {
free((void *)lock); free((void *)lock);
lock = 0; lock = 0;
} }
...@@ -170,80 +171,82 @@ type_lock allocate_lock _P0() ...@@ -170,80 +171,82 @@ type_lock allocate_lock _P0()
void free_lock _P1(lock, type_lock lock) void free_lock _P1(lock, type_lock lock)
{ {
pthread_lock *thelock = (pthread_lock *)lock;
int status, error = 0;
dprintf(("free_lock(%lx) called\n", (long)lock)); dprintf(("free_lock(%lx) called\n", (long)lock));
if ( pthread_mutex_destroy(&((pthread_lock *)lock)->mutex) )
perror("pthread_mutex_destroy"); status = pthread_mutex_destroy( &thelock->mut );
if ( pthread_cond_destroy(&((pthread_lock *)lock)->cond) ) CHECK_STATUS("pthread_mutex_destroy");
perror("pthread_cond_destroy");
if ( pthread_mutex_destroy(&((pthread_lock *)lock)->cmutex) ) status = pthread_cond_destroy( &thelock->lock_released );
perror("pthread_mutex_destroy"); CHECK_STATUS("pthread_cond_destroy");
free((void *)lock);
free((void *)thelock);
} }
int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag) int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
{ {
int success; int success;
pthread_lock *thelock = (pthread_lock *)lock;
int status, error = 0;
dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag)); dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
{
pthread_lock *thelock = (pthread_lock *)lock; status = pthread_mutex_lock( &thelock->mut );
success = TRYLOCK_OFFSET + CHECK_STATUS("pthread_mutex_lock[1]");
pthread_mutex_trylock( &thelock->mutex ); success = thelock->locked == 0;
if (success < 0) { if (success) thelock->locked = 1;
perror("pthread_mutex_trylock [1]"); status = pthread_mutex_unlock( &thelock->mut );
success = 0; CHECK_STATUS("pthread_mutex_unlock[1]");
} else if ( success == 0 && waitflag ) {
if ( !success && waitflag ) {
/* continue trying until we get the lock */ /* continue trying until we get the lock */
/* cmutex must be locked by me -- part of the condition /* mut must be locked by me -- part of the condition
* protocol */ * protocol */
if ( pthread_mutex_lock( &thelock->cmutex ) ) status = pthread_mutex_lock( &thelock->mut );
perror("pthread_mutex_lock"); CHECK_STATUS("pthread_mutex_lock[2]");
while ( 0 == (success = TRYLOCK_OFFSET + while ( thelock->locked ) {
pthread_mutex_trylock(&thelock->mutex)) ) { status = pthread_cond_wait(&thelock->lock_released,
if ( pthread_cond_wait(&thelock->cond, &thelock->mut);
&thelock->cmutex) ) CHECK_STATUS("pthread_cond_wait");
perror("pthread_cond_wait");
}
if (success < 0)
perror("pthread_mutex_trylock [2]");
/* now ->mutex & ->cmutex are both locked by me */
if ( pthread_mutex_unlock( &thelock->cmutex ) )
perror("pthread_mutex_unlock");
} }
thelock->locked = 1;
status = pthread_mutex_unlock( &thelock->mut );
CHECK_STATUS("pthread_mutex_unlock[2]");
success = 1;
} }
if (error) success = 0;
dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success)); dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
return success; return success;
} }
void release_lock _P1(lock, type_lock lock) void release_lock _P1(lock, type_lock lock)
{ {
dprintf(("release_lock(%lx) called\n", (long)lock));
{
pthread_lock *thelock = (pthread_lock *)lock; pthread_lock *thelock = (pthread_lock *)lock;
int status, error = 0;
/* tricky: if the release & signal occur between the dprintf(("release_lock(%lx) called\n", (long)lock));
* pthread_mutex_trylock(&thelock->mutex))
* and pthread_cond_wait during the acquire, the acquire status = pthread_mutex_lock( &thelock->mut );
* will miss the signal it's waiting for; locking cmutex CHECK_STATUS("pthread_mutex_lock[3]");
* around the release prevents that
*/ thelock->locked = 0;
if (pthread_mutex_lock( &thelock->cmutex ))
perror("pthread_mutex_lock"); status = pthread_mutex_unlock( &thelock->mut );
if (pthread_mutex_unlock( &thelock->mutex )) CHECK_STATUS("pthread_mutex_unlock[3]");
perror("pthread_mutex_unlock");
if (pthread_mutex_unlock( &thelock->cmutex ))
perror("pthread_mutex_unlock");
/* wake up someone (anyone, if any) waiting on the lock */ /* wake up someone (anyone, if any) waiting on the lock */
if (pthread_cond_signal( &thelock->cond )) status = pthread_cond_signal( &thelock->lock_released );
perror("pthread_cond_signal"); CHECK_STATUS("pthread_cond_signal");
}
} }
/* /*
* Semaphore support. * Semaphore support.
*/ */
/* NOTE: 100% non-functional at this time - tim */
type_sema allocate_sema _P1(value, int value) type_sema allocate_sema _P1(value, int value)
{ {
char *sema = 0; char *sema = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment