int thread_join(struct thread *t, void **p_ret) { struct thread *current = thread_self(); int ret = 0; assert(t); if (t == current) return -EDEADLK; sched_lock(); { assert(!(t->state & TS_DETACHED)); if (!(t->state & TS_EXITED)) { assert(!t->joining); t->joining = current; ret = SCHED_WAIT(t->state & TS_EXITED); if (ret) { goto out; } } if (p_ret) *p_ret = t->run_ret; thread_delete(t); } out: sched_unlock(); return ret < 0 ? ret : 0; }
/* * Delete threads created by create_filler_threads. */ void delete_filler_threads(void) { while (allocated_threads > 0) { thread_delete(thread_l4tid(threads[allocated_threads - 1])); allocated_threads--; } }
static void dnscache_delete(dnscache_t *dnscache) { event_free(dnscache->sig_int_event_); event_free(dnscache->sig_term_event_); thread_delete(dnscache); thread_pool_delete(dnscache->tp_); free(dnscache->listen_socket); free(dnscache); }
END_TEST START_TEST(PD0600) { thread_ref_t iguana_thrd = 0; L4_ThreadId_t l4_thrd; iguana_thrd = pd_create_thread_with_priority(pd_myself(), 100, &l4_thrd); fail_if(iguana_thrd == 0, "NULL thread returned"); if (iguana_thrd != 0) { thread_delete(l4_thrd); } }
int main() { kprintf("Thread '%s' started.\n", thread_self()->td_name); td0 = thread_self(); td1 = thread_create("first", demo_thread_1, NULL); td2 = thread_create("second", demo_thread_2, NULL); thread_switch_to(td1); kprintf("Thread '%s' running.\n", thread_self()->td_name); assert(td0 == thread_get_by_tid(td0->td_tid)); assert(td1 == thread_get_by_tid(td1->td_tid)); assert(td2 == thread_get_by_tid(td2->td_tid)); assert(NULL == thread_get_by_tid(1234)); thread_dump_all(); thread_delete(td2); thread_delete(td1); return 0; }
status_t thread_create(thread_t *pthd, Fxn fxn, thread_attrs_t * attrs, ...) { int i; va_list va; status_t status = OSA_SOK; struct __thread_t * thd = NULL; thread_check_arguments2(pthd, fxn); (*pthd) = INVALID_HANDLE; status = OSA_memAlloc(sizeof(struct __thread_t), &thd); if (OSA_ISERROR(status) || thd == NULL) { return status; } thd->pri = attrs->priority; /* * TODO: Bug here, the attrs variable may be exist at stack, * the thd_hdl->name pointer may be invalid soon. */ thd->name = attrs->name; thd->env = attrs->environ; thd->fxn = fxn; thd->thd_status = -1; thd->exit_status = -1; /* Copy up to 'THREAD_MAX_ARGS' arguments from task */ va_start(va, attrs); for (i = 0; i < OSA_ARRAYSIZE(thd->args); i++) { thd->args[i] = va_arg(va, Arg); } va_end(va); /* Create a realtime detached thread */ pthread_attr_init(&thd->pattrs); pthread_attr_setdetachstate(&thd->pattrs, PTHREAD_CREATE_DETACHED); thd->thd_status = pthread_create(&thd->thd_id, &thd->pattrs, (void * (*)(void *))__thread_run_stub, (void *)thd); if (thd->thd_status != 0) { thread_delete((thread_t *)&thd); } (*pthd) = (thread_t)thd; return status; }
int zfp_transport_delete(zfp_transport_t *transport) { if (transport == NULL) return ZISS_ERROR; if (transport->thread != NULL) { thread_delete(transport->thread); transport->thread = NULL; } free(transport); transport = NULL; return ZISS_OK; }
END_TEST START_TEST(test_pd_create_thread_with_priority) { thread_ref_t iguana_thrd = 0; L4_ThreadId_t l4_thrd; pd_ref_t newpd = 0; newpd = pd_create(); fail_if(newpd == 0, "NULL pd returned"); iguana_thrd = pd_create_thread_with_priority(newpd, 100, &l4_thrd); fail_if(iguana_thrd == 0, "NULL thread returned"); thread_delete(l4_thrd); pd_delete(newpd); }
END_TEST #if 0 START_TEST(test_pd_create_thread) { thread_ref_t iguana_thrd = 0; L4_ThreadId_t l4_thrd; pd_ref_t newpd = 0; newpd = pd_create(); fail_if(newpd == 0, "NULL pd returned"); iguana_thrd = pd_create_thread(newpd, &l4_thrd); fail_if(iguana_thrd == 0, "NULL thread returned"); thread_delete(l4_thrd); pd_delete(newpd); }
/* after thread drd_joiner joined thread drd_joinee. */ void drd_post_thread_join(DrdThreadId drd_joiner, DrdThreadId drd_joinee) { tl_assert(IsValidDrdThreadId(drd_joiner)); tl_assert(IsValidDrdThreadId(drd_joinee)); thread_new_segment(drd_joiner); thread_combine_vc(drd_joiner, drd_joinee); thread_new_segment(drd_joinee); if (s_drd_trace_fork_join) { const ThreadId joiner = DrdThreadIdToVgThreadId(drd_joiner); const ThreadId joinee = DrdThreadIdToVgThreadId(drd_joinee); const unsigned msg_size = 256; char* msg; msg = VG_(malloc)("drd.main.dptj.1", msg_size); tl_assert(msg); VG_(snprintf)(msg, msg_size, "drd_post_thread_join joiner = %d/%d, joinee = %d/%d", joiner, drd_joiner, joinee, drd_joinee); if (joiner) { VG_(snprintf)(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg), ", new vc: "); vc_snprint(msg + VG_(strlen)(msg), msg_size - VG_(strlen)(msg), thread_get_vc(drd_joiner)); } VG_(message)(Vg_DebugMsg, "%s", msg); VG_(free)(msg); } if (! s_drd_check_stack_accesses) { drd_finish_suppression(thread_get_stack_max(drd_joinee) - thread_get_stack_size(drd_joinee), thread_get_stack_max(drd_joinee)); } thread_delete(drd_joinee); mutex_thread_delete(drd_joinee); cond_thread_delete(drd_joinee); semaphore_thread_delete(drd_joinee); barrier_thread_delete(drd_joinee); }
int session_mgr_stop(session_mgr_t *mgr) { if (mgr == NULL) { LOG_ERROR("Invalid session mgr"); return ZISS_ERROR; } if (mgr->thread != NULL) { cond_signal(mgr->exit_cond); thread_stop(mgr->thread); thread_delete(mgr->thread); cond_delete(mgr->exit_cond); mgr->thread = NULL; mgr->exit_cond = NULL; } session_mgr_clear(mgr); return ZISS_OK; }
int thread_detach(struct thread *t) { assert(t); sched_lock(); { assert(!(t->state & TS_DETACHED)); if (!(t->state & TS_EXITED)) { /* The target will free itself upon finishing. */ assert(!t->joining); t->state |= TS_DETACHED; } else /* The target thread has finished, free it here. */ thread_delete(t); } sched_unlock(); return 0; }
END_TEST /* * Repeat of the above test with a changed IID in the reference. * * EXECUTE_IID is chosen because this will result in an unaligned * pointer on most architectures. */ START_TEST(PD0501) { thread_ref_t iguana_thrd = 0; L4_ThreadId_t l4_thrd; iguana_thrd = pd_create_thread(pd_myself(), &l4_thrd); fail_if(iguana_thrd == 0, "NULL thread returned"); if (iguana_thrd != 0) { iguana_thrd |= EXECUTE_IID; thread_delete(l4_thrd); } }
int zsp_listener_stop(zsp_listener_t *listener) { if (listener == NULL) return SSS_ERROR; if (listener->sock != NULL) { socket_shutdown(listener->sock); socket_delete(listener->sock); listener->sock = NULL; } if (listener->thread != NULL) { thread_stop(listener->thread); thread_delete(listener->thread); listener->thread = NULL; } listener->port = 0; return SSS_OK; }
extern int thread_join(struct thread* thread, void **retval){ struct thread* current = thread_current; struct thread* tmp = NULL; int i = 0; // Si l'on a jamais appelé thread_create if (thread_current == NULL) exit(-1); //structure_print(thread_set); // Si le thread n'est pas déjà fini if (!thread->isfinished) { thread->joiner = thread_current; // passer la main tmp = structure_get(thread_set); if (tmp == NULL){ fprintf(stderr, "%s l.%d:\t%s\n", __FILE__, __LINE__, "Problème si l'on attends un thread qui n'existe pas"); exit(-1); } thread_current = tmp; i = 0; if (getcontext(current->context)) return -1; if ( i == 0 ){ i = 1; if (setcontext(thread_current->context)) return -1; } } // Ici on a repris la main if (retval != NULL) *retval = thread->retval; if (thread_delete(thread)) return -1; return 0; }
void _NORETURN thread_exit(void *ret) { struct thread *current = thread_self(); struct task *task = task_self(); struct thread *joining; /* We can free only not main threads */ if (current == task_get_main(task)) { /* We are last thread. */ task_exit(ret); /* NOTREACHED */ } sched_lock(); // sched_finish(current); current->schedee.waiting = true; current->state |= TS_EXITED; /* Wake up a joining thread (if any). * Note that joining and run_ret are both in a union. */ joining = current->joining; current->run_ret = ret; if (joining) { sched_wakeup(&joining->schedee); } if (current->state & TS_DETACHED) /* No one references this thread anymore. Time to delete it. */ thread_delete(current); schedule(); /* NOTREACHED */ sched_unlock(); /* just to be honest */ panic("Returning from thread_exit()"); }
int main(int argc, char **argv) { struct okl4_libmutex rm; L4_ThreadId_t tid; int i, max_iteration, eg_num, server_on; L4_Word_t me; L4_MsgTag_t tag = L4_Niltag; /*** Initialisation ***/ pi_main = thread_l4tid(env_thread(iguana_getenv("MAIN"))); me = pi_main.raw; eg_num = max_iteration = server_on = 0; if (argc == 3) { eg_num = atoi(argv[0]); max_iteration = atoi(argv[1]); server_on = atoi(argv[2]); } else { printf("(%s 0x%lx) Error: Argument(s) missing!\n", test_name, me); return 1; } resource_mutex = &rm; okl4_libmutex_init(resource_mutex); high_prio_thread = medium1_prio_thread = medium2_prio_thread = medium3_prio_thread = low_prio_thread = L4_nilthread; high_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_HIGH"))); medium3_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_2"))); medium2_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_MEDIUM"))); medium1_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_1"))); low_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_LOW"))); // Tell other threads that it is safe to use libraries libs_ready = 1; if (!server_on) printf("Start %s test #%d(0x%lx)\n", test_name, eg_num, me); /*** Start test ***/ scenario1 = 1; for (i = 0; i < 2 * max_iteration; i++) { // Wait for threads to be ready tag = L4_Wait(&tid); // If one thread had a problem while initialisation, then stop the test and notify // server that the test is dead. if (L4_Label(tag) == 0xdead) { rtos_init(); test_died(test_name, eg_num); rtos_cleanup(); return 1; } // Tell high prio thread to start the next iteration. L4_LoadMR(0, 0); tag = L4_Send(high_prio_thread); stop_spinning = 0; // Wait for the iteration to finish. L4_Receive(high_prio_thread); stop_spinning = 1; // If end of iterations for scenario1, then report results to RTOS server if server is on. if (i == (max_iteration - 1)) { if (server_on) { rtos_init(); mixed_priority_inversion_results(eg_num, 1, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); } else print_metrics(max_iteration); // Start scenario2 cnt_h = cnt_m1 = cnt_m2 = cnt_l = cnt_i1 = cnt_i2 = 0; scenario1 = 0; scenario2 = 1; } } /*** Test finished ***/ thread_delete(medium1_prio_thread); thread_delete(medium3_prio_thread); thread_delete(high_prio_thread); thread_delete(medium2_prio_thread); thread_delete(low_prio_thread); /* Clean up allocated mutexes. */ okl4_libmutex_free(resource_mutex); // If RTOS server is on, report results to it. if (server_on) { mixed_priority_inversion_results(eg_num, 2, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); rtos_cleanup(); } else { print_metrics(max_iteration); printf("%s test #%d(0x%lx) finished\n", test_name, eg_num, me); } return 0; }
int main(int argc, char **argv) { int i, tmp, eg_num, nb_philosophers, nb_dinners, server_on; L4_ThreadId_t *philo_tids; L4_ThreadId_t tid, any_thread; L4_MsgTag_t tag = L4_Niltag; /*** Initialisation ***/ dp_main = thread_l4tid(env_thread(iguana_getenv("MAIN"))); eg_num = nb_philosophers = nb_dinners = server_on = 0; if (argc == 3) { eg_num = atoi(argv[0]); nb_philosophers = atoi(argv[1]); server_on = atoi(argv[2]); } else { printf("(%s 0x%lx) Error: Argument(s) missing!\n", test_name, dp_main.raw); return 1; } if (!server_on) printf("Start %s test #%d(0x%lx): %d philosophers\n", test_name, eg_num, dp_main.raw, nb_philosophers); chopstick = malloc((nb_philosophers + 1) * sizeof(okl4_libmutex_t)); philo_tids = malloc(nb_philosophers * sizeof(L4_ThreadId_t)); for (i = 0; i < nb_philosophers; i++) { chopstick[i] = malloc (sizeof(struct okl4_libmutex)); okl4_libmutex_init(chopstick[i]); } chopstick[nb_philosophers] = NULL; // Tell other threads that it is safe to use libraries and mutexes libs_ready = 1; // Retrieve philosophers thread Ids and give them a go for (i = 0; i < nb_philosophers; i++) { L4_Wait(&tid); philo_tids[i] = tid; } /*** Start test ***/ meal_served = 1; tmp = nb_philosophers; while (tmp) { tag = L4_Wait(&any_thread); for (i = 0; i < nb_philosophers; i++) { if (any_thread.raw == philo_tids[i].raw) { thread_delete(any_thread); tmp--; if (L4_Label(tag) == 0xfed) { // Philosopher finished eating nb_dinners++; } break; } } } /*** Test finished ***/ free(philo_tids); for (i = 0; i < nb_philosophers; i++) { okl4_libmutex_free(chopstick[i]); free(chopstick[i]); } //free(*chopstick); // If RTOS server is on, report results to it. if (server_on) { rtos_init(); dining_philosophers_results(eg_num, nb_philosophers, nb_dinners); rtos_cleanup(); } else printf("%s test #%d(0x%lx) finished\n", test_name, eg_num, dp_main.raw); return 0; }
int _thread_delete(void *handle) { return thread_delete(handle); }
/* * Get current value, request timeout for different threads, check all notified * correctly. */ static void test02(void) { uint32_t cur_value; L4_Word_t result, i; thread_ref_t thread1, thread2, thread3; L4_ThreadId_t tid1, tid2, tid3, any_thread; L4_Word_t notifybits1 = 0x1; L4_Word_t notifybits2 = 0x2; L4_Word_t notifybits3 = 0x3; L4_MsgTag_t tag; L4_Word_t label; printf("%s: ", __func__); thread1 = thread_create_simple(waiting_notify_thread, NULL, 99); thread2 = thread_create_simple(waiting_notify_thread, NULL, 99); thread3 = thread_create_simple(waiting_notify_thread, NULL, 99); tid1 = thread_l4tid(thread1); tid2 = thread_l4tid(thread2); tid3 = thread_l4tid(thread3); tag = L4_Make_MsgTag(notifybits1, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid1); tag = L4_Make_MsgTag(notifybits2, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid2); tag = L4_Make_MsgTag(notifybits3, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid3); result = counter_current_value(&cur_value); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 10, tid1, notifybits1); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 12, tid2, notifybits2); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 14, tid3, notifybits3); if (result == 0) { FAILED(); return; } for (i = 0; i < 3; i++) { tag = L4_Wait(&any_thread); label = L4_Label(tag); if (((i == 0) && (label != 0x1)) || ((i == 1) && (label != 0x2)) || ((i == 2) && (label != 0x3))) { thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); FAILED(); return; } } thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); PASSED(); }
/* Create a barrier (closed if CLOSED is true, open otherwise), then call CALLBACK with ARG as its argument. The barrier will be in place for the duration of the call to CALLBACK. If either of IN or OUT aren't null pointers then they will be called when the barrier is crossed (while invoking a continuation). Closed barriers are never crossed. DATA is passed to both IN and OUT functions when they are called. The IN function is called when control passes from above barrier on the stack to below; OUT when control passes from below to above. */ repv rep_call_with_barrier (repv (*callback)(repv), repv arg, rep_bool closed, void (*in)(void *), void (*out)(void *), void *data) { repv ret; rep_barrier b; memset (&b, 0, sizeof (b)); b.point = (char *) &b; #if STACK_DIRECTION > 0 b.point += sizeof (rep_barrier); /* don't want to save barrier */ #endif b.root = root_barrier; b.in = in; b.out = out; b.data = data; b.closed = closed; b.depth = barriers ? barriers->depth + 1 : 1; b.next = barriers; barriers = &b; if (closed) root_barrier = &b; DB(("with-barrier[%s]: in %p (%d)\n", closed ? "closed" : "open", &b, b.depth)); ret = callback (arg); if (closed) { rep_thread *ptr; again: if (rep_throw_value == exit_barrier_cell) { DB (("caught barrier exit throw\n")); rep_throw_value = rep_CDR (exit_barrier_cell); ret = (rep_throw_value == rep_NULL) ? Qnil : rep_NULL; rep_CDR (exit_barrier_cell) = Qnil; } if (rep_throw_value == rep_NULL && b.active != 0) { /* An active thread exited. Calling thread_delete () on the active thread will call thread_invoke (). That will exit if there are no more runnable threads. */ DB (("deleting active thread %p\n", b.active)); thread_delete (b.active); goto again; } if (b.targeted) { /* Invalidate any continuations that require this barrier */ rep_continuation *c; for (c = continuations; c != 0; c = c->next) { if (c->root == &b) c->car |= CF_INVALID; } } for (ptr = b.head; ptr != 0; ptr = ptr->next) ptr->car |= TF_EXITED; for (ptr = b.susp_head; ptr != 0; ptr = ptr->next) ptr->car |= TF_EXITED; if (b.active != 0) b.active->car |= TF_EXITED; } DB(("with-barrier[%s]: out %p (%d)\n", closed ? "closed" : "open", &b, b.depth)); barriers = b.next; root_barrier = b.root; return ret; }