diff options
author | joeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-06-12 19:55:30 +0000 |
---|---|---|
committer | joeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2001-06-12 19:55:30 +0000 |
commit | 04bdfccc14f14306ecf03ca3a1b1cb186fdbe901 (patch) | |
tree | 1d866ec3aa7f8187066fe7e089c3c22bc80bf050 | |
parent | acda1919234808028b0bf5f812acb7b73716ba46 (diff) | |
download | ATCD-04bdfccc14f14306ecf03ca3a1b1cb186fdbe901.tar.gz |
ChangeLogTag: Tue Jun 12 14:46:48 2001 Joe Hoffert <joeh@cs.wustl.edu>
-rw-r--r-- | PACE/ChangeLog | 25 | ||||
-rw-r--r-- | PACE/THANKS | 5 | ||||
-rw-r--r-- | PACE/pace/config/config.h | 4 | ||||
-rw-r--r-- | PACE/pace/pthread.h | 56 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.c | 858 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.h | 19 | ||||
-rw-r--r-- | PACE/pace/vxworks/pthread.inl | 881 | ||||
-rw-r--r-- | PACE/pace/vxworks/time.inl | 1 | ||||
-rw-r--r-- | PACE/pace/vxworks/unistd.inl | 4 |
9 files changed, 950 insertions, 903 deletions
diff --git a/PACE/ChangeLog b/PACE/ChangeLog index 76bf69335cd..65099265360 100644 --- a/PACE/ChangeLog +++ b/PACE/ChangeLog @@ -1,3 +1,28 @@ +Tue Jun 12 14:46:48 2001 Joe Hoffert <joeh@cs.wustl.edu> + + * pace/vxworks/unistd.inl: + Added cast for non-const char*. + + * pace/vxworks/time.inl: + Removed declaration of errno. + + * pace/vxworks/pthread.inl: + * pace/vxworks/pthread.h: + * pace/vxworks/pthread.c: + Added supported for pthreads. The vast majority of this code + was donated by Hughes Network Systems via Braeton Taylor + <btaylor@hns.com>. + + * pace/config/config.h: + + * pace/pthread.h: + With the addition of VxWorks not all PACE functions are inlined + now. Added #if !(PACE_VXWORKS) to handle this. + + * THANKS: + Added Braeton Taylor of Hughes Network Systems for his + contribution of pthread code for VxWorks. + Fri Jun 1 15:38:45 2001 Joe Hoffert <joeh@cs.wustl.edu> * pace/vxworks/aio.c: diff --git a/PACE/THANKS b/PACE/THANKS index ee8a7aee07f..17390e05f6a 100644 --- a/PACE/THANKS +++ b/PACE/THANKS @@ -5,12 +5,13 @@ Brunsch, Darrell <brunsch@ece.uci.edu> Gilpin, Andrew <agg1@cs.wustl.edu> Guallar, Gonzalo Diethelm <Gonzalo.Diethelm@sonda.com> Heitmann, John <jwh1@cs.wustl.edu> -Hoefort, Joe <joeh@cs.wustl.edu> +Hoffert, Joe <joeh@cs.wustl.edu> Levine, David <levine@cs.wustl.edu> Loftis, Bjorn <bl6394@momail.sbc.com> Syyid, Umar <usyyid@hns.com> <rbolourian@hns.com> +Taylor, Braeton <btaylor@hns.com> Thanks, - The PACE Development Team
\ No newline at end of file + The PACE Development Team diff --git a/PACE/pace/config/config.h b/PACE/pace/config/config.h index 85f6c9af5d4..6a14a84250d 100644 --- a/PACE/pace/config/config.h +++ b/PACE/pace/config/config.h @@ -59,18 +59,22 @@ # define PACE_NONCONST_ARG_CAST(TYPE) (TYPE) # define PACE_VOIDSTARTSTAR_ARG_CAST(TYPE) (TYPE) # define PACE_AIO_SUSPEND_LIST_ARG_CAST (struct aiocb **) +# define PACE_THR_ENTRY_CAST #elif PACE_HAS_POSIX == DIGITAL_UNIX # define PACE_NONCONST_ARG_CAST(TYPE) (TYPE) # define PACE_VOIDSTARTSTAR_ARG_CAST(TYPE) # define PACE_AIO_SUSPEND_LIST_ARG_CAST (const struct aiocb **) +# define PACE_THR_ENTRY_CAST #elif PACE_LACKS_POSIX == PACE_VXWORKS # define PACE_NONCONST_ARG_CAST(TYPE) (TYPE) # define PACE_VOIDSTARTSTAR_ARG_CAST(TYPE) # define PACE_AIO_SUSPEND_LIST_ARG_CAST (const struct aiocb **) +# define PACE_THR_ENTRY_CAST(TYPE) (TYPE) #else /* ! PACE_LYNXOS */ # define PACE_NONCONST_ARG_CAST(TYPE) # define PACE_VOIDSTARTSTAR_ARG_CAST(TYPE) # define PACE_AIO_SUSPEND_LIST_ARG_CAST +# define PACE_THR_ENTRY_CAST #endif /* ! PACE_LYNXOS */ /* Adding appropriate macros for the different POSIX units of diff --git a/PACE/pace/pthread.h b/PACE/pace/pthread.h index 148a99ef5e4..638a4b7c141 100644 --- a/PACE/pace/pthread.h +++ b/PACE/pace/pthread.h @@ -274,9 +274,12 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 11.4.4. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_cond_timedwait (pace_pthread_cond_t * cond, - pace_pthread_mutex_t * mutex, - const pace_timespec * abstime); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_cond_timedwait (pace_pthread_cond_t * cond, + pace_pthread_mutex_t * mutex, + const pace_timespec * abstime); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -285,8 +288,11 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 11.4.4. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_cond_wait (pace_pthread_cond_t * cond, - pace_pthread_mutex_t * mutex); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_cond_wait (pace_pthread_cond_t * cond, + pace_pthread_mutex_t * mutex); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -333,10 +339,13 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 16.2.2. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_create (pace_pthread_t * thread, - const pace_pthread_attr_t * attr, - void * (*start_routine) (void*), - void * arg); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_create (pace_pthread_t * thread, + const pace_pthread_attr_t * attr, + void * (*start_routine) (void*), + void * arg); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -345,7 +354,10 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 16.2.4. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_detach (pace_pthread_t thread); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_detach (pace_pthread_t thread); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -392,7 +404,10 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 16.2.3. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_join (pace_pthread_t thread, void ** value_ptr); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_join (pace_pthread_t thread, void ** value_ptr); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -401,8 +416,11 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 17.1.1. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_key_create (pace_pthread_key_t * key, - void (*destructor)(void*)); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_key_create (pace_pthread_key_t * key, + void (*destructor)(void*)); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -411,7 +429,10 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 17.1.3. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_key_delete (pace_pthread_key_t key); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_key_delete (pace_pthread_key_t key); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ /** @@ -579,8 +600,11 @@ extern "C" { IEEE Std 1003.1, 1996 Edition), Section 16.2.8. */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pace_pthread_once (pace_pthread_once_t * once_control, - void (*void_routine) (void)); +#if !(PACE_VXWORKS) + PACE_INLINE +#endif + int pace_pthread_once (pace_pthread_once_t * once_control, + void (*void_routine) (void)); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ # define PACE_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT diff --git a/PACE/pace/vxworks/pthread.c b/PACE/pace/vxworks/pthread.c index 2e4786b391c..d34f496dc87 100644 --- a/PACE/pace/vxworks/pthread.c +++ b/PACE/pace/vxworks/pthread.c @@ -16,6 +16,864 @@ #include "pace/pthread.h" +/* pthread queue */ +static pthread_q_entry pthread_queue[PTHEAD_QUEUE_MAX_LEN]; +static pthread_q_entry * first, *current; +static int pthread_count = 0; +/*static pthread_q_entry * pthread_queue_get_entry();*/ +static initialized = 0; + +static pthread_key_entry keyList[PTHREAD_KEYS_MAX]; + +/* + * The defaut pthread attr structure, if calling task + * does not pass attr, this default will be used + */ +static struct _PTHREAD_ATTR _pthread_attr_default_s = +{ + 10000, /* stacksize */ + { '\0' }, /* name */ + {100}, /* priority */ + PTHREAD_SCOPE_SYSTEM, /* scope */ + SCHED_FIFO, /* indirect function */ + PTHREAD_CREATE_DETACHED /* detached */ +}; + +/* global default access */ +pace_pthread_attr_t pthread_attr_default = &_pthread_attr_default_s; + + #if !defined (PACE_HAS_INLINE) # include "pace/vxworks/pthread.inl" #endif /* ! PACE_HAS_INLINE */ + +/* + * VxWorks Helper Functions + */ + +/* + * Get a free entry from the pthread queue. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +pthread_q_entry * +pacevx_pthread_queue_get_entry() +{ + int i; + for (i = 0; i<PTHEAD_QUEUE_MAX_LEN; i++) + { + if (pthread_queue[i].status == FALSE) + return &pthread_queue[i]; + } + + /* error condition, can alloc more in future */ + return NULL; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Run the destructor functions for the specific data key + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +void +pacevx_pthread_destructor_key(pace_pthread_key_t key, void * arg) +{ + if (pacevx_pthread_key_validate(key)) + { + if (keyList[key].destructor != NULL) + (*(keyList[key].destructor))(arg); + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Run the destructor functions for the thread + * For each key value, if there is a non-NULL destructor pointer, + * and the thread has a non-NULL value associated with that key, + * the function pointed to is called with the current associated + * value as its sole argument. + * + * return: none. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +void +pacevx_pthread_destructor_thread(pace_pthread_t pthread) +{ + int i; + + for (i = 0; i < PTHREAD_KEYS_MAX; i ++) + { + if (pthread->keyvaluelist[i] != NULL) + pacevx_pthread_destructor_key(i, pthread->keyvaluelist[i]); + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * General exit processing. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +void +pacevx_pthread_proc_exit(pace_pthread_t pthread, void *value_ptr) +{ + int key; + int needgive = 0; + + pacevx_pthread_cleanup_popall(pthread); + + /* thread storage data cleanup is automatically*/ + pacevx_pthread_destructor_thread(pthread); + + /* joinable or detached */ + if(pthread->detachflag == PTHREAD_CREATE_DETACHED) + { + free(pthread); + } + else + { + key = intLock(); + + /* pass the value */ + pthread->joinvalue = value_ptr; + + switch(pthread->joinstate) + { + case JOIN_PENDING: + pthread->joinstate = JOIN_TERMINATED; + needgive = 1; + break; + case JOIN_NORMAL: + default: + pthread->joinstate = JOIN_TERMINATED; + break; + } + intUnlock(key); + + /* unblock the calling thread */ + if(needgive) + semGive(((pace_pthread_t)(pthread->jointhread))->joinSem); + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pacevx_pthread_verify(pace_pthread_t pthread) +{ + int key; + pthread_q_entry * entry; + + key = intLock(); + + /* if queue is empty */ + if (first == NULL) + { + intUnlock(key); + return ERROR; + } + + entry = first; /* get the first one */ + + while (entry != NULL) + { + if (entry->pthread == pthread) + { + intUnlock(key); + return TRUE; + } + entry = entry->next; + } + + intUnlock(key); + + return FALSE; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * The cleanup routine that will be called if the task get deleted. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +void +pacevx_pthread_run_cleanup (WIND_TCB *pTcb) +/* pointer to deleted task's WIND_TCB */ +{ + pace_pthread_t pthread; + + /* free thread tcb only*/ + if (pTcb->_USER_SPARE4 != 0) + { + pthread = (pace_pthread_t) pTcb->_USER_SPARE4; + + pacevx_pthread_proc_exit(pthread, NULL); + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Add to the pthread queue. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pacevx_pthread_queue_add(pace_pthread_t pthread) +{ + int key; + pthread_q_entry * entry; + + key = intLock(); + + if ((entry = pacevx_pthread_queue_get_entry()) != NULL) + { + entry->status = TRUE; + entry->pthread = pthread; + + if (first == NULL) + { + first = entry; + current = entry; + } + else + { + current->next = entry; + current = entry; + } + pthread_count ++; + intUnlock(key); + return OK; + } + + intUnlock(key); + return ERROR; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Remove an entry to the pthread queue. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pacevx_pthread_queue_remove(pace_pthread_t pthread) +{ + int key; + pthread_q_entry * entry1; + pthread_q_entry * entry2; + + key = intLock(); + + if (first == NULL) + { + intUnlock(key); + return ERROR; + } + + /* if it is the first one, simple */ + if (first->pthread == pthread) + { + first->status = FALSE; + first->pthread = NULL; + + entry1 = first->next; + + first->next = NULL; + + /* if it is the only one */ + if (current == first) + current = entry1; + + first = entry1; + + intUnlock(key); + return OK; + } + + /* else */ + + entry1 = first; + entry2 = entry1->next; + + while (entry2 != NULL) + { + if (entry2->pthread == pthread) + { + if (current == entry2) + current = entry1; + + entry1->next = entry2->next; /* remove the node */ + + /* set invalid and put back to the list */ + entry2->status = FALSE; + entry2->pthread = NULL; + entry2->next = NULL; + intUnlock(key); + return OK; + } + entry1 = entry2; + entry2 = entry2->next; + } + + intUnlock(key); + return ERROR; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Run the rest of cleanup routines left in the stack. + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +void +pacevx_pthread_cleanup_popall(pace_pthread_t thread) +{ + int count; + int i; + + count = thread->rtnCount - 1; + for (i = count; i > 0 ; i--) + { + thread->rtnCount --; + (*(thread->cleanupRtn[i].routine))(thread->cleanupRtn[i].args); + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +/* + * Validate the key to see if the key is already created (valid) + */ +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pacevx_pthread_key_validate(pace_pthread_key_t key) +{ + int intkey; + + intkey = intLock(); + + if (keyList[key].valid) + { + intUnlock(intkey); + return TRUE; + } + else + { + intUnlock(intkey); + return FALSE; + } +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + + +/* + * PACE - POSIX Functions + */ + + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pace_pthread_cond_timedwait (pace_pthread_cond_t * cond, + pace_pthread_mutex_t * mutex, + const pace_timespec * abstime) +{ + STATUS status; + int timeval = 0; + int errornumber, returnval = 0; + + if (pace_pthread_mutex_unlock(mutex) != OK) return ERROR; + + /* convert the abstime to timeval */ + status = semTake(*cond, timeval); + + if (status != OK) + { + errornumber = errnoGet(); + if (errornumber == S_objLib_OBJ_ID_ERROR) + returnval = EINVAL; + else if (errornumber == S_objLib_OBJ_TIMEOUT) + returnval = ETIMEDOUT; + else + returnval = ERROR; + } + + pace_pthread_mutex_lock(mutex); + + return returnval; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pace_pthread_cond_wait (pace_pthread_cond_t * cond, + pace_pthread_mutex_t * mutex) +{ + STATUS status; + int errornumber; + int returnval = 0; + + if (pace_pthread_mutex_unlock(mutex) != OK) + return ERROR; + + status = semTake(*cond, WAIT_FOREVER); + + if(status != OK) + { + errornumber = errnoGet(); + if (errornumber == S_objLib_OBJ_ID_ERROR) + returnval = EINVAL; + else + returnval = ERROR; + } + + pace_pthread_mutex_lock(mutex); + + return returnval; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +# if defined (PACE_HAS_CPLUSPLUS) +int +pace_pthread_create (pace_pthread_t * thread, + const pace_pthread_attr_t * attr, + pace_create_pf start_routine, + void * arg) +{ + pace_pthread_attr_t pattr; + char * pname; + int taskid; + pace_pthread_t pthread; + WIND_TCB * pTcb; + + 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) + { + 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 = 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; +} +# else /* ! PACE_HAS_CPLUSPLUS */ +int +pace_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; + + 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) + { + 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 = 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) +int +pace_pthread_detach (pace_pthread_t thread) +{ + int key; + int needfree; + needfree = 0; + + if (!pacevx_pthread_verify(thread)) + return EINVAL; + + key = intLock(); + + switch (thread->joinstate) + { + /* task is joined, or detached, but still running, do nothing */ + case JOIN_PENDING: + case JOIN_DETATCHED: + intUnlock(key); + return OK; + break; + case JOIN_NORMAL: /* task is running */ + thread->joinstate = JOIN_DETATCHED; + break; + case JOIN_TERMINATED: + needfree = 1; + break; + default: + break; + } + + intUnlock(key); + + if (needfree) + { + pacevx_pthread_queue_remove(thread); + free(thread); + } + return OK; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pace_pthread_join (pace_pthread_t thread, void ** value_ptr) +{ + /* + * The pthread_join() function suspends execution of the calling + * thread until the target thread terminates, unless the target + * thread has already terminated. + * The terminating thread can pass value to the caller by + * pthread_exit() and the calling thread gets it from "value_ptr" + * The application must verify the "value_ptr" value before using it. + */ + pace_pthread_t pthread; + int needfree; + int key; + + if (!pacevx_pthread_verify(thread)) + return ERROR; + + if (thread->detachflag != PTHREAD_CREATE_JOINABLE) + return ERROR; + + if ((pthread = pace_pthread_self()) == NULL) + return ERROR; + + needfree = 0; + + key = intLock(); + switch (thread->joinstate) + { + case JOIN_NORMAL: + thread->jointhread = pthread; + thread->joinstate = JOIN_PENDING; + break; + case JOIN_TERMINATED: + needfree = 1; + break; + case JOIN_PENDING: + default: + intUnlock(key); + return ERROR; + } + intUnlock(key); + + if (needfree) + { + *value_ptr = thread->joinvalue; + pacevx_pthread_queue_remove(thread); + free(thread); + return OK; + } + + /* if we are here, thread is not terminated yet */ + + semTake(pthread->joinSem, WAIT_FOREVER); + + /* cleanup */ + *value_ptr = thread->joinvalue; + pacevx_pthread_queue_remove(thread); + free(thread); + return OK; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +# if defined (PACE_HAS_CPLUSPLUS) +int +pace_pthread_key_create (pace_pthread_key_t * key, + pace_keycreate_pf destructor) +{ + /* + * 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 +pace_pthread_key_create (pace_pthread_key_t * key, + void (*destructor)(void*)) +{ + /* + * 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; +} +# endif /* PACE_HAS_CPLUSPLUS */ +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +int +pace_pthread_key_delete (pace_pthread_key_t key) +{ + int intkey; + + if ((key < 0) || (key >= PTHREAD_KEYS_MAX)) + return ERROR; + + intkey = intLock(); + + keyList[key].valid = FALSE; + keyList[key].destructor = NULL; + + intUnlock(intkey); + + return OK; +} +#endif /* PACE_HAS_NONUOF_FUNCS */ + +#if (PACE_HAS_POSIX_NONUOF_FUNCS) +# if defined (PACE_HAS_CPLUSPLUS) +int +pace_pthread_once (pace_pthread_once_t * once_control, + pace_once_pf void_routine) +{ + /* + * 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 +pace_pthread_once (pace_pthread_once_t * once_control, + void (*void_routine) (void)) +{ + /* + * 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; +} +# endif /* PACE_HAS_CPLUSPLUS */ +#endif /* PACE_HAS_NONUOF_FUNCS */ diff --git a/PACE/pace/vxworks/pthread.h b/PACE/pace/vxworks/pthread.h index c6fcc73cfb0..a2b7d009613 100644 --- a/PACE/pace/vxworks/pthread.h +++ b/PACE/pace/vxworks/pthread.h @@ -80,14 +80,17 @@ extern "C" { * VxWorks helper functions */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) - PACE_INLINE int pthread_verify(pace_pthread_t pthread); - PACE_INLINE void pthread_run_cleanup (WIND_TCB *pTcb); - PACE_INLINE int pthread_queue_add(pace_pthread_t pthread); - PACE_INLINE int pthread_queue_remove(pace_pthread_t pthread); - PACE_INLINE void pthread_cleanup_popall(pace_pthread_t thread); - PACE_INLINE void pthread_destructor_thread(pace_pthread_t pthread); - PACE_INLINE int pthread_key_validate(pace_pthread_key_t key); - PACE_INLINE void pthread_destructor_key(pace_pthread_key_t key, void * arg); + extern pace_pthread_attr_t pthread_attr_default; + + 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); + int pacevx_pthread_queue_add(pace_pthread_t pthread); + int pacevx_pthread_queue_remove(pace_pthread_t pthread); + void pacevx_pthread_cleanup_popall(pace_pthread_t thread); + void pacevx_pthread_destructor_thread(pace_pthread_t pthread); + int pacevx_pthread_key_validate(pace_pthread_key_t key); + void pacevx_pthread_destructor_key(pace_pthread_key_t key, void * arg); #endif /* PACE_HAS_POSIX_NONUOF_FUNCS */ #if defined (PACE_HAS_CPLUSPLUS) diff --git a/PACE/pace/vxworks/pthread.inl b/PACE/pace/vxworks/pthread.inl index 356c1cfe5ec..ccef569d001 100644 --- a/PACE/pace/vxworks/pthread.inl +++ b/PACE/pace/vxworks/pthread.inl @@ -17,350 +17,6 @@ #include "pace/unistd.h" -/* pthread queue */ -static pthread_q_entry pthread_queue[PTHEAD_QUEUE_MAX_LEN]; -static pthread_q_entry * first, *current; -static int pthread_count = 0; -static pthread_q_entry * pthread_queue_get_entry(); -static initialized = 0; - -pthread_key_entry keyList[PTHREAD_KEYS_MAX]; - -/* - * The defaut pthread attr structure, if calling task - * does not pass attr, this default will be used - */ -struct _PTHREAD_ATTR _pthread_attr_default_s = -{ - 10000, /* stacksize */ - { '\0' }, /* name */ - {100}, /* priority */ - PTHREAD_SCOPE_SYSTEM, /* scope */ - SCHED_FIFO, /* indirect function */ - PTHREAD_CREATE_DETACHED /* detached */ -}; - -/* global default access */ -pace_pthread_attr_t pthread_attr_default = &_pthread_attr_default_s; - - -/* - * VxWorks Helper Functions - */ - - -/* - * Get a free entry from the pthread queue. - */ -pthread_q_entry * pthread_queue_get_entry() -{ - int i; - for (i = 0; i<PTHEAD_QUEUE_MAX_LEN; i++) - { - if (pthread_queue[i].status == FALSE) - return &pthread_queue[i]; - } - - /* error condition, can alloc more in future */ - return NULL; -} - -/* - * Run the destructor functions for the specific data key - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -void -pthread_destructor_key(pace_pthread_key_t key, void * arg) -{ - if (pthread_key_validate(key)) - { - if (keyList[key].destructor != NULL) - (*(keyList[key].destructor))(arg); - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * Run the destructor functions for the thread - * For each key value, if there is a non-NULL destructor pointer, - * and the thread has a non-NULL value associated with that key, - * the function pointed to is called with the current associated - * value as its sole argument. - * - * return: none. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -void -pthread_destructor_thread(pace_pthread_t pthread) -{ - int i; - - for (i = 0; i < PTHREAD_KEYS_MAX; i ++) - { - if (pthread->keyvaluelist[i] != NULL) - pthread_destructor_key(i, pthread->keyvaluelist[i]); - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * General exit processing. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -static void pthread_proc_exit(pace_pthread_t pthread, void *value_ptr) -{ - int key; - int needgive = 0; - - pthread_cleanup_popall(pthread); - - /* thread storage data cleanup is automatically*/ - pthread_destructor_thread(pthread); - - /* joinable or detached */ - if(pthread->detachflag == PTHREAD_CREATE_DETACHED) - { - free(pthread); - } - else - { - key = intLock(); - - /* pass the value */ - pthread->joinvalue = value_ptr; - - switch(pthread->joinstate) - { - case JOIN_PENDING: - pthread->joinstate = JOIN_TERMINATED; - needgive = 1; - break; - case JOIN_NORMAL: - default: - pthread->joinstate = JOIN_TERMINATED; - break; - } - intUnlock(key); - - /* unblock the calling thread */ - if(needgive) - semGive(((pace_pthread_t)(pthread->jointhread))->joinSem); - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pthread_verify(pace_pthread_t pthread) -{ - int key; - pthread_q_entry * entry; - - key = intLock(); - - /* if queue is empty */ - if (first == NULL) - { - intUnlock(key); - return ERROR; - } - - entry = first; /* get the first one */ - - while (entry != NULL) - { - if (entry->pthread == pthread) - { - intUnlock(key); - return TRUE; - } - entry = entry->next; - } - - intUnlock(key); - - return FALSE; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * The cleanup routine that will be called if the task get deleted. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -void -pthread_run_cleanup (WIND_TCB *pTcb) /* pointer to deleted task's WIND_TCB */ -{ - pace_pthread_t pthread; - - /* free thread tcb only*/ - if (pTcb->_USER_SPARE4 != 0) - { - pthread = (pace_pthread_t) pTcb->_USER_SPARE4; - - pthread_proc_exit(pthread, NULL); - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * Add to the pthread queue. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pthread_queue_add(pace_pthread_t pthread) -{ - int key; - pthread_q_entry * entry; - - key = intLock(); - - if ((entry = pthread_queue_get_entry()) != NULL) - { - entry->status = TRUE; - entry->pthread = pthread; - - if (first == NULL) - { - first = entry; - current = entry; - } - else - { - current->next = entry; - current = entry; - } - pthread_count ++; - intUnlock(key); - return OK; - } - - intUnlock(key); - return ERROR; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * Remove an entry to the pthread queue. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pthread_queue_remove(pace_pthread_t pthread) -{ - int key; - pthread_q_entry * entry1; - pthread_q_entry * entry2; - - key = intLock(); - - if (first == NULL) - { - intUnlock(key); - return ERROR; - } - - /* if it is the first one, simple */ - if (first->pthread == pthread) - { - first->status = FALSE; - first->pthread = NULL; - - entry1 = first->next; - - first->next = NULL; - - /* if it is the only one */ - if (current == first) - current = entry1; - - first = entry1; - - intUnlock(key); - return OK; - } - - /* else */ - - entry1 = first; - entry2 = entry1->next; - - while (entry2 != NULL) - { - if (entry2->pthread == pthread) - { - if (current == entry2) - current = entry1; - - entry1->next = entry2->next; /* remove the node */ - - /* set invalid and put back to the list */ - entry2->status = FALSE; - entry2->pthread = NULL; - entry2->next = NULL; - intUnlock(key); - return OK; - } - entry1 = entry2; - entry2 = entry2->next; - } - - intUnlock(key); - return ERROR; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * Run the rest of cleanup routines left in the stack. - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -void -pthread_cleanup_popall(pace_pthread_t thread) -{ - int count; - int i; - - count = thread->rtnCount - 1; - for (i = count; i > 0 ; i--) - { - thread->rtnCount --; - (*(thread->cleanupRtn[i].routine))(thread->cleanupRtn[i].args); - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -/* - * Validate the key to see if the key is already created (valid) - */ -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pthread_key_validate(pace_pthread_key_t key) -{ - int intkey; - - intkey = intLock(); - - if (keyList[key].valid) - { - intUnlock(intkey); - return TRUE; - } - else - { - intUnlock(intkey); - return FALSE; - } -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - - - /* * PACE - POSIX Functions */ @@ -667,7 +323,7 @@ pace_pthread_cancel (pace_pthread_t thread) /* * In VxWorks, to cancel a thread is to delete a task. */ - if (!pthread_verify(thread)) + if (!pacevx_pthread_verify(thread)) return ESRCH; if (taskIdVerify(thread->tid) == ERROR) /* already exit, never happen */ @@ -731,69 +387,6 @@ pace_pthread_cond_signal (pace_pthread_cond_t * cond) #if (PACE_HAS_POSIX_NONUOF_FUNCS) PACE_INLINE int -pace_pthread_cond_timedwait (pace_pthread_cond_t * cond, - pace_pthread_mutex_t * mutex, - const pace_timespec * abstime) -{ - STATUS status; - int timeval = 0; - int errornumber, returnval = 0; - - if (pace_pthread_mutex_unlock(mutex) != OK) return ERROR; - - /* convert the abstime to timeval */ - status = semTake(*cond, timeval); - - if (status != OK) - { - errornumber = errnoGet(); - if (errornumber == S_objLib_OBJ_ID_ERROR) - returnval = EINVAL; - else if (errornumber == S_objLib_OBJ_TIMEOUT) - returnval = ETIMEDOUT; - else - returnval = ERROR; - } - - pace_pthread_mutex_lock(mutex); - - return returnval; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pace_pthread_cond_wait (pace_pthread_cond_t * cond, - pace_pthread_mutex_t * mutex) -{ - STATUS status; - int errornumber; - int returnval = 0; - - if (pace_pthread_mutex_unlock(mutex) != OK) - return ERROR; - - status = semTake(*cond, WAIT_FOREVER); - - if(status != OK) - { - errornumber = errnoGet(); - if (errornumber == S_objLib_OBJ_ID_ERROR) - returnval = EINVAL; - else - returnval = ERROR; - } - - pace_pthread_mutex_lock(mutex); - - return returnval; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int pace_pthread_condattr_destroy (pace_pthread_condattr_t * attr) { return OK; @@ -840,210 +433,11 @@ pace_pthread_condattr_setpshared (pace_pthread_condattr_t * attr, #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) -PACE_INLINE -int -pace_pthread_create (pace_pthread_t * thread, - const pace_pthread_attr_t * attr, - pace_create_pf start_routine, - void * arg) -{ - pthread_attr_t pattr; - char * pname; - int taskid; - pace_pthread_t pthread; - WIND_TCB * pTcb; - - 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) - { - 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 = 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)pthread_run_cleanup); - - pthread_queue_add(pthread); - - return OK; -} -# else /* ! PACE_HAS_CPLUSPLUS */ -PACE_INLINE -int -pace_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; - - 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) - { - 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 = 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)pthread_run_cleanup); - - pthread_queue_add(pthread); - - return OK; -} -# endif /*! PACE_HAS_CPLUSPLUS */ -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pace_pthread_detach (pace_pthread_t thread) -{ - int key; - int needfree; - needfree = 0; - - if (!pthread_verify(thread)) - return EINVAL; - - key = intLock(); - - switch (thread->joinstate) - { - /* task is joined, or detached, but still running, do nothing */ - case JOIN_PENDING: - case JOIN_DETATCHED: - intUnlock(key); - return OK; - break; - case JOIN_NORMAL: /* task is running */ - thread->joinstate = JOIN_DETATCHED; - break; - case JOIN_TERMINATED: - needfree = 1; - break; - default: - break; - } - - intUnlock(key); - - if (needfree) - { - pthread_queue_remove(thread); - free(thread); - } - return OK; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) PACE_INLINE int pace_pthread_equal (pace_pthread_t t1, pace_pthread_t t2) { - if (pthread_verify(t1) && pthread_verify(t2)) + if (pacevx_pthread_verify(t1) && pacevx_pthread_verify(t2)) { if (t1->tid != t2->tid) return 0; @@ -1066,7 +460,7 @@ pace_pthread_exit (void * value_ptr) if ((pthread = pace_pthread_self()) != NULL) { - pthread_proc_exit(pthread, value_ptr); + pacevx_pthread_proc_exit(pthread, value_ptr); exit(0); } @@ -1104,7 +498,7 @@ pace_pthread_getspecific (pace_pthread_key_t key) { pace_pthread_t pthread; - if (!pthread_key_validate(key)) + if (!pacevx_pthread_key_validate(key)) return NULL; if ((pthread = pace_pthread_self()) != NULL) @@ -1119,187 +513,9 @@ pace_pthread_getspecific (pace_pthread_key_t key) #if (PACE_HAS_POSIX_NONUOF_FUNCS) PACE_INLINE int -pace_pthread_join (pace_pthread_t thread, void ** value_ptr) -{ - /* - * The pthread_join() function suspends execution of the calling - * thread until the target thread terminates, unless the target - * thread has already terminated. - * The terminating thread can pass value to the caller by - * pthread_exit() and the calling thread gets it from "value_ptr" - * The application must verify the "value_ptr" value before using it. - */ - pace_pthread_t pthread; - int needfree; - int key; - - if (!pthread_verify(thread)) - return ERROR; - - if (thread->detachflag != PTHREAD_CREATE_JOINABLE) - return ERROR; - - if ((pthread = pace_pthread_self()) == NULL) - return ERROR; - - needfree = 0; - - key = intLock(); - switch (thread->joinstate) - { - case JOIN_NORMAL: - thread->jointhread = pthread; - thread->joinstate = JOIN_PENDING; - break; - case JOIN_TERMINATED: - needfree = 1; - break; - case JOIN_PENDING: - default: - intUnlock(key); - return ERROR; - } - intUnlock(key); - - if (needfree) - { - *value_ptr = thread->joinvalue; - pthread_queue_remove(thread); - free(thread); - return OK; - } - - /* if we are here, thread is not terminated yet */ - - semTake(pthread->joinSem, WAIT_FOREVER); - - /* cleanup */ - *value_ptr = thread->joinvalue; - pthread_queue_remove(thread); - free(thread); - return OK; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) -PACE_INLINE -int -pace_pthread_key_create (pace_pthread_key_t * key, - pace_keycreate_pf destructor) -{ - /* - * 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 = (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 */ -PACE_INLINE -int -pace_pthread_key_create (pace_pthread_key_t * key, - void (*destructor)(void*)) -{ - /* - * 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; -} -# endif /* PACE_HAS_CPLUSPLUS */ -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int -pace_pthread_key_delete (pace_pthread_key_t key) -{ - int intkey; - - if ((key < 0) || (key >= PTHREAD_KEYS_MAX)) - return ERROR; - - intkey = intLock(); - - keyList[key].valid = FALSE; - keyList[key].destructor = NULL; - - intUnlock(intkey); - - return OK; -} -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) -PACE_INLINE -int pace_pthread_kill (pace_pthread_t thread, int sig) { - if (pthread_verify(thread)) + if (pacevx_pthread_verify(thread)) return kill(thread->tid, sig); else return EINVAL; @@ -1587,90 +803,6 @@ pace_pthread_mutexattr_setpshared (pace_pthread_mutexattr_t * attr, #endif /* PACE_HAS_NONUOF_FUNCS */ #if (PACE_HAS_POSIX_NONUOF_FUNCS) -# if defined (PACE_HAS_CPLUSPLUS) -PACE_INLINE -int -pace_pthread_once (pace_pthread_once_t * once_control, - pace_once_pf void_routine) -{ - /* - * 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 */ -PACE_INLINE -int -pace_pthread_once (pace_pthread_once_t * once_control, - void (*void_routine) (void)) -{ - /* - * 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; -} -# endif /* PACE_HAS_CPLUSPLUS */ -#endif /* PACE_HAS_NONUOF_FUNCS */ - -#if (PACE_HAS_POSIX_NONUOF_FUNCS) PACE_INLINE pace_pthread_t pace_pthread_self () @@ -1764,7 +896,7 @@ pace_pthread_setspecific (pace_pthread_key_t key, const void * value) { pace_pthread_t pthread; - if (!pthread_key_validate(key)) + if (!pacevx_pthread_key_validate(key)) return ERROR; if ((pthread = pace_pthread_self()) != NULL) @@ -1812,6 +944,7 @@ PACE_INLINE void pace_pthread_testcancel () { + /* Do nothing per ACE (i.e., ACE_OS::thr_testcancel). */ return; } #endif /* PACE_HAS_NONUOF_FUNCS */ diff --git a/PACE/pace/vxworks/time.inl b/PACE/pace/vxworks/time.inl index 04a3d06b576..b5f988eca4f 100644 --- a/PACE/pace/vxworks/time.inl +++ b/PACE/pace/vxworks/time.inl @@ -15,7 +15,6 @@ #include "pace/errno.h" #include "pace/signal.h" -extern int errno; #if (PACE_HAS_POSIX_CLS_UOF) PACE_INLINE diff --git a/PACE/pace/vxworks/unistd.inl b/PACE/pace/vxworks/unistd.inl index c2446346b86..aefa66f0b5c 100644 --- a/PACE/pace/vxworks/unistd.inl +++ b/PACE/pace/vxworks/unistd.inl @@ -366,7 +366,7 @@ PACE_INLINE ssize_t pace_read (PACE_HANDLE fildes, void * buf, size_t nbyte) { - return read (fildes, buf, nbyte); + return read (fildes, PACE_NONCONST_ARG_CAST (char *) buf, nbyte); } #endif /* PACE_HAS_POSIX_DI_UOF */ @@ -501,6 +501,6 @@ PACE_INLINE ssize_t pace_write (PACE_HANDLE fildes, const void * buf, size_t nbyte) { - return write (fildes, PACE_NONCONST_ARG_CAST (void *) buf, nbyte); + return write (fildes, PACE_NONCONST_ARG_CAST (char *) buf, nbyte); } #endif /* PACE_HAS_POSIX_DI_UOF */ |