summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-06-12 19:55:30 +0000
committerjoeh <joeh@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2001-06-12 19:55:30 +0000
commit04bdfccc14f14306ecf03ca3a1b1cb186fdbe901 (patch)
tree1d866ec3aa7f8187066fe7e089c3c22bc80bf050
parentacda1919234808028b0bf5f812acb7b73716ba46 (diff)
downloadATCD-04bdfccc14f14306ecf03ca3a1b1cb186fdbe901.tar.gz
ChangeLogTag: Tue Jun 12 14:46:48 2001 Joe Hoffert <joeh@cs.wustl.edu>
-rw-r--r--PACE/ChangeLog25
-rw-r--r--PACE/THANKS5
-rw-r--r--PACE/pace/config/config.h4
-rw-r--r--PACE/pace/pthread.h56
-rw-r--r--PACE/pace/vxworks/pthread.c858
-rw-r--r--PACE/pace/vxworks/pthread.h19
-rw-r--r--PACE/pace/vxworks/pthread.inl881
-rw-r--r--PACE/pace/vxworks/time.inl1
-rw-r--r--PACE/pace/vxworks/unistd.inl4
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 */