summaryrefslogtreecommitdiff
path: root/PACE/pace/vxworks/pthread.c
diff options
context:
space:
mode:
Diffstat (limited to 'PACE/pace/vxworks/pthread.c')
-rw-r--r--PACE/pace/vxworks/pthread.c879
1 files changed, 0 insertions, 879 deletions
diff --git a/PACE/pace/vxworks/pthread.c b/PACE/pace/vxworks/pthread.c
deleted file mode 100644
index d34f496dc87..00000000000
--- a/PACE/pace/vxworks/pthread.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/* $Id$
-
- * =============================================================================
- *
- * = LIBRARY
- * pace
- *
- * = FILENAME
- * pace/vxworks/pthread.c
- *
- * = AUTHOR
- * Joe Hoffert. The *VAST* majority of the pthread code for VxWorks
- * has been supplied by Hughes Network Systems via Braeton Taylor.
- *
- * ============================================================================= */
-
-#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 */