diff options
| -rw-r--r-- | ChangeLog | 40 | ||||
| -rw-r--r-- | cancel.c | 25 | ||||
| -rw-r--r-- | create.c | 22 | ||||
| -rw-r--r-- | exit.c | 2 | ||||
| -rw-r--r-- | global.c | 12 | ||||
| -rw-r--r-- | implement.h | 22 | ||||
| -rw-r--r-- | misc.c | 15 | ||||
| -rw-r--r-- | private.c | 6 | ||||
| -rw-r--r-- | sched.c | 8 | ||||
| -rw-r--r-- | signal.c | 9 | ||||
| -rw-r--r-- | sync.c | 37 | 
11 files changed, 128 insertions, 70 deletions
@@ -1,5 +1,45 @@  Tue Jul 28 14:04:29 1998  Ross Johnson  <rpj@swan.canberra.edu.au> +	* implement.h: Add _PTHREAD_VALID macro. + +	* sync.c (pthread_join): Modify to use the new thread +	type and _pthread_delete_thread(). Rename "target" to "thread". +	Remove extra local variable "target". +	(pthread_detach): Ditto. + +	* signal.c (pthread_sigmask): Move init of "us" out of inner block. +	Fix instance of "this" should have been "us". Rename "us" to "thread". + +	* sched.c (pthread_setschedparam): Modify to use the new thread +	type. +	(pthread_getschedparam): Ditto. + +	* private.c (_pthread_find_thread): Fix return type and arg. + +	* implement.h: Remove _PTHREAD_YES and _PTHREAD_NO. +	(_pthread_new_thread): Add prototype. +	(_pthread_find_thread): Ditto. +	(_pthread_delete_thread): Ditto. +	(_pthread_new_thread_entry): Remove prototype. +	(_pthread_find_thread_entry): Ditto. +	(_pthread_delete_thread_entry): Ditto. +	(  _PTHREAD_NEW, _PTHREAD_INUSE, _PTHREAD_EXITED, _PTHREAD_REUSE): +	Add. + + +	* create.c (pthread_create): Minor rename "us" to "new" (I need +	these cues but it doesn't stop me coming out with some major bugs +	at times). +	Load start_routine and arg into the thread so the wrapper can +	call it. + +	* exit.c (pthread_exit): Fix pthread_this should be pthread_self. + +	* cancel.c (pthread_setcancelstate): Change + 	_pthread_threads_thread_t * to pthread_t and init with + 	pthread_this(). +	(pthread_setcanceltype): Ditto. +  	* exit.c (_pthread_exit): Add new pthread_t arg.  	Rename _pthread_delete_thread_entry to _pthread_delete_thread.  	Rename "us" to "thread". @@ -12,7 +12,7 @@ int  pthread_setcancelstate(int state,  		       int *oldstate)  { -  _pthread_threads_thread_t * us = _PTHREAD_THIS; +  pthread_t us = pthread_self();    /* Validate the new cancellation state. */    if (state != PTHREAD_CANCEL_ENABLE  @@ -33,7 +33,7 @@ pthread_setcancelstate(int state,  int  pthread_setcanceltype(int type, int *oldtype)  { -  _pthread_threads_thread_t * us = _PTHREAD_THIS; +  pthread_t us = pthread_self();    /* Validate the new cancellation type. */    if (type != PTHREAD_CANCEL_DEFERRED  @@ -54,32 +54,29 @@ pthread_setcanceltype(int type, int *oldtype)  int  pthread_cancel(pthread_t thread)  { -  _pthread_threads_thread_t * us = _PTHREAD_THIS; - -  if (us == NULL) +  if (_PTHREAD_VALID(thread) +      && thread->ptstatus != _PTHREAD_REUSE)      { -      return ESRCH; +      thread->cancel_pending = TRUE; +      return 0;      } -  us->cancel_pending = TRUE; - -  return 0; +  return ESRCH;  }  void  pthread_testcancel(void)  { -  _pthread_threads_thread_t * us; +  pthread_t thread; -  us = _PTHREAD_THIS; +  thread = pthread_self(); -  if (us == NULL -      || us->cancelstate == PTHREAD_CANCEL_DISABLE) +  if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)      {        return;      } -  if (us->cancel_pending == TRUE) +  if (thread->cancel_pending == TRUE)      {        pthread_exit(PTHREAD_CANCELED); @@ -17,7 +17,7 @@ unsigned  _pthread_start_call(void * us_arg)  {    /* We're now in a running thread. Any local variables here are on -     this threads private stack so we're safe to leave data in them +     this thread's private stack so we're safe to leave data in them       until we leave. */    pthread_t us;    _pthread_call_t * call; @@ -56,21 +56,21 @@ pthread_create(pthread_t *thread,    void *   security = NULL;    DWORD  threadID;    pthread_attr_t * attr_copy; -  pthread_t us; +  pthread_t new;    /* Success unless otherwise set. */    int ret;    /* CRITICAL SECTION */    pthread_mutex_lock(&_pthread_table_mutex); -  ret = _pthread_new_thread(&us); +  ret = _pthread_new_thread(&new);    pthread_mutex_lock(&_pthread_table_mutex);    /* END CRITICAL SECTION */    if (ret == 0)      { -      attr_copy = &(us->attr); +      attr_copy = &(new->attr);        /* Map given attributes otherwise just use default values. */        if (attr != NULL)  @@ -88,13 +88,17 @@ pthread_create(pthread_t *thread,  #endif /* HAVE_SIGSET_T */  	} +      /* We call a generic wrapper which then calls the start routine. */ +      new->call.routine = start_routine; +      new->call.arg = arg; +        /* Start running, not suspended. */        flags = 0;        handle = (HANDLE) _beginthreadex(security,  				       attr_copy->stacksize,  				       _pthread_start_call, -				       (void *) us, +				       (void *) new,  				       flags,  				       &threadID); @@ -111,9 +115,9 @@ pthread_create(pthread_t *thread,    if (ret == 0)      {        /* Let the caller know the thread handle. */ -      us->win32handle = handle; -      us->ptstatus = _PTHREAD_INUSE; -      *thread = (pthread_t) us; +      new->win32handle = handle; +      new->ptstatus = _PTHREAD_INUSE; +      *thread = new;      }    else      { @@ -121,7 +125,7 @@ pthread_create(pthread_t *thread,        pthread_mutex_lock(&_pthread_table_mutex);        /* Remove the failed thread entry. */ -      _pthread_delete_thread(us); +      _pthread_delete_thread(new);        pthread_mutex_lock(&_pthread_table_mutex);        /* END CRITICAL SECTION */ @@ -69,5 +69,5 @@ _pthread_exit(pthread_t thread, void * value, int return_code)  void  pthread_exit(void * value)  { -  _pthread_exit(pthread_this(), value, 0); +  _pthread_exit(pthread_self(), value, 0);  } @@ -38,8 +38,16 @@ pthread_mutex_t _pthread_table_mutex = PTHREAD_MUTEX_INITIALIZER;  DWORD _pthread_threads_count = 0; -/* Per thread management storage. */ -_pthread_threads_thread_t _pthread_threads_table[PTHREAD_THREADS_MAX]; +/* Per thread management storage. See comments in private.c */ +_pthread_t _pthread_virgins[PTHREAD_THREADS_MAX]; + +int _pthread_virgin_next = 0; + +pthread_t _pthread_reuse[PTHREAD_THREADS_MAX]; + +int _pthread_reuse_top = -1; + +pthread_t _pthread_win32handle_map[PTHREAD_THREADS_MAX];  /* Per thread mutex locks. */  pthread_mutex_t _pthread_threads_mutex_table[PTHREAD_THREADS_MAX]; diff --git a/implement.h b/implement.h index c19e6b9..5ee9ba3 100644 --- a/implement.h +++ b/implement.h @@ -9,8 +9,17 @@  #define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX) -#define _PTHREAD_YES 1 -#define _PTHREAD_NO  0 +enum { +  _PTHREAD_NEW, +  _PTHREAD_INUSE, +  _PTHREAD_EXITED, +  _PTHREAD_REUSE +}; + +#define _PTHREAD_VALID(T) \ +  (T) != NULL \ +  && ((T)->ptstatus == _PTHREAD_NEW +      || (T)->ptstatus == _PTHREAD_INUSE)  /* Handler execution flags. */  #define _PTHREAD_HANDLER_NOEXECUTE 0 @@ -103,18 +112,17 @@ void _pthread_handler_pop_all(int stack,  /* Primitives to manage threads table entries. */ -int _pthread_new_thread_entry(pthread_t thread, -			      _pthread_threads_thread_t * entry); +int _pthread_new_thread(pthread_t * thread); -_pthread_threads_thread_t * _pthread_find_thread_entry(pthread_t thread); +pthread_t _pthread_find_thread(HANDLE win32handle); -void _pthread_delete_thread_entry(_pthread_threads_thread_t * this); +int _pthread_delete_thread(pthread_t thread);  /* Thread cleanup. */  void _pthread_vacuum(void); -void _pthread_exit(void * value, int return_code); +void _pthread_exit(pthread_t thread, void * value, int return_code);  #ifdef __cplusplus  } @@ -49,15 +49,22 @@ pthread_self(void)       that all of the Win32 functions we are going to use only need       HANDLEs.  The morons. */ +  /* FIXME: Need a new lookup method with the new thread allocation +     scheme. + +     We can use the Win32 handle though as a basis (perhaps +     to look up a table) because pthread_self() will never be called +     after the Win32 thread has terminated (unless we can raise +     ourselves from the dead!), and therefore the Win32 handle cannot +     have been reused yet. */ + +#if 0    return GetCurrentThread(); +#endif  }  int  pthread_equal(pthread_t t1, pthread_t t2)  { -  /* For the time being, assume that HANDLEs can be directly compared. -     If not, then use the appropriate Win32 function for -     comparison. */ -    return (t1 != t2);  } @@ -135,10 +135,10 @@ _pthread_new_thread(pthread_t * thread)    return 0;  } -_pthread_threads_thread * -_pthread_find_thread(pthread_t thread) +pthread_t +_pthread_find_thread((HANDLE) win32handle)  { -  /* Should no longer be needed */ +  /* FIXME: No-op at present */  }  int @@ -36,7 +36,7 @@ int pthread_setschedparam(pthread_t thread, int policy,  			  const struct sched_param *param)  {    /* Validate the thread id. */ -  if (_pthread_find_thread_entry(thread) < 0) +  if (_PTHREAD_VALID(thread) < 0)      {        return EINVAL;      } @@ -61,7 +61,7 @@ int pthread_setschedparam(pthread_t thread, int policy,      }    /* This is practically guaranteed to return TRUE. */ -  (void) SetThreadPriority(thread, param->sched_policy); +  (void) SetThreadPriority(thread->win32handle, param->sched_policy);    return 0;  } @@ -71,7 +71,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,    int prio;    /* Validate the thread id. */ -  if (_pthread_find_thread_entry(thread) < 0) +  if (_PTHREAD_VALID(thread) != 0)      {        return EINVAL;      } @@ -86,7 +86,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,    *policy = SCHED_OTHER;    /* Fill out the sched_param structure. */ -  prio = GetThreadPriority(thread); +  prio = GetThreadPriority(thread->win32handle);    if (prio == THREAD_PRIORITY_ERROR_RETURN)      {        return EINVAL; @@ -10,6 +10,8 @@  int  pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)  { +  pthread_t thread = pthread_self(); +    /* Validate the `how' argument.*/    if (set != NULL)      { @@ -30,19 +32,18 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)    /* Copy the old mask before modifying it. */    if (oset != NULL)      { -      memcpy(oset, this->attr->sigmask, sizeof(sigset_t)); +      memcpy(oset, thread->attr.sigmask, sizeof(sigset_t));      }    if (set != NULL)      { -      _pthread_threads_thread_t * us = _PTHREAD_THIS;        int i;        /* FIXME: this code assumes that sigmask is an even multiple of  	 the size of a long integer. */         unsigned long *src = set; -      unsigned long *dest = us->attr.sigmask; +      unsigned long *dest = thread->attr.sigmask;        switch (how)  	{ @@ -61,7 +62,7 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)  	    }  	case SIG_SET:  	  /* Replace the whole sigmask. */ -	  memcpy(us->attr.sigmask, set, sizeof(sigset_t)); +	  memcpy(thread->attr.sigmask, set, sizeof(sigset_t));  	  break;  	}      } @@ -57,7 +57,6 @@ pthread_join(pthread_t thread, void ** valueptr)  {    LPDWORD exitcode;    int detachstate; -  _pthread_threads_thread_t * target;    /* First check if we are trying to join to ourselves. */    if (thread == pthread_self()) @@ -65,15 +64,12 @@ pthread_join(pthread_t thread, void ** valueptr)        return EDEADLK;      } -  /* Find the thread. */ -  target = _pthread_find_thread_entry(thread); - -  if (target != NULL) +  if (thread != NULL)      {        pthread_mutex_t * target_thread_mutex;        int ret; -      target_thread_mutex = _PTHREAD_THREAD_MUTEX(target); +      target_thread_mutex = _PTHREAD_THREAD_MUTEX(thread);        /* CRITICAL SECTION */        pthread_mutex_lock(&_pthread_table_mutex); @@ -81,13 +77,13 @@ pthread_join(pthread_t thread, void ** valueptr)        /* If the thread is in DETACHED state, then join will return  	 immediately. */ -      if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0  +      if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0   	  || detachstate == PTHREAD_CREATE_DETACHED)  	{  	  return EINVAL;  	} -      target->join_count++; +      thread->join_count++;        pthread_mutex_lock(&_pthread_table_mutex);        /* END CRITICAL SECTION */ @@ -96,7 +92,7 @@ pthread_join(pthread_t thread, void ** valueptr)        pthread_testcancel();        /* Wait on the kernel thread object. */ -      switch (WaitForSingleObject(thread, INFINITE)) +      switch (WaitForSingleObject(thread->win32handle, INFINITE))  	{  	case WAIT_FAILED:  	  /* The thread does not exist. */ @@ -121,27 +117,27 @@ pthread_join(pthread_t thread, void ** valueptr)        /* Collect the value pointer passed to pthread_exit().  If  	 another thread detaches our target thread while we're  	 waiting, then we report a deadlock as it likely that storage -	 pointed to by target->joinvalueptr has been freed or +	 pointed to by thread->joinvalueptr has been freed or  	 otherwise no longer valid. */ -      if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0  +      if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0   	  || detachstate == PTHREAD_CREATE_DETACHED)  	{  	  ret = EDEADLK;  	}        else  	{ -	  *value_ptr = target->joinvalueptr; +	  *value_ptr = thread->joinvalueptr;  	  ret = 0;  	} -      target->join_count--; +      thread->join_count--;        /* If we're the last join to return then we are responsible for  	 removing the target thread's table entry. */ -      if (target->join_count == 0) +      if (thread->join_count == 0)  	{ -	  _pthread_delete_thread_entry(target); +	  ret = _pthread_delete_thread(thread);  	}        pthread_mutex_lock(&_pthread_table_mutex); @@ -157,7 +153,6 @@ pthread_join(pthread_t thread, void ** valueptr)  int  pthread_detach(pthread_t thread)  { -  _pthread_threads_thread_t * target;    int detachstate;    int ret;    pthread_mutex_t * target_thread_mutex; @@ -165,19 +160,17 @@ pthread_detach(pthread_t thread)    /* CRITICAL SECTION */    pthread_mutex_lock(&_pthread_table_mutex); -  target = _pthread_find_thread_entry(thread); - -  if (target == NULL) +  if (thread == NULL)      {        ret = ESRCH;      }    else      { -      target_thread_mutex = _PTHREAD_THREAD_MUTEX(target); +      target_thread_mutex = _PTHREAD_THREAD_MUTEX(thread);        /* Check that we can detach this thread. */ -      if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0  +      if (pthread_attr_getdetachedstate(&(thread->attr), &detachstate) != 0   	  || detachstate == PTHREAD_CREATE_DETACHED)  	{  	  ret = EINVAL; @@ -188,7 +181,7 @@ pthread_detach(pthread_t thread)  	  /* This is all we do here - the rest is done either when the  	     thread exits or when pthread_join() exits. Once this is  	     set it will never be unset. */ -	  pthread_attr_setdetachedstate(&(target->attr),  +	  pthread_attr_setdetachedstate(&(thread->attr),   					PTHREAD_CREATE_DETACHED);  	  ret = 0;  | 
