diff options
author | joeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-08-31 21:49:09 +0000 |
---|---|---|
committer | joeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-08-31 21:49:09 +0000 |
commit | 444c49aa1db88c5de7f4a8a03852a36492f62558 (patch) | |
tree | ef5cd9e2b626062f9b4d93e82a830d26100a9afd /PACE | |
parent | 66f832c091dedb2bfad05893e0860eac7d0979ee (diff) | |
download | ATCD-444c49aa1db88c5de7f4a8a03852a36492f62558.tar.gz |
ChangeLogTag: Fri Aug 31 16:48:10 2001 Joe Hoffert <joeh@cs.wustl.edu>
Diffstat (limited to 'PACE')
-rw-r--r-- | PACE/ChangeLog | 17 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.c | 343 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.h | 8 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.inl | 2 | ||||
-rw-r--r-- | PACE/pace/vxworks/types.h | 3 |
5 files changed, 179 insertions, 194 deletions
diff --git a/PACE/ChangeLog b/PACE/ChangeLog index 09328574bbf..e30de58d5d7 100644 --- a/PACE/ChangeLog +++ b/PACE/ChangeLog @@ -1,3 +1,20 @@ +Fri Aug 31 16:48:10 2001 Joe Hoffert <joeh@cs.wustl.edu> + + * pace/vxworks/types.h: + Removed extraneous blank lines. + + * pace/vxworks/pthread.inl: + Cleaned up comment for popping cleanup routines. + + * pace/vxworks/pthread.c: + Removed duplicate code (for C and C++) and fixed + VxWorks unld errors by making the main thread detached + and unregistering the cleanup function when the + last non-main thread is done. + + * pace/vxworks/pthread.h: + Added PACE_PTHREAD_MUTEX_INITIALIZER initializer. + Fri Aug 24 08:24:43 2001 Joe Hoffert <joeh@cs.wustl.edu> * pace/vxworks/stdio.inl: diff --git a/PACE/pace/vxworks/pthread.c b/PACE/pace/vxworks/pthread.c index ce7dd848f28..512fdc77609 100644 --- a/PACE/pace/vxworks/pthread.c +++ b/PACE/pace/vxworks/pthread.c @@ -18,10 +18,12 @@ /* pthread queue */ static pthread_q_entry pthread_queue[PTHEAD_QUEUE_MAX_LEN]; -static pthread_q_entry * first, *current; +static pthread_q_entry * first = NULL; +static pthread_q_entry * current = NULL; static int pthread_count = 0; /*static pthread_q_entry * pthread_queue_get_entry();*/ -static initialized = 0; +static int initialized = 0; +static int registered_cleanup_init = 0; static pthread_key_entry keyList[PTHREAD_KEYS_MAX]; @@ -36,7 +38,11 @@ static struct _PTHREAD_ATTR _pthread_attr_default_s = {100}, /* priority */ PTHREAD_SCOPE_SYSTEM, /* scope */ SCHED_FIFO, /* indirect function */ - PTHREAD_CREATE_DETACHED /* detached */ + /* According to the POSIX standard PTHREAD_CREATE_JOINABLE + * is the default + */ + /*PTHREAD_CREATE_DETACHED * detached */ + PTHREAD_CREATE_JOINABLE /* joinable */ }; /* global default access */ @@ -52,17 +58,90 @@ pace_pthread_attr_t pthread_attr_default = &_pthread_attr_default_s; */ /* + * Setup the thread information needed for main. This function + * mimics much of what's in pthread_create below but this is + * only for registering a thread already created (as in the case + * of main). + */ +STATUS +pacevx_vxworks_init() +{ + WIND_TCB *pTcb; + pace_pthread_t pthread; + int taskid; + unsigned int i; + STATUS status; + + PACE_TRACE("pacevx_vxworks_init"); + + /* Fill in the main thread's TCB with the information needed + * for POSIX emulation. + */ + taskid = taskIdSelf(); + if ((pTcb = taskTcb(taskid)) == NULL) + { + taskDelete(taskid); + return ERROR; + } + + pthread = (pace_pthread_t )malloc(sizeof(struct _PTHREAD_T)); + + if (pthread == NULL) + { + taskDelete(taskid); + return ERROR; + } + + /* construct pace_pthread_t structure */ + + bzero((char *)pthread, sizeof(struct _PTHREAD_T)); + pthread->tid = taskid; + pthread->stateflag = PTHREAD_CANCEL_ENABLE; + pthread->canceltype = PTHREAD_CANCEL_ASYNCHRONOUS; + /*pthread->detachflag = PTHREAD_CREATE_JOINABLE;*/ + pthread->detachflag = PTHREAD_CREATE_DETACHED; + + /* initialize the join semaphore also */ + if ((pthread->joinSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL) + { + free((void *)pthread); + taskDelete(taskid); + return ERROR; + } + + /* save to the WIND_TCB for reference afterward */ + pTcb->_USER_SPARE4 = (int) pthread; + + /* I guess this doesn't need to get added for the main thread. + * It seems to cause problems for main. + if (registered_cleanup_init == 0) + { + status = taskDeleteHookAdd((FUNCPTR)pacevx_pthread_run_cleanup); + if (status == ERROR) + { + return ERROR; + } + registered_cleanup_init = 1; + } + + pacevx_pthread_queue_add(pthread); + */ + + return OK; +} + +/* * Get a free entry from the pthread queue. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) pthread_q_entry * -pacevx_pthread_queue_get_entry() +pacevx_pthread_queue_get_entry () { int i; PACE_TRACE("pacevx_pthread_queue_get_entry"); - for (i = 0; i<PTHEAD_QUEUE_MAX_LEN; i++) + for (i = 0; i < PTHEAD_QUEUE_MAX_LEN; i++) { if (pthread_queue[i].status == FALSE) return &pthread_queue[i]; @@ -78,7 +157,7 @@ pacevx_pthread_queue_get_entry() */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) void -pacevx_pthread_destructor_key(pace_pthread_key_t key, void * arg) +pacevx_pthread_destructor_key (pace_pthread_key_t key, void * arg) { PACE_TRACE("pacevx_pthread_destructor_key"); @@ -101,7 +180,7 @@ pacevx_pthread_destructor_key(pace_pthread_key_t key, void * arg) */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) void -pacevx_pthread_destructor_thread(pace_pthread_t pthread) +pacevx_pthread_destructor_thread (pace_pthread_t pthread) { int i; @@ -120,7 +199,7 @@ pacevx_pthread_destructor_thread(pace_pthread_t pthread) */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) void -pacevx_pthread_proc_exit(pace_pthread_t pthread, void *value_ptr) +pacevx_pthread_proc_exit (pace_pthread_t pthread, void *value_ptr) { int key; int needgive = 0; @@ -166,7 +245,7 @@ pacevx_pthread_proc_exit(pace_pthread_t pthread, void *value_ptr) #if (PACE_HAS_POSIX_NONUOF_FUNCS) int -pacevx_pthread_verify(pace_pthread_t pthread) +pacevx_pthread_verify (pace_pthread_t pthread) { int key; pthread_q_entry * entry; @@ -241,6 +320,8 @@ pacevx_pthread_queue_add (pace_pthread_t pthread) entry->status = TRUE; entry->pthread = pthread; + pace_printf("pacevx_pthread_queue_add: first == %ld.\n", (long) first); + if (first == NULL) { first = entry; @@ -298,6 +379,10 @@ pacevx_pthread_queue_remove (pace_pthread_t pthread) first = entry1; + /* Check for the last thread and unregister cleanup function */ + if (first == NULL) + taskDeleteHookDelete((FUNCPTR)pacevx_pthread_run_cleanup); + intUnlock(key); return OK; } @@ -391,9 +476,44 @@ pthread_cond_timedwait (pace_pthread_cond_t * cond, pace_pthread_mutex_t * mutex, const pace_timespec * abstime) { - STATUS status; + /* + int msec_timeout; + if (abstime->sec () == 0 && abstime->usec () == 0) + msec_timeout = 0; * Do a "poll." * + else + { + // Assumes that struct timespec is same size as struct timeval, + // which assumes that time_t is a long: it currently is. + struct pace_timespec ts; + + pace_clock_gettime (CLOCK_REALTIME, &ts); + + // Note that we must convert between absolute time (which is + // passed as a parameter) and relative time. + pace_timespec relative_time = (*abstime) - ts; + + // Watchout for situations where a context switch has caused the + // current time to be > the timeout. + if (relative_time < 0) + msec_timeout = 0; + else + msec_timeout = relative_time.msec (); + } + // Inline the call to ACE_OS::sema_wait () because it takes an + // ACE_Time_Value argument. Avoid the cost of that conversion . . . + int ticks_per_sec = ::sysClkRateGet (); + int ticks = msec_timeout * ticks_per_sec / ACE_ONE_SECOND_IN_MSECS; + result = ::semTake (cv->sema_.sema_, ticks); + */ + + + + + int timeval = 0; - int errornumber, returnval = 0; + int errornumber; + int returnval = 0; + STATUS status; PACE_TRACE("pthread_cond_timedwait"); @@ -452,21 +572,24 @@ pthread_cond_wait (pace_pthread_cond_t * cond, #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) int pthread_create (pace_pthread_t * thread, const pace_pthread_attr_t * attr, +# if defined (PACE_HAS_CPLUSPLUS) pace_create_pf start_routine, +# else + void * (*start_routine) (void*), +# endif void * arg) { - PACE_TRACE("pthread_create"); - pace_pthread_attr_t pattr; char * pname; int taskid; pace_pthread_t pthread; WIND_TCB * pTcb; + PACE_TRACE("pthread_create"); + if (attr == 0) pattr = pthread_attr_default; else @@ -496,7 +619,7 @@ pthread_create (pace_pthread_t * thread, pthread = (pace_pthread_t )malloc(sizeof(struct _PTHREAD_T)); - if(pthread == NULL) + if (pthread == NULL) { taskDelete(taskid); return ERROR; @@ -524,91 +647,16 @@ pthread_create (pace_pthread_t * thread, /* save to the WIND_TCB for reference afterward */ pTcb->_USER_SPARE4 = (int) pthread; - taskDeleteHookAdd((FUNCPTR)pacevx_pthread_run_cleanup); - - pacevx_pthread_queue_add(pthread); - - return OK; -} -# else /* ! PACE_HAS_CPLUSPLUS */ -int -pthread_create (pace_pthread_t * thread, - const pace_pthread_attr_t * attr, - void * (*start_routine) (void*), - void * arg) -{ - pace_pthread_attr_t pattr; - char * pname; - int taskid; - pace_pthread_t pthread; - WIND_TCB * pTcb; - - PACE_TRACE("pthread_create"); - - if (attr == 0) - pattr = pthread_attr_default; - else - if (*attr == 0) - pattr = pthread_attr_default; - else - pattr = *attr; - - if (pattr->name[0] != '\0') /* name is provided */ - pname = pattr->name; - else - pname = (char *)0; - - taskid = taskSpawn(pname, - (SCHED_FIFO_HIGH_PRI - pattr->schedule.sched_priority), - VX_FP_TASK, pattr->stacksize, (FUNCPTR)start_routine, - (int)arg, 0,0,0,0,0,0,0,0,0); - - if (taskid == ERROR) - return ERROR; - - if ((pTcb = taskTcb(taskid)) == NULL) + if (registered_cleanup_init == 0) { - taskDelete(taskid); - return ERROR; + taskDeleteHookAdd((FUNCPTR)pacevx_pthread_run_cleanup); + registered_cleanup_init = 1; } - pthread = (pace_pthread_t )malloc(sizeof(struct _PTHREAD_T)); - - if(pthread == NULL) - { - taskDelete(taskid); - return ERROR; - } - - /* construct pace_pthread_t structure */ - - bzero((char *)pthread, sizeof(struct _PTHREAD_T)); - pthread->tid = taskid; - pthread->stateflag = PTHREAD_CANCEL_ENABLE; - pthread->canceltype = PTHREAD_CANCEL_ASYNCHRONOUS; - pthread->detachflag = pattr->dstate; - - /* initialize the join semaphore also */ - if ((pthread->joinSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)) == NULL) - { - free((void *)pthread); - taskDelete(taskid); - return ERROR; - } - - /* pass it to the caller */ - *thread = pthread; - - /* save to the WIND_TCB for reference afterward */ - pTcb->_USER_SPARE4 = (int) pthread; - - taskDeleteHookAdd((FUNCPTR)pacevx_pthread_run_cleanup); - pacevx_pthread_queue_add(pthread); return OK; } -# endif /*! PACE_HAS_CPLUSPLUS */ #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) @@ -680,7 +728,7 @@ pthread_join (pace_pthread_t thread, void ** value_ptr) return ERROR; if ((pthread = pace_pthread_self()) == NULL) - return ERROR; + return ERROR; needfree = 0; @@ -710,7 +758,6 @@ pthread_join (pace_pthread_t thread, void ** value_ptr) } /* if we are here, thread is not terminated yet */ - semTake(pthread->joinSem, WAIT_FOREVER); /* cleanup */ @@ -722,55 +769,13 @@ pthread_join (pace_pthread_t thread, void ** value_ptr) #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) int pthread_key_create (pace_pthread_key_t * key, +# if defined (PACE_HAS_CPLUSPLUS) pace_keycreate_pf destructor) -{ - PACE_TRACE("pthread_key_create"); - - /* - * Create a thread-specific data key. Also initialize the - * data structure if it is called first time. - */ - int i; - int intkey; - - /* do the initialization if it is the first time */ - if (initialized == 0) - { - initialized = 1; - - /* initialize the data structure */ - for (i = 0; i < PTHREAD_KEYS_MAX; i++) - { - keyList[i].index = i; - keyList[i].valid = FALSE; - keyList[i].destructor = NULL; - } - } - - /* find first available position */ - intkey = intLock(); - for (i = 0; i < PTHREAD_KEYS_MAX; i++) - { - if(keyList[i].valid == FALSE) - { - *key = (pace_pthread_key_t)keyList[i].index; - keyList[i].valid = TRUE; - keyList[i].destructor = destructor; - intUnlock(intkey); - return OK; - } - } - - intUnlock(intkey); - return ERROR; -} -#else /* ! PACE_HAS_CPLUSPLUS */ -int -pthread_key_create (pace_pthread_key_t * key, +# else void (*destructor)(void*)) +# endif { /* * Create a thread-specific data key. Also initialize the @@ -812,7 +817,6 @@ pthread_key_create (pace_pthread_key_t * key, intUnlock(intkey); return ERROR; } -# endif /* PACE_HAS_CPLUSPLUS */ #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) @@ -838,51 +842,13 @@ pthread_key_delete (pace_pthread_key_t key) #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) -int -pthread_once (pace_pthread_once_t * once_control, - pace_once_pf void_routine) -{ - PACE_TRACE("pthread_once"); - - /* - * Once function allows the function to be executed exact only once - * Subsequent calls of pthread_once() with the same once_control will - * not call the void_routine(). - */ - int i; - int key; - pace_pthread_t pthread; - - if ((pthread = pace_pthread_self()) == NULL) - return ERROR; - - /* make it atomic */ - key = intLock(); - - for (i = 0; i < pthread->onceCount; i++) - { - if (*once_control == pthread->onceList[i].once_ctl) - { - /* do nothing, already called */ - intUnlock(key); - return OK; - } - } - - /* if we are here, no match is found */ - pthread->onceList[pthread->onceCount].once_ctl = *once_control; - pthread->onceCount++; - intUnlock(key); - - /* run the init routine */ - (*void_routine)(); - return OK; -} -# else /* ! PACE_HAS_CPLUSPLUS */ int pthread_once (pace_pthread_once_t * once_control, - void (*void_routine) (void)) +# if defined (PACE_HAS_CPLUSPLUS) + pace_once_pf init_routine) +# else + void (*init_routine) (void)) +# endif { /* * Once function allows the function to be executed exact only once @@ -917,10 +883,9 @@ pthread_once (pace_pthread_once_t * once_control, intUnlock(key); /* run the init routine */ - (*void_routine)(); + (*init_routine)(); return OK; } -# endif /* PACE_HAS_CPLUSPLUS */ #endif /* PACE_HAS_NONUOF_FUNCS */ @@ -1123,8 +1088,10 @@ pthread_mutex_lock (pace_pthread_mutex_t * mutex) PACE_TRACE("pthread_mutex_lock"); status = semTake(*mutex, WAIT_FOREVER); - if (status == OK) - return OK; + if (status == OK) + { + return OK; + } else { errornumber = errnoGet(); diff --git a/PACE/pace/vxworks/pthread.h b/PACE/pace/vxworks/pthread.h index 1dd51b75472..4e5edef61b3 100644 --- a/PACE/pace/vxworks/pthread.h +++ b/PACE/pace/vxworks/pthread.h @@ -48,6 +48,9 @@ extern "C" { #define PACE_PTHREAD_SCOPE_PROCESS PTHREAD_SCOPE_PROCESS #define PACE_PTHREAD_SCOPE_SYSTEM PTHREAD_SCOPE_SYSTEM +#define PTHREAD_MUTEX_INITIALIZER 0 +#define PTHREAD_COND_INITIALIZER 0 + #ifndef PACE_SCHED_PARAM #define PACE_SCHED_PARAM typedef struct sched_param pace_sched_param; @@ -82,6 +85,7 @@ extern "C" { #if (PACE_HAS_POSIX_NONUOF_FUNCS) extern pace_pthread_attr_t pthread_attr_default; + STATUS pacevx_vxworks_init(); void pacevx_pthread_proc_exit(pace_pthread_t pthread, void *value_ptr); int pacevx_pthread_verify(pace_pthread_t pthread); void pacevx_pthread_run_cleanup (WIND_TCB *pTcb); @@ -105,7 +109,7 @@ extern "C" { int pthread_key_create (pace_pthread_key_t * key, pace_keycreate_pf destructor); int pthread_once (pace_pthread_once_t * once_control, - pace_once_pf void_routine); + pace_once_pf init_routine); # else /* ! PACE_HAS_CPLUSPLUS */ int pthread_create (pace_pthread_t * thread, const pace_pthread_attr_t * attr, @@ -114,7 +118,7 @@ extern "C" { int pthread_key_create (pace_pthread_key_t * key, void (*destructor)(void*)); int pthread_once (pace_pthread_once_t * once_control, - void (*void_routine) (void)); + void (*init_routine) (void)); # endif /*! PACE_HAS_CPLUSPLUS */ int pthread_detach (pace_pthread_t thread); int pthread_join (pace_pthread_t thread, void ** value_ptr); diff --git a/PACE/pace/vxworks/pthread.inl b/PACE/pace/vxworks/pthread.inl index 7e0442463f3..2fabc95a995 100644 --- a/PACE/pace/vxworks/pthread.inl +++ b/PACE/pace/vxworks/pthread.inl @@ -519,7 +519,7 @@ void pace_pthread_exit (void * value_ptr) { /* - * Normal thread exit. All the cleanup routine will be popped, if any. + * Normal thread exit. All the cleanup routines will be popped, if any. * If the thread is detached, free the storage; otherwise wait for join. */ pace_pthread_t pthread; diff --git a/PACE/pace/vxworks/types.h b/PACE/pace/vxworks/types.h index 12f1bf1b81d..44a98a0d93d 100644 --- a/PACE/pace/vxworks/types.h +++ b/PACE/pace/vxworks/types.h @@ -229,9 +229,6 @@ extern "C" { typedef uid_t pace_uid_t; #endif /* PACE_UID_T */ - - - #ifndef PACE_PTHREAD_QUEUE_T #define PACE_PTHREAD_QUEUE_T struct _PTHREAD_QUEUE_ENTRY |