|
version 1.13.2.3, 2012/08/22 23:43:36
|
version 1.13.2.4, 2012/08/23 02:09:54
|
|
Line 57 sched_useTask(sched_root_task_t * __restrict root)
|
Line 57 sched_useTask(sched_root_task_t * __restrict root)
|
| { |
{ |
| sched_task_t *task, *tmp; |
sched_task_t *task, *tmp; |
| |
|
| TAILQ_FOREACH_SAFE(task, &root->root_unuse, task_node, tmp) { |
|
| if (!TASK_ISLOCKED(task)) { |
|
| #ifdef HAVE_LIBPTHREAD |
#ifdef HAVE_LIBPTHREAD |
| pthread_mutex_lock(&root->root_mtx[taskUNUSE]); | pthread_mutex_lock(&root->root_mtx[taskUNUSE]); |
| #endif |
#endif |
| |
TAILQ_FOREACH_SAFE(task, &root->root_unuse, task_node, tmp) { |
| |
if (!TASK_ISLOCKED(task)) { |
| TAILQ_REMOVE(&root->root_unuse, task, task_node); |
TAILQ_REMOVE(&root->root_unuse, task, task_node); |
| #ifdef HAVE_LIBPTHREAD |
|
| pthread_mutex_unlock(&root->root_mtx[taskUNUSE]); |
|
| #endif |
|
| break; |
break; |
| } |
} |
| } |
} |
| |
#ifdef HAVE_LIBPTHREAD |
| |
pthread_mutex_unlock(&root->root_mtx[taskUNUSE]); |
| |
#endif |
| |
|
| if (!task) { |
if (!task) { |
| task = malloc(sizeof(sched_task_t)); |
task = malloc(sizeof(sched_task_t)); |
|
Line 108 sched_unuseTask(sched_task_t * __restrict task)
|
Line 108 sched_unuseTask(sched_task_t * __restrict task)
|
| |
|
| #pragma GCC visibility push(hidden) |
#pragma GCC visibility push(hidden) |
| |
|
| |
#ifdef HAVE_LIBPTHREAD |
| |
static void |
| |
_sched_threadCleanup(sched_task_t *t) |
| |
{ |
| |
if (!t || !TASK_ROOT(t)) |
| |
return; |
| |
|
| |
if (TASK_FLAG(t) == PTHREAD_CREATE_JOINABLE) |
| |
pthread_detach(pthread_self()); |
| |
|
| |
sched_unuseTask(t); |
| |
} |
| void * |
void * |
| _sched_threadJoin(sched_task_t *task) | _sched_threadWrapper(sched_task_t *t) |
| { |
{ |
| void *ret = NULL; |
void *ret = NULL; |
| |
|
| if (!task) | if (!t || !TASK_ROOT(t)) |
| return NULL; | pthread_exit(ret); |
| |
|
| #ifdef HAVE_LIBPTHREAD | pthread_cleanup_push((void (*)(void*)) _sched_threadCleanup, t); |
| if (pthread_kill((pthread_t) TASK_VAL(task), 0)) { | |
| pthread_join((pthread_t) TASK_VAL(task), &ret); | |
| TASK_ROOT(task)->root_ret = ret; | |
| } else { | |
| usleep(10000); | |
| schedTaskSelf(task); | |
| } | |
| #endif | |
| |
|
| return NULL; | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); |
| | pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); |
| | pthread_testcancel(); |
| | |
| | ret = TASK_FUNC(t)(t); |
| | |
| | pthread_cleanup_pop(42); |
| | TASK_ROOT(t)->root_ret = ret; |
| | pthread_exit(ret); |
| } |
} |
| |
#endif |
| |
|
| #pragma GCC visibility pop |
#pragma GCC visibility pop |
| |
|
|
Line 148 sched_taskExit(sched_task_t *task, intptr_t retcode)
|
Line 161 sched_taskExit(sched_task_t *task, intptr_t retcode)
|
| TASK_ROOT(task)->root_hooks.hook_exec.exit(task, (void*) retcode); |
TASK_ROOT(task)->root_hooks.hook_exec.exit(task, (void*) retcode); |
| |
|
| TASK_ROOT(task)->root_ret = (void*) retcode; |
TASK_ROOT(task)->root_ret = (void*) retcode; |
| |
|
| #ifdef HAVE_LIBPTHREAD |
|
| if (TASK_TYPE(task) == taskTHREAD) { |
|
| if (TASK_FLAG(task) == PTHREAD_CREATE_JOINABLE) /* joinable thread */ |
|
| schedTask(TASK_ROOT(task), _sched_threadJoin, TASK_ARG(task), |
|
| TASK_VAL(task), TASK_DATA(task), TASK_DATLEN(task)); |
|
| sched_unuseTask(task); |
|
| pthread_exit((void*) retcode); |
|
| } |
|
| #endif |
|
| |
|
| return (void*) retcode; |
return (void*) retcode; |
| } |
} |
| |
|