//.........这里部分代码省略.........
ptcb->cmn.flags |= TCB_FLAG_SCHED_FIFO;
break;
#if CONFIG_RR_INTERVAL > 0
case SCHED_RR:
ptcb->cmn.flags |= TCB_FLAG_SCHED_RR;
ptcb->cmn.timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
break;
#endif
#ifdef CONFIG_SCHED_SPORADIC
case SCHED_SPORADIC:
ptcb->cmn.flags |= TCB_FLAG_SCHED_SPORADIC;
break;
#endif
#if 0 /* Not supported */
case SCHED_OTHER:
ptcb->cmn.flags |= TCB_FLAG_SCHED_OTHER;
break;
#endif
}
/* Get the assigned pid before we start the task (who knows what
* could happen to ptcb after this!). Copy this ID into the join structure
* as well.
*/
pid = (int)ptcb->cmn.pid;
pjoin->thread = (pthread_t)pid;
/* Initialize the semaphores in the join structure to zero. */
ret = sem_init(&pjoin->data_sem, 0, 0);
if (ret == OK)
{
ret = sem_init(&pjoin->exit_sem, 0, 0);
}
/* Activate the task */
sched_lock();
if (ret == OK)
{
ret = task_activate((FAR struct tcb_s *)ptcb);
}
if (ret == OK)
{
/* Wait for the task to actually get running and to register
* its join structure.
*/
(void)pthread_takesemaphore(&pjoin->data_sem);
/* Return the thread information to the caller */
if (thread)
{
*thread = (pthread_t)pid;
}
if (!pjoin->started)
{
ret = EINVAL;
}
/***** main program *****/
int main(int argc, char *argv[])
{
pthread_mutex_t mtx_null, mtx_def;
pthread_mutexattr_t mattr;
pthread_t thr;
pthread_mutex_t * tab_mutex[2]={&mtx_null, &mtx_def};
int tab_res[2][3]={{0,0,0},{0,0,0}};
int ret;
void * th_ret;
int i;
output_init();
#if VERBOSE >1
output("Test starting...\n");
#endif
/* We first initialize the two mutexes. */
if ((ret=pthread_mutex_init(&mtx_null, NULL)))
{ UNRESOLVED(ret, "NULL mutex init"); }
if ((ret=pthread_mutexattr_init(&mattr)))
{ UNRESOLVED(ret, "Mutex attribute init"); }
if ((ret=pthread_mutex_init(&mtx_def, &mattr)))
{ UNRESOLVED(ret, "Default attribute mutex init"); }
if ((ret=pthread_mutexattr_destroy(&mattr)))
{ UNRESOLVED(ret, "Mutex attribute destroy"); }
if ((ret=sem_init(&semA, 0, 0)))
{ UNRESOLVED(errno, "Sem A init"); }
if ((ret=sem_init(&semB, 0, 0)))
{ UNRESOLVED(errno, "Sem B init"); }
#if VERBOSE >1
output("Data initialized...\n");
#endif
/* OK let's go for the first part of the test : abnormals unlocking */
/* We first check if unlocking an unlocked mutex returns an error. */
retval = pthread_mutex_unlock(tab_mutex[0]);
ret = pthread_mutex_unlock(tab_mutex[1]);
#if VERBOSE >0
output("Results for unlock issue #1:\n mutex 1 unlocking returned %i\n mutex 2 unlocking returned %i\n",
retval, ret);
#endif
if (ret != retval)
{
FAILED("Unlocking an unlocked mutex behaves differently.");
}
/* Now we focus on unlocking a mutex lock by another thread */
for (i=0; i<2; i++)
{
p_mtx = tab_mutex[i];
tab_res[i][0]=0;
tab_res[i][1]=0;
tab_res[i][2]=0;
#if VERBOSE >1
output("Creating thread (unlock)...\n");
#endif
if ((ret = pthread_create(&thr, NULL, unlock_issue, NULL)))
{ UNRESOLVED(ret, "Unlock issue thread create"); }
if ((ret = sem_wait(&semA)))
{ UNRESOLVED(errno, "Sem A wait failed for unlock issue."); }
#if VERBOSE >1
output("Unlocking in parent...\n");
#endif
retval = pthread_mutex_unlock(p_mtx);
if ((ret = sem_post(&semB)))
{ UNRESOLVED(errno, "Sem B post failed for unlock issue."); }
if ((ret=pthread_join(thr, &th_ret)))
{ UNRESOLVED(ret, "Join thread"); }
#if VERBOSE >1
output("Thread joined successfully...\n");
#endif
tab_res[i][0] = retval;
}
#if VERBOSE >0
output("Results for unlock issue #2:\n mutex 1 returned %i\n mutex 2 returned %i\n",
tab_res[0][0],tab_res[1][0]);
#endif
if (tab_res[0][0] != tab_res[1][0])
{
//.........这里部分代码省略.........
/****************************** INITIALIZATION *******************************/
int SCP_concurrent::init( bool bcount = false )
{
/* lock global mutex */
int result = pthread_mutex_lock( &mrh_mutex );
int ret, ret_init;
switch (result)
{
case 0: // OK
/* initialize binary semaphore with 0 */
ret_init = sem_init( &(mr_event_table[ mn_id ]), 0, 0 );
if(bcount)
{
/* iterator for count table */
std::map<int, int>::iterator it;
/* pick first element in the map */
it = mr_count_table.begin();
/* check if its count is valid number */
if( (*it).second >= 0 )
{
/* runtime; init count variable with count
* variable of any other object (let it
* be first) */
mr_count_table[ mn_id ] = (*it).second;
}
else
{
/* assign 0 in case of bad element */
mr_count_table[ mn_id ] = 0;
}
}
else
{
/* startup; init count variable with 0 */
mr_count_table[ mn_id ] = 0;
}
/* init missedwakeups variable with 0 */
mr_missed_wakeups[ mn_id ] = 0;
/* release global mutex */
ret = pthread_mutex_unlock( &mrh_mutex );
switch(ret)
{
case 0: /* success */
/* if not zero,return semaphore initialization error */
if( ret_init != 0 )
return -3;
else
break;
case EINVAL:
/* mutex has not been properly initialized */
return -2;
default:
/* other mutex problem */
return -1;
}
break;
case EINVAL:
/* mutex has not been properly initialized */
return -2;
case EDEADLK:
/* mutex is already owned by the calling thread */
return -4;
default:
/* other mutex problem */
return -1;
}
return 1; /* return SUCCESS */
}
开发者ID:voldymyr,项目名称:SCP,代码行数:69,代码来源:scp_impl.cpp
示例15: main
Int main (Int argc, Char * argv [])
{
pthread_t thread_sys; /* server thread object */
pthread_t thread_app; /* server thread object */
pthread_t thread_dsp; /* server thread object */
Char * log_file = NULL;
Bool daemon = TRUE;
Int i;
traceBufferParams args_sys;
traceBufferParams args_app;
traceBufferParams args_dsp;
/* parse cmd-line args */
for (i = 1; i < argc; i++) {
if (!strcmp ("-l", argv[i])) {
if (++i >= argc) {
printUsageExit (argv[0]);
}
log_file = argv[i];
}
else if (!strcmp ("-f", argv[i])) {
daemon = FALSE;
}
else if (!strcmp ("-h", argv[i])) {
printUsageExit (argv[0]);
}
}
Osal_printf ("Spawning Ducati-Tesla Trace daemon...\n");
if (daemon) {
pid_t child_pid;
pid_t child_sid;
/* Fork off the parent process */
child_pid = fork ();
if (child_pid < 0) {
Osal_printf ("Spawning Trace daemon failed!\n");
exit (EXIT_FAILURE); /* Failure */
}
/* If we got a good PID, then we can exit the parent process. */
if (child_pid > 0) {
exit (EXIT_SUCCESS); /* Success */
}
/* Create a new SID for the child process */
child_sid = setsid ();
if (child_sid < 0) {
Osal_printf ("setsid failed!\n");
exit (EXIT_FAILURE); /* Failure */
}
}
if (log_file == NULL) {
log = NULL;
}
else {
if (strcmp (log_file, "stdout") == 0) {
/* why do we need this? It would be an issue when logging to file.. */
/* Change file mode mask */
umask (0);
log = stdout;
}
else {
log = fopen (log_file, "a+");
if (log == NULL ) {
Osal_printf("Failed to open file: %s\n", log_file);
exit (EXIT_FAILURE); /* Failure */
}
}
}
/* Change the current working directory */
if ((chdir("/")) < 0) {
Osal_printf ("chdir failed!\n");
exit (EXIT_FAILURE); /* Failure */
}
sem_init (&semPrint, 0, 1);
UsrUtilsDrv_setup ();
args_sys.coreName = "[SYSM3]: ";
args_sys.bufferAddress = SYSM3_TRACE_BUFFER_PHYS_ADDR;
args_app.coreName = "[APPM3]: ";
args_app.bufferAddress = APPM3_TRACE_BUFFER_PHYS_ADDR;
args_dsp.coreName = "[DSP]: ";
args_dsp.bufferAddress = TESLA_TRACE_BUFFER_PHYS_ADDR;
pthread_create (&thread_sys, NULL, (Void *)&printRemoteTraces,
(Void*)&args_sys);
pthread_create (&thread_app, NULL, (Void *)&printRemoteTraces,
(Void*)&args_app);
pthread_create (&thread_dsp, NULL, (Void *)&printRemoteTraces,
(Void*)&args_dsp);
pthread_join (thread_sys, NULL);
Osal_printf ("SysM3 trace thread exited\n");
pthread_join (thread_app, NULL);
//.........这里部分代码省略.........
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
{
FAR struct task_group_s *group;
int ret;
DEBUGASSERT(tcb && !tcb->cmn.group);
/* Allocate the group structure and assign it to the TCB */
group = (FAR struct task_group_s *)kmm_zalloc(sizeof(struct task_group_s));
if (!group)
{
return -ENOMEM;
}
#if CONFIG_NFILE_STREAMS > 0 && (defined(CONFIG_BUILD_PROTECTED) || \
defined(CONFIG_BUILD_KERNEL)) && defined(CONFIG_MM_KERNEL_HEAP)
/* If this group is being created for a privileged thread, then all elements
* of the group must be created for privileged access.
*/
if ((ttype & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
{
group->tg_flags |= GROUP_FLAG_PRIVILEGED;
}
/* In a flat, single-heap build. The stream list is allocated with the
* group structure. But in a kernel build with a kernel allocator, it
* must be separately allocated using a user-space allocator.
*/
group->tg_streamlist = (FAR struct streamlist *)
group_zalloc(group, sizeof(struct streamlist));
if (!group->tg_streamlist)
{
kmm_free(group);
return -ENOMEM;
}
#endif
/* Attach the group to the TCB */
tcb->cmn.group = group;
#if defined(HAVE_GROUP_MEMBERS) || defined(CONFIG_ARCH_ADDRENV)
/* Assign the group a unique ID. If g_gidcounter were to wrap before we
* finish with task creation, that would be a problem.
*/
group_assigngid(group);
#endif
/* Duplicate the parent tasks environment */
ret = env_dup(group);
if (ret < 0)
{
#if CONFIG_NFILE_STREAMS > 0 && (defined(CONFIG_BUILD_PROTECTED) || \
defined(CONFIG_BUILD_KERNEL)) && defined(CONFIG_MM_KERNEL_HEAP)
group_free(group, group->tg_streamlist);
#endif
kmm_free(group);
tcb->cmn.group = NULL;
return ret;
}
#ifndef CONFIG_DISABLE_PTHREAD
/* Initialize the pthread join semaphore */
(void)sem_init(&group->tg_joinsem, 0, 1);
#endif
#if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT)
/* Initialize the exit/wait semaphores
*
* This semaphore is used for signaling and, hence, should not have
* priority inheritance enabled.
*/
(void)sem_init(&group->tg_exitsem, 0, 0);
(void)sem_setprotocol(&group->tg_exitsem, SEM_PRIO_NONE);
#endif
return OK;
}
/** parent thread function **/
int main(int argc, char * argv[])
{
int ret;
int i;
pthread_mutexattr_t ma;
pthread_t child;
output_init();
#if VERBOSE >1
output("Initialize the PTHREAD_MUTEX_RECURSIVE mutex\n");
#endif
/* Initialize the semaphore */
if ((ret = sem_init(&sem, 0, 0)))
{ UNRESOLVED(ret, "Sem init failed"); }
/* We initialize the recursive mutex */
if ((ret = pthread_mutexattr_init(&ma)))
{ UNRESOLVED(ret, "Mutex attribute init failed"); }
if ((ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE)))
{ UNRESOLVED(ret, "Set type RECURSIVE failed"); }
if ((ret = pthread_mutex_init(&mtx, &ma)))
{ UNRESOLVED(ret, "Recursive mutex init failed"); }
if ((ret = pthread_mutexattr_destroy(&ma)))
{ UNRESOLVED(ret, "Mutex attribute destroy failed"); }
/* -- The mutex is now ready for testing -- */
/* First, we lock it twice and unlock once */
if ((ret = pthread_mutex_lock(&mtx)))
{ UNRESOLVED(ret, "First lock failed"); }
if ((ret = pthread_mutex_lock(&mtx)))
{ FAILED("Second lock failed"); }
if ((ret = pthread_mutex_unlock(&mtx)))
{ FAILED("First unlock failed"); }
#if VERBOSE >1
output("The mutex has been locked twice and unlocked once, start the thread now.\n");
#endif
/* Here this thread owns the mutex and the internal count is "1" */
/* We create the child thread */
if ((ret = pthread_create(&child, NULL, threaded, NULL)))
{ UNRESOLVED(ret, "Unable to create child thread"); }
/* then wait for child to be ready */
if ((ret = sem_wait(&sem)))
{ UNRESOLVED(errno, "Wait sem in child failed"); }
#if VERBOSE >1
output("[main] unlock the mutex.\n");
#endif
/* We can now unlock the mutex */
if ((ret = pthread_mutex_unlock(&mtx)))
{ FAILED("Second unlock failed"); }
/* We wait for the child to lock the mutex */
if ((ret = sem_wait(&sem)))
{ UNRESOLVED(errno, "Wait sem in child failed"); }
/* Then, try to unlock the mutex (owned by the child or unlocked) */
ret = pthread_mutex_unlock(&mtx);
if (ret == 0)
{ FAILED("Unlock of unowned mutex succeeds"); }
/* Everything seems OK here */
if ((ret = pthread_join(child, NULL)))
{ UNRESOLVED(ret, "Child join failed"); }
/* Simple loop to double-check */
#if VERBOSE >1
output("[main] joined the thread.\n");
output("Lock & unlock the mutex 50 times.\n");
#endif
for (i=0; i<50; i++)
{
if ((ret = pthread_mutex_lock(&mtx)))
{ FAILED("Lock failed in loop"); }
}
for (i=0; i<50; i++)
{
if ((ret = pthread_mutex_unlock(&mtx)))
{ FAILED("Unlock failed in loop"); }
}
ret = pthread_mutex_unlock(&mtx);
if (ret == 0)
{ FAILED("Unlock succeeds after the loop"); }
#if VERBOSE >1
//.........这里部分代码省略.........
请发表评论