int mutex_test(void) { static mutex_t imutex = MUTEX_INITIAL_VALUE(imutex); printf("preinitialized mutex:\n"); hexdump(&imutex, sizeof(imutex)); mutex_t m; mutex_init(&m); thread_t *threads[5]; for (uint i=0; i < countof(threads); i++) { threads[i] = thread_create("mutex tester", &mutex_thread, &m, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(threads[i]); } for (uint i=0; i < countof(threads); i++) { thread_join(threads[i], NULL, INFINITE_TIME); } printf("done with simple mutex tests\n"); printf("testing mutex timeout\n"); mutex_t timeout_mutex; mutex_init(&timeout_mutex); mutex_acquire(&timeout_mutex); for (uint i=0; i < 2; i++) { threads[i] = thread_create("mutex timeout tester", &mutex_timeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(threads[i]); } for (uint i=2; i < 4; i++) { threads[i] = thread_create("mutex timeout tester", &mutex_zerotimeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(threads[i]); } thread_sleep(5000); mutex_release(&timeout_mutex); for (uint i=0; i < 4; i++) { thread_join(threads[i], NULL, INFINITE_TIME); } printf("done with mutex tests\n"); mutex_destroy(&timeout_mutex); return 0; }
void quantum_test(void) { thread_resume(thread_create ("quantum tester 0", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create ("quantum tester 1", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create ("quantum tester 2", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create ("quantum tester 3", &quantum_tester, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); }
QTSSvrControlThread::~QTSSvrControlThread() { fDone = true; port_deallocate(task_self(), fMessagePort);//force SC thread to wakeup fMessagePort = 0; //wait for thread to terminate... these mach prototypes are very strange... //why, for instance, does thread_resume take an INT???? if (fThreadsAllocated) { thread_resume((unsigned int)fThreadID);//force a wakeup. cthread_join(fThreadID); thread_resume((unsigned int)fHistoryThreadID); cthread_join(fHistoryThreadID); } }
int boot_script_exec_cmd (void *hook, task_t task, char *path, int argc, char **argv, char *strings, int stringlen) { struct multiboot_module *mod = hook; int err; if (task != MACH_PORT_NULL) { thread_t thread; struct user_bootstrap_info info = { mod, argv, 0, }; simple_lock_init (&info.lock); simple_lock (&info.lock); err = thread_create ((task_t)task, &thread); assert(err == 0); thread->saved.other = &info; thread_start (thread, user_bootstrap); thread_resume (thread); /* We need to synchronize with the new thread and block this main thread until it has finished referring to our local state. */ while (! info.done) { thread_sleep ((event_t) &info, simple_lock_addr(info.lock), FALSE); simple_lock (&info.lock); } printf ("\n"); } return 0; }
static void module_load(multiboot_tag_t *tag) { /* calculate size and phy32 pointer */ size_t size = tag->module.mod_end - tag->module.mod_start; elf64_ehdr_t *elf = (elf64_ehdr_t *) aphy32_to_virt(tag->module.mod_start); /* make a new process */ proc_t *proc = proc_create(); if (!proc) panic("couldn't create process for module"); /* switch our address space */ proc_switch(proc); /* load the ELF file */ if (!elf64_load(elf, size)) panic("couldn't load elf64 file"); /* make a new thread */ thread_t *thread = thread_create(proc, 0); if (!thread) panic("couldn't create thread for module"); /* set entry point of the thread */ thread->rip = elf->e_entry; /* add thread to the scheduler's ready queue */ thread_resume(thread); }
void bsd_utaskbootstrap(void) { thread_t thread; struct uthread *ut; /* * Clone the bootstrap process from the kernel process, without * inheriting either task characteristics or memory from the kernel; */ thread = cloneproc(TASK_NULL, kernproc, FALSE); /* Hold the reference as it will be dropped during shutdown */ initproc = proc_find(1); #if __PROC_INTERNAL_DEBUG if (initproc == PROC_NULL) panic("bsd_utaskbootstrap: initproc not set\n"); #endif /* * Since we aren't going back out the normal way to our parent, * we have to drop the transition locks explicitly. */ proc_signalend(initproc, 0); proc_transend(initproc, 0); ut = (struct uthread *)get_bsdthread_info(thread); ut->uu_sigmask = 0; act_set_astbsd(thread); (void) thread_resume(thread); }
/* LOCKING: assumes the GC lock is held */ int sgen_thread_handshake (BOOL suspend) { SgenThreadInfo *cur_thread = mono_thread_info_current (); kern_return_t ret; SgenThreadInfo *info; int count = 0; FOREACH_THREAD_SAFE (info) { if (info == cur_thread || sgen_is_worker_thread (mono_thread_info_get_tid (info))) continue; if (info->gc_disabled) continue; if (suspend) { if (!sgen_suspend_thread (info)) continue; } else { ret = thread_resume (info->info.native_handle); if (ret != KERN_SUCCESS) continue; } count ++; } END_FOREACH_THREAD_SAFE return count; }
int resume_thread(unsigned int thread) { int i; kern_return_t ret; unsigned int size = THREAD_BASIC_INFO_COUNT; struct thread_basic_info info; ret = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &size); if(ret != KERN_SUCCESS) { fprintf(stderr, "Failed to get thread info 1, got %d\n", ret); // return ok for the case when the process is going away return -1; return 0; } for(i = 0; i < info.suspend_count; i++) { ret = thread_resume(thread); if(ret != KERN_SUCCESS) { fprintf(stderr, "Failed to get thread info 2, got %d\n", ret); return -1; } } return 0; }
static int _thread_cond_signal(cond_t *cond, int broadcast) { /* consistency checks */ if (cond == NULL) return_errno(FALSE, EINVAL); if (!(cond->cn_state & THREAD_COND_INITIALIZED)) return_errno(FALSE, EDEADLK); // do something only if there is at least one waiters (POSIX semantics) if (cond->cn_waiters > 0) { // signal the condition do { thread_t *t = dequeue(&cond->wait_queue); assert (t != NULL); thread_resume(t); // t could also be a timed out thread, but it doesn't matter cond->cn_waiters--; } while (broadcast && !queue_isempty(&cond->wait_queue)); // and give other threads a chance to grab the CPU CAP_SET_SYSCALL(); thread_yield(); CAP_CLEAR_SYSCALL(); } /* return to caller */ return TRUE; }
static void thread_alloc_and_run(struct thread_smc_args *args) { size_t n; struct thread_core_local *l = get_core_local(); bool found_thread = false; assert(l->curr_thread == -1); lock_global(); if (!have_one_active_thread() && !have_one_preempted_thread()) { for (n = 0; n < NUM_THREADS; n++) { if (threads[n].state == THREAD_STATE_FREE) { threads[n].state = THREAD_STATE_ACTIVE; found_thread = true; break; } } } unlock_global(); if (!found_thread) { args->a0 = TEESMC_RETURN_EBUSY; args->a1 = 0; args->a2 = 0; args->a3 = 0; return; } l->curr_thread = n; threads[n].regs.pc = (uint32_t)thread_stdcall_entry; /* Stdcalls starts in SVC mode with masked IRQ and unmasked FIQ */ threads[n].regs.cpsr = CPSR_MODE_SVC | CPSR_I; threads[n].flags = 0; /* Enable thumb mode if it's a thumb instruction */ if (threads[n].regs.pc & 1) threads[n].regs.cpsr |= CPSR_T; /* Reinitialize stack pointer */ threads[n].regs.svc_sp = threads[n].stack_va_end; /* * Copy arguments into context. This will make the * arguments appear in r0-r7 when thread is started. */ threads[n].regs.r0 = args->a0; threads[n].regs.r1 = args->a1; threads[n].regs.r2 = args->a2; threads[n].regs.r3 = args->a3; threads[n].regs.r4 = args->a4; threads[n].regs.r5 = args->a5; threads[n].regs.r6 = args->a6; threads[n].regs.r7 = args->a7; /* Save Hypervisor Client ID */ threads[n].hyp_clnt_id = args->a7; thread_resume(&threads[n].regs); }
/* * Thread 2 - Priority = 101 */ static void thread_2(void) { int error; printf("thread_2: starting\n"); /* * 1) Lock mutex A */ printf("thread_2: 1) lock A\n"); error = mutex_lock(&mtx_A); if (error) printf("error=%d\n", error); /* * Switch to thread 1 */ thread_resume(th_1); printf("thread_2: running\n"); /* * 4) Lock mutex B * * Deadlock occurs here! */ printf("thread_2: 4) lock B\n"); error = mutex_lock(&mtx_B); if (error) printf("error=%d\n", error); if (error == EDEADLK) printf("**** DEADLOCK!! ****\n"); printf("thread_2: exit\n"); thread_terminate(th_2); }
void gdb_pthread_kill(pthread_t pthread) { mach_port_t mthread; kern_return_t kret; int ret; mthread = pthread_mach_thread_np(pthread); kret = thread_suspend(mthread); MACH_CHECK_ERROR(kret); ret = pthread_cancel(pthread); if (ret != 0) { /* in case a macro has re-defined this function: */ #undef strerror warning("Unable to cancel thread: %s (%d)", strerror(errno), errno); thread_terminate(mthread); } kret = thread_abort (mthread); MACH_CHECK_ERROR (kret); kret = thread_resume (mthread); MACH_CHECK_ERROR (kret); ret = pthread_join (pthread, NULL); if (ret != 0) { warning ("Unable to join to canceled thread: %s (%d)", strerror (errno), errno); } }
/* LOCKING: assumes the GC lock is held */ int sgen_thread_handshake (BOOL suspend) { SgenThreadInfo *cur_thread = mono_thread_info_current (); kern_return_t ret; int count = 0; cur_thread->client_info.suspend_done = TRUE; FOREACH_THREAD (info) { if (info == cur_thread || sgen_thread_pool_is_thread_pool_thread (mono_thread_info_get_tid (info))) continue; info->client_info.suspend_done = FALSE; if (info->client_info.gc_disabled) continue; if (suspend) { if (!sgen_suspend_thread (info)) continue; } else { do { ret = thread_resume (info->client_info.info.native_handle); } while (ret == KERN_ABORTED); if (ret != KERN_SUCCESS) continue; } count ++; } FOREACH_THREAD_END return count; }
int __cdecl ThreadPThread__SuspendThread (m3_pthread_t mt) { kern_return_t status = { 0 }; mach_port_t mach_thread = PTHREAD_FROM_M3(mt); status = thread_suspend(mach_thread); if (status != KERN_SUCCESS) { fprintf(stderr, "thread_suspend returned %d instead of %d\n", (int)status, (int)KERN_SUCCESS); return 0; } status = thread_abort_safely(mach_thread); if (status != KERN_SUCCESS) { fprintf(stderr, "thread_abort_safely returned %d instead of %d\n", (int)status, (int)KERN_SUCCESS); status = thread_resume(mach_thread); if (status != KERN_SUCCESS) { fprintf(stderr, "thread_resume returned %d instead of %d\n", (int)status, (int)KERN_SUCCESS); abort(); } return 0; } return 1; }
void mono_threads_core_abort_syscall (MonoThreadInfo *info) { kern_return_t ret; do { ret = thread_suspend (info->native_handle); } while (ret == KERN_ABORTED); if (ret != KERN_SUCCESS) return; do { ret = thread_abort_safely (info->native_handle); } while (ret == KERN_ABORTED); /* * We are doing thread_abort when thread_abort_safely returns KERN_SUCCESS because * for some reason accept is not interrupted by thread_abort_safely. * The risk of aborting non-atomic operations while calling thread_abort should not * exist because by the time thread_abort_safely returns KERN_SUCCESS the target * thread should have return from the kernel and should be waiting for thread_resume * to resume the user code. */ if (ret == KERN_SUCCESS) ret = thread_abort (info->native_handle); do { ret = thread_resume (info->native_handle); } while (ret == KERN_ABORTED); g_assert (ret == KERN_SUCCESS); }
int download_ex(u32 data_length)//Big image and parallel transfer. { thread_t *thr; init_engine_context(&ctx); init_sto_info(&sto_info, FALSE); //no checksum enabled. sto_info.to_write_data_len = data_length; thr = thread_create("fastboot", write_storage_proc, 0, DEFAULT_PRIORITY, 16*1024); if (!thr) { return -1; } thread_resume(thr); TIME_START; read_usb_proc(&data_length); //wait for write thread end. event_wait(&ctx.thr_end_ev); destroy_engine(&ctx); if(ctx.b_error) { fastboot_fail_wrapper("\n@DOWNLOAD ERROR@\nPlease re-plug your USB cable\n"); fastboot_state = STATE_ERROR; }else { fastboot_okay(""); } return 0; }
int __cdecl ThreadPThread__RestartThread (m3_pthread_t mt) { mach_port_t mach_thread = PTHREAD_FROM_M3(mt); return thread_resume(mach_thread) == KERN_SUCCESS; }
int sleep_test(void) { int i; for (i=0; i < 16; i++) thread_resume(thread_create("sleeper", &sleep_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); return 0; }
static void start_app(const struct app_descriptor *app) { uint32_t stack_size = (app->flags & APP_FLAG_CUSTOM_STACK_SIZE) ? app->stack_size : DEFAULT_STACK_SIZE; printf("starting app %s\n", app->name); thread_resume(thread_create(app->name, &app_thread_entry, (void *)app, DEFAULT_PRIORITY, stack_size)); }
/* LOCKING: assumes the GC lock is held */ int mono_sgen_thread_handshake (int signum) { SgenThreadInfo *cur_thread = mono_sgen_thread_info_current (); kern_return_t ret; SgenThreadInfo *info; int count = 0; FOREACH_THREAD (info) { if (info == cur_thread || mono_sgen_is_worker_thread (info->id)) continue; if (signum == suspend_signal_num) { if (!mono_sgen_suspend_thread (info)) continue; } else { ret = thread_resume (info->mach_port); if (ret != KERN_SUCCESS) continue; } count ++; } END_FOREACH_THREAD return count; }
static int getThreadContext(J9ThreadWalkState *state) { int ret = 0; char buffer[1]; PlatformWalkData *data = (PlatformWalkData *)state->platform_data; thread_port_t thread = data->threadList[data->threadIndex]; /* Create a pipe to allow the resumed thread to report it has completed * sending its context info. */ ret = pipe(pipeFileDescriptor); if (0 == ret) { ret = pthread_kill(pthread_from_mach_thread_np(thread), SUSPEND_SIG); } if (0 == ret) { /* Resume the thread, with the signal pending. */ if (KERN_SUCCESS != thread_resume(thread)) { ret = -1; } } if (0 == ret) { /* Wait for the signal handler to complete. */ if (0 == read(pipeFileDescriptor[0], buffer, 1)) { ret = -1; } } return ret; }
static void bootstrap_exec_compat(void *e) { task_t bootstrap_task; thread_t bootstrap_thread; /* * Create the bootstrap task. */ (void) task_create(TASK_NULL, FALSE, &bootstrap_task); (void) thread_create(bootstrap_task, &bootstrap_thread); /* * Insert send rights to the master host and device ports. */ boot_host_port = task_insert_send_right(bootstrap_task, ipc_port_make_send(realhost.host_priv_self)); boot_device_port = task_insert_send_right(bootstrap_task, ipc_port_make_send(master_device_port)); /* * Start the bootstrap thread. */ bootstrap_thread->saved.other = e; thread_start(bootstrap_thread, user_bootstrap_compat); (void) thread_resume(bootstrap_thread); }
void o_thrResume(o_thr_t thr) { mach_port_t mthread; mthread = pthread_mach_thread_np(thr); thread_resume(mthread); }
static void atomic_test(void) { atomic = 0; atomic_count = 8; printf("testing atomic routines\n"); thread_t *threads[8]; threads[0] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[1] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[2] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[3] = thread_create("atomic tester 1", &atomic_tester, (void *)1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[4] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[5] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[6] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE); threads[7] = thread_create("atomic tester 2", &atomic_tester, (void *)-1, LOW_PRIORITY, DEFAULT_STACK_SIZE); /* start all the threads */ for (uint i = 0; i < countof(threads); i++) thread_resume(threads[i]); /* wait for them to all stop */ for (uint i = 0; i < countof(threads); i++) { thread_join(threads[i], NULL, INFINITE_TIME); } printf("atomic count == %d (should be zero)\n", atomic); }
void event_test(void) { thread_t *threads[5]; static event_t ievent = EVENT_INITIAL_VALUE(ievent, true, 0x1234); printf("preinitialized event:\n"); hexdump(&ievent, sizeof(ievent)); printf("event tests starting\n"); /* make sure signalling the event wakes up all the threads */ event_init(&e, false, 0); threads[0] = thread_create("event signaller", &event_signaller, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[1] = thread_create("event waiter 0", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[2] = thread_create("event waiter 1", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[3] = thread_create("event waiter 2", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[4] = thread_create("event waiter 3", &event_waiter, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); for (uint i = 0; i < countof(threads); i++) thread_resume(threads[i]); thread_sleep(2000); printf("destroying event\n"); event_destroy(&e); for (uint i = 0; i < countof(threads); i++) thread_join(threads[i], NULL, INFINITE_TIME); /* make sure signalling the event wakes up precisely one thread */ event_init(&e, false, EVENT_FLAG_AUTOUNSIGNAL); threads[0] = thread_create("event signaller", &event_signaller, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[1] = thread_create("event waiter 0", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[2] = thread_create("event waiter 1", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[3] = thread_create("event waiter 2", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); threads[4] = thread_create("event waiter 3", &event_waiter, (void *)99, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); for (uint i = 0; i < countof(threads); i++) thread_resume(threads[i]); thread_sleep(2000); event_destroy(&e); for (uint i = 0; i < countof(threads); i++) thread_join(threads[i], NULL, INFINITE_TIME); printf("event tests done\n"); }
static int join_tester_server(void *arg) { int ret; status_t err; thread_t *t; printf("\ttesting thread_join/thread_detach\n"); printf("\tcreating and waiting on thread to exit with thread_join\n"); t = thread_create("join tester", &join_tester, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(t); ret = 99; printf("\tthread magic is 0x%x (should be 0x%x)\n", t->magic, THREAD_MAGIC); err = thread_join(t, &ret, INFINITE_TIME); printf("\tthread_join returns err %d, retval %d\n", err, ret); printf("\tthread magic is 0x%x (should be 0)\n", t->magic); printf("\tcreating and waiting on thread to exit with thread_join, after thread has exited\n"); t = thread_create("join tester", &join_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(t); thread_sleep(1000); // wait until thread is already dead ret = 99; printf("\tthread magic is 0x%x (should be 0x%x)\n", t->magic, THREAD_MAGIC); err = thread_join(t, &ret, INFINITE_TIME); printf("\tthread_join returns err %d, retval %d\n", err, ret); printf("\tthread magic is 0x%x (should be 0)\n", t->magic); printf("\tcreating a thread, detaching it, let it exit on its own\n"); t = thread_create("join tester", &join_tester, (void *)3, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_detach(t); thread_resume(t); thread_sleep(1000); // wait until the thread should be dead printf("\tthread magic is 0x%x (should be 0)\n", t->magic); printf("\tcreating a thread, detaching it after it should be dead\n"); t = thread_create("join tester", &join_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_resume(t); thread_sleep(1000); // wait until thread is already dead printf("\tthread magic is 0x%x (should be 0x%x)\n", t->magic, THREAD_MAGIC); thread_detach(t); printf("\tthread magic is 0x%x\n", t->magic); printf("\texiting join tester server\n"); return 55; }
void context_switch_test(void) { event_init(&context_switch_event, false, 0); event_init(&context_switch_done_event, false, 0); thread_resume(thread_create("context switch idle", &context_switch_tester, (void *)1, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_sleep(100); event_signal(&context_switch_event, true); event_wait(&context_switch_done_event); thread_sleep(100); event_unsignal(&context_switch_event); event_unsignal(&context_switch_done_event); thread_resume(thread_create("context switch 2a", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create("context switch 2b", &context_switch_tester, (void *)2, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_sleep(100); event_signal(&context_switch_event, true); event_wait(&context_switch_done_event); thread_sleep(100); event_unsignal(&context_switch_event); event_unsignal(&context_switch_done_event); thread_resume(thread_create("context switch 4a", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create("context switch 4b", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create("context switch 4c", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_resume(thread_create("context switch 4d", &context_switch_tester, (void *)4, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_sleep(100); event_signal(&context_switch_event, true); event_wait(&context_switch_done_event); thread_sleep(100); }
int mutex_test(void) { mutex_init(&m); int i; for (i = 0; i < 5; i++) thread_resume(thread_create ("mutex tester", &mutex_thread, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_sleep(1000); while (mutex_thread_count > 0) thread_yield(); printf("done with simple mutex tests\n"); printf("testing mutex timeout\n"); mutex_t timeout_mutex; mutex_init(&timeout_mutex); mutex_acquire(&timeout_mutex); for (i = 0; i < 2; i++) thread_resume(thread_create ("mutex timeout tester", &mutex_timeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); for (i = 0; i < 2; i++) thread_resume(thread_create ("mutex timeout tester", &mutex_zerotimeout_thread, (void *)&timeout_mutex, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE)); thread_sleep(5000); mutex_release(&timeout_mutex); printf("done with mutex tests\n"); mutex_destroy(&timeout_mutex); return 0; }
gboolean sgen_resume_thread (SgenThreadInfo *info) { kern_return_t ret; do { ret = thread_resume (info->client_info.info.native_handle); } while (ret == KERN_ABORTED); return ret == KERN_SUCCESS; }
void lk_main(void) { inc_critical_section(); // get us into some sort of thread context thread_init_early(); // early arch stuff lk_init_level(LK_INIT_LEVEL_ARCH_EARLY - 1); arch_early_init(); // do any super early platform initialization lk_init_level(LK_INIT_LEVEL_PLATFORM_EARLY - 1); platform_early_init(); // do any super early target initialization lk_init_level(LK_INIT_LEVEL_TARGET_EARLY - 1); target_early_init(); dprintf(INFO, "welcome to lk\n\n"); #if WITH_PLATFORM_MSM_SHARED bs_set_timestamp(BS_BL_START); #endif // deal with any static constructors dprintf(SPEW, "calling constructors\n"); call_constructors(); // bring up the kernel heap dprintf(SPEW, "initializing heap\n"); lk_init_level(LK_INIT_LEVEL_HEAP - 1); heap_init(); #if WITH_PLATFORM_MSM_SHARED __stack_chk_guard_setup(); #endif // initialize the kernel lk_init_level(LK_INIT_LEVEL_KERNEL - 1); kernel_init(); lk_init_level(LK_INIT_LEVEL_THREADING - 1); #if (!ENABLE_NANDWRITE) // create a thread to complete system initialization dprintf(SPEW, "creating bootstrap completion thread\n"); thread_t *t = thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE); thread_detach(t); thread_resume(t); // become the idle thread and enable interrupts to start the scheduler thread_become_idle(); #else bootstrap_nandwrite(); #endif }