📄 pthread.c
字号:
/**************************************************************************
* FILE NAME:
* pthread.c
*
* DESCRIPTION:
* This file includes functions simulator the pthread function calls.
* NOTES:
* The posix function 'nanosleep()' in pthread_delay_np() needs
* hardware support, change to nanosleep when it is ready.
* Not all the pthreads functions are simulated. We take what we need.
*
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
* EDIT HISTORY
* $Log: pthread.c,v $
* Revision 1.5 2003/08/27 09:08:00 patrick
* skip copy when arg_len == 0
*
* Revision 1.4 2003/08/27 05:28:53 rexyan
* Added comments
*
* Revision 1.3 2003/08/27 04:53:27 rexyan
* In pthread_get_num, added thread_seq_num = 1;
* In pthread_con_timedwait, added send tid to msgQ;
* in pthread_create, added a input parameter arg_len
*
* Revision 1.2 2003/08/26 04:04:17 rexyan
* Added EDIT HISTORY
*
*
**************************************************************************
*/
#include <vxWorks.h>
#include <stdio.h>
#include <msgQLib.h>
#include <taskLib.h>
#include <sysLib.h>
#include <time.h>
#include <timers.h>
#include "pthread.h"
static thread_seq_num[PTHR_MAX_THREAD_NUM];
static inited = 0;
#define DEFAULT_PRI 100 /* default task priority */
#define DEFAULT_STACK 6400 /* default stack size */
/**************************************************************************
* FUNCTION NAME:
* pthread_delay_np
*
* DESCRIPTION:
* This function causes the calling thread to delay for the specified
* duration.
* Althoufg time is specified in seconds and nanoseconds, the system has
* approximately millsecond granularity. Due to the scheduling and
* priorities, the amount of time you actualy wait might be slightly more
* or less than the amount of the time specified.
*
* INPUTS:
* 1. const struct timespec *t -- pointer to the duration of the delay
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
* The posix function 'nanosleep()' in pthread_delay_np() needs
* hardware support, change to nanosleep when it is ready.
*
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
**************************************************************************
*/
int pthread_delay_np(const struct timespec *t)
{
long int timeval; /* in ms */
timeval = t->tv_sec*1000 + t->tv_nsec/1000;
if(taskDelay(timeval*sysClkRateGet()/1000) == ERROR) return PTHR_FAILURE;
/* if(nanosleep(t, NULL) == ERROR) return PTHR_FAILURE; */
return PTHR_SUCCESS;
}
/**************************************************************************
* FUNCTION NAME:
* pthread_cond_init
*
* DESCRIPTION:
* This function initializes a conditional variable.
*
* INPUTS:
* 1. pthread_cond_t *cond -- pointer to the conditional variable
* 2. NULL
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
* The second parameter is actually is not used here. It might be a NULL
* when you call this function.
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
**************************************************************************
*/
int pthread_cond_init(pthread_cond_t *cond , const pthread_cond_attr_t * attr)
{
if (!cond)
return PTHR_FAILURE;
cond->defunct = TRUE;
if ((cond->waite_msg_q = msgQCreate(PTHR_MAX_WAITERS, sizeof(int),
MSG_Q_FIFO)) == NULL)
return PTHR_FAILURE;
cond->defunct = FALSE;
return PTHR_SUCCESS;
}
/**************************************************************************
* FUNCTION NAME:
* pthread_cond_destory
*
* DESCRIPTION:
* This function removes a conditional variable.
*
* INPUTS:
* 1. pthread_cond_t *cond -- pointer to the conditional variable
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
*
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
**************************************************************************
*/
int pthread_cond_destroy(pthread_cond_t * cond)
{
int tid;
if (!cond)
return PTHR_FAILURE;
cond->defunct = TRUE;
while (msgQNumMsgs(cond->waite_msg_q) > 0) {
if (msgQReceive(cond->waite_msg_q, (char *)&tid, sizeof(int),
WAIT_FOREVER) == ERROR) {
printf("ERROR: pthread_cond_signal can't read waiter tid\n");
return PTHR_FAILURE;
}
if (taskResume(tid) == ERROR) {
printf("ERROR: pthread_cond_signal can't restart task %d\n", tid);
return PTHR_FAILURE;
}
}
if (msgQDelete(cond->waite_msg_q) == ERROR) {
printf("ERROR: pthread_cond_destroy can't delete msgQ!\n");
return PTHR_FAILURE;
}
return PTHR_SUCCESS;
}
/**************************************************************************
* FUNCTION NAME:
* pthread_cond_wait
*
* DESCRIPTION:
* This function blocks the calling thread, waiting for the condition
* specified by cond to be signaled or broadcast to.
* When the function is called, the calling thread must have mutex locked.
* It atomically unlocks mutex and performs the wait for the condition.
* In this case, atomically means with repect to the mutex and the condition
* variable and another threads access to those objects through the pthread
* condition variable interfaces.
*
* INPUTS:
* 1. pthread_cond_t *cond -- pointer to the conditional variable
* 2. pthread_mutex_t * mutex -- pointer to the mutex semaphore
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
*
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
**************************************************************************
*/
int pthread_cond_wait(pthread_cond_t * cond , pthread_mutex_t * mutex)
{
int tid, status;
if (!cond || !mutex || cond->defunct)
return PTHR_FAILURE;
tid = taskIdSelf();
if (msgQSend(cond->waite_msg_q, (char *) &tid, sizeof(int),
WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR) {
printf("ERROR: pthread_cond_wait can't place taskId on waiters msgQ\n");
return PTHR_FAILURE;
}
if (pthread_mutex_unlock(mutex) != PTHR_SUCCESS) {
printf("ERROR: pthread_cond_wait can't unlock mutex %x\n", mutex);
return PTHR_FAILURE;
}
if ((status = taskSuspend(tid)) != OK) {
printf("ERROR: pthread_cond_wait can't suspend task 5d\n", tid);
return PTHR_FAILURE;
}
if (pthread_mutex_lock(mutex) != PTHR_SUCCESS) {
printf("ERROR: pthread_cond_wait can't reacquire mutex %x\n", mutex);
return PTHR_FAILURE;
}
return PTHR_SUCCESS;
}
/**************************************************************************
* FUNCTION NAME:
* pthread_cond_timedwait
*
* DESCRIPTION:
* This function is the timed version of pthread_cond_wait
*
* INPUTS:
* 1. pthread_cond_t *cond -- pointer to the conditional variable
* 2. pthread_mutex_t * mutex -- pointer to the mutex semaphore
* 3. const struct timespec * abstime -- pointer to the duration
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
*
* AUTHOR:
* Rex Yan, <rexyan@lucent.com>
*
**************************************************************************
*/
int pthread_cond_timedwait(pthread_cond_t * cond , pthread_mutex_t * mutex,
const struct timespec * abstime)
{
int tid, status;
if (!cond || !mutex || !abstime)
return PTHR_FAILURE;
tid = taskIdSelf();
if (msgQSend(cond->waite_msg_q, (char *) &tid, sizeof(int),
WAIT_FOREVER, MSG_PRI_NORMAL) == ERROR) {
printf("ERROR: pthread_cond_wait can't place taskId on waiters msgQ\n");
return PTHR_FAILURE;
}
if (pthread_mutex_unlock(mutex) != PTHR_SUCCESS) {
printf("ERROR: pthread_cond_wait can't unlock mutex %x\n", mutex);
return PTHR_FAILURE;
}
pthread_delay_np(abstime);
if (pthread_mutex_lock(mutex) != PTHR_SUCCESS) {
printf("ERROR: pthread_cond_wait can't reacquire mutex %x\n", mutex);
return PTHR_FAILURE;
}
return PTHR_SUCCESS;
}
/**************************************************************************
* FUNCTION NAME:
* pthread_cond_signal
*
* DESCRIPTION:
* This function wakes up at least one thread that is currently waiting
* on the condition variable specified by cond. If no threads are currently
* blocked on condition variable, this call has no effect.
*
* INPUTS:
* 1. pthread_cond_t *cond -- pointer to the conditional variable
*
* OUTPUTS:
* N/A
*
* RETURN:
* PTHR_SUCCESS -- success
* PTHR_FAILURE -- failure
*
* NOTES:
*
* AUTHOR:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -