static void ipc_irq_teardown(struct new_bench_test *test, int args[]) { int r = 0; L4_Word_t control; //L4_DeassociateInterrupt(thread_tid); control = 0 | (1 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot unregister interrupt\n"); } #if SPINNER /* Delete spinner */ r = L4_ThreadControl (spinner_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); #endif /* Delete handler thread */ r = L4_ThreadControl (handler_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); /* Delete pager */ r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); }
static void ipc_teardown(struct bench_test *test, int args[]) { int r = 0; if (!fault_test) { /* Kill ping thread */ r = L4_ThreadControl (ping_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); if (r == 0) printf("thread control Error: %lx\n", L4_ErrorCode()); assert (r == 1); } if (!pagertimer) { /* Kill pong thread */ r = L4_ThreadControl (pong_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); } /* Delete ping space */ if (ping_space.raw != L4_nilspace.raw) { r = L4_SpaceControl(ping_space, L4_SpaceCtrl_delete, KBENCH_CLIST, L4_Nilpage, 0, NULL); assert (r == 1); okl4_kspaceid_free(spaceid_pool, ping_space); } /* Delete pong space */ if (pong_space.raw != L4_nilspace.raw) { r = L4_SpaceControl(pong_space, L4_SpaceCtrl_delete, KBENCH_CLIST, L4_Nilpage, 0, NULL); assert (r == 1); okl4_kspaceid_free(spaceid_pool, pong_space); } }
L4_ThreadId_t thread_new(AddrSpace_t *space) { assert (space != NULL); L4_Word_t tno; L4_ThreadId_t tid; L4_ThreadId_t space_spec; L4_Word_t utcb_location; slab_t *sb; list_t *li; thread_t *this; mutex_lock(&thrlock); tno = threadno_find_free(bitmap, MAX_TASKS); if (!tno) { mutex_unlock(&thrlock); return L4_nilthread; } tid = L4_GlobalId(tno, 1); utcb_location = UTCB_AREA_LOCATION; space_spec = space->tid; tno = threadno_find_free(space->threads, MAX_THREADS_PER_TASK); if (!tno) { mutex_unlock(&thrlock); return L4_nilthread; } utcb_location += tno * UTCB_SIZE; sb = slab_alloc(&thrpool); if (!sb) { mutex_unlock(&thrlock); return L4_nilthread; } if (FALSE == (L4_ThreadControl(tid, space_spec, tid, space->pager, (void *) utcb_location))) { slab_free(&thrpool, sb); mutex_unlock(&thrlock); return L4_nilthread; } li = LIST_TYPE(sb->data); this = (thread_t *) li->data; list_push(&thread_list, li); this->tid = tid; this->space = space; this->index = tno; this->creation = L4_SystemClock(); threadno_alloc(bitmap, L4_ThreadNo(tid)); threadno_alloc(space->threads, tno); mutex_unlock(&thrlock); return tid; }
void __USER_TEXT __root_thread(kip_t *kip_ptr, utcb_t *utcb_ptr) { l4_thread_t myself = utcb_ptr->t_globalid; char *free_mem = (char *) get_free_base(kip_ptr); uint32_t msg[8] = { 0 }; /* Allocate utcbs and stacks in Free memory region */ char *utcbs[2] = { free_mem, free_mem + UTCB_SIZE }; char *stacks[2] = { free_mem + 2 * UTCB_SIZE, free_mem + 2 * UTCB_SIZE + STACK_SIZE }; threads[PING_THREAD] = L4_THREAD_NUM(PING_THREAD, kip_ptr->thread_info.s.user_base); /* Ping */ threads[PONG_THREAD] = L4_THREAD_NUM(PONG_THREAD, kip_ptr->thread_info.s.user_base); /* Pong */ L4_ThreadControl(threads[PING_THREAD], myself, 0, myself, utcbs[PING_THREAD]); L4_ThreadControl(threads[PONG_THREAD], myself, 0, myself, utcbs[PONG_THREAD]); L4_Map(myself, (memptr_t) stacks[PING_THREAD], STACK_SIZE); L4_Map(myself, (memptr_t) stacks[PONG_THREAD], STACK_SIZE); L4_Start(threads[PING_THREAD], ping_thread, stacks[PING_THREAD] + STACK_SIZE); L4_Start(threads[PONG_THREAD], pong_thread, stacks[PONG_THREAD] + STACK_SIZE); while (1) L4_Ipc(L4_NILTHREAD, L4_NILTHREAD, 0, msg); }
int thread_new ( struct thread * thread, L4_SpaceId_t space, L4_ThreadId_t scheduler, L4_ThreadId_t pager, L4_ThreadId_t exception ) { int rv; int fpu = 0; #if defined(ARCH_IA32) /* Always allocate FPU resources to every thread iguana creates on IA32 * (bug 2836) */ fpu = 0x80000001; #endif rv = L4_ThreadControl ( thread->id, space, scheduler, pager, exception, fpu, (void *)thread->utcb ); if (rv == 1) { L4_Word_t handle; L4_StoreMR(0, &handle); thread->handle.raw = handle; assert(hash_lookup(l4tid_to_thread, handle) == NULL); /* Guaranteed to work because hash_lookup was just performed */ hash_insert(l4tid_to_thread, handle, thread); L4_Set_Priority(thread->id, 100); } else { /* Initialise the handle to an invalid valid. */ thread->handle = L4_nilthread; } return rv; }
int thread_destroy(L4_ThreadId_t tid) { list_t *li; AddrSpace_t *as; L4_Word_t tno; mutex_lock(&thrlock); li = list_find(thread_list, &tid, sizeof(L4_ThreadId_t)); if (li == NULL) { mutex_unlock(&thrlock); return FALSE; } if (FALSE == L4_ThreadControl(tid, L4_nilthread, L4_nilthread, L4_nilthread, (void *) -1)) { mutex_unlock(&thrlock); return FALSE; } as = THREAD_TYPE(li->data)->space; tno = THREAD_TYPE(li->data)->index; list_remove(&thread_list, li); slab_free(&thrpool, SLAB_FROM_DATA(li)); threadno_free(bitmap, L4_ThreadNo(tid)); threadno_free(as->threads, tno); if (tid.raw == as->tid.raw) { for (li = thread_list; li; li = li->next) { if (THREAD_TYPE(li->data)->space == as) break; } if (li == NULL) { // task destroy notification should go here address_space_destroy(as); } else { as->tid = THREAD_TYPE(li->data)->tid; } } mutex_unlock(&thrlock); // thread destroy notification should go here return TRUE; }
static L4_ThreadId_t create_local_thread(char *desc, L4_KernelInterfacePage_t *kip, int idx, threadfunc_t func, L4_Word_t stack_size) { L4_Word_t utcb_size = L4_UtcbSize(kip); L4_Word_t my_utcb = L4_MyLocalId().raw; my_utcb = (my_utcb & ~(utcb_size - 1)); L4_ThreadId_t tid = L4_GlobalId(L4_ThreadNo(L4_Myself()) + idx, 1); L4_Word_t utcb_location = my_utcb + idx * utcb_size; if (FALSE == L4_ThreadControl(tid, L4_Myself(), L4_Myself(), L4_Pager(), (void *) utcb_location)) { printf("panic: can't execute %s: error code %d\n", desc, (int) L4_ErrorCode()); return L4_nilthread; } void *stack = kmalloc(stack_size); L4_Start_SpIp(tid, (L4_Word_t) stack + stack_size - 32, (L4_Word_t) func); return tid; }
void thread_delete(struct thread *thread) { struct pd *pd; #if defined(CONFIG_SESSION) struct session_p_node *sd; #endif pd = thread->owner; (void)L4_ThreadControl(thread->id, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, NULL); thread_free(thread->id); if ( #if defined(CONFIG_EAS) thread->eas == NULL && #endif thread->utcb != (void *)-1UL) { /* free local thread no. */ bfl_free(pd->local_threadno, ((uintptr_t)thread->utcb - L4_Address(pd->space.utcb_area)) >> L4_GetUtcbBits()); }
void task_destroy(AddrSpace_t *space) { list_t *li, *next; AddrSpace_t *as; L4_Word_t tno; L4_ThreadId_t tid; assert(space != NULL); mutex_lock(&thrlock); next = NULL; for (li = thread_list; li; li = next) { as = THREAD_TYPE(li->data)->space; next = li->next; if (as != space) continue; tno = THREAD_TYPE(li->data)->index; tid = THREAD_TYPE(li->data)->tid; /* hope this succeeds */ L4_ThreadControl(tid, L4_nilthread, L4_nilthread, L4_nilthread, (void *) -1); list_remove(&thread_list, li); slab_free(&thrpool, SLAB_FROM_DATA(li)); threadno_free(bitmap, L4_ThreadNo(tid)); // thread destroy notification should go here } address_space_destroy(space); mutex_unlock(&thrlock); // task destroy notification should go here return; }
static void ipc_setup(struct bench_test *test, int args[]) { static bool setup = false; int r; L4_Word_t utcb; fass = (test == &bench_ipc_fass); pagertimer = (test == &bench_ipc_pagemap); pagertimer_simulated = (test == &bench_ipc_pagemap_simulated); inter = (test == &bench_ipc_inter); fass_buffer = ((test == &bench_ipc_fass_buffer) || (test == &bench_ipc_fass_buffer_vspace)); fault_test = (test == &bench_ipc_page_faults); intra_open = (test == &bench_ipc_intra_open); intra_close = (test == &bench_ipc_intra_close); intra_rpc = (test == &bench_ipc_intra_rpc); intra_ovh = (test == &bench_ipc_intra_ovh); intra_async = (test == &bench_ipc_intra_async); intra_async_ovh = (test == &bench_ipc_intra_async_ovh); num_iterations = args[0]; num_mrs = args[1]; ping_space = pong_space = L4_nilspace; if (! setup) { /* Find smallest supported page size. There's better at least one * bit set. */ /* Size for one UTCB */ utcb_size = L4_GetUtcbSize(); /* We need a maximum of two threads per task */ #ifdef NO_UTCB_RELOCATE no_utcb_alloc = 1; utcb_area = L4_Nilpage; if (fass) { pong_utcb_area = L4_Nilpage; } #else no_utcb_alloc = 0; utcb_area = L4_Fpage((L4_Word_t) UTCB_ADDRESS, L4_GetUtcbAreaSize() + 1); if (fass) { pong_utcb_area = L4_Fpage ((L4_Word_t) UTCB_ADDRESS, L4_GetUtcbAreaSize() + 1); } #endif /* Create pager */ master_tid.raw = KBENCH_SERVER.raw; pager_tid.raw = KBENCH_SERVER.raw + 1; ping_tid.raw = KBENCH_SERVER.raw + 2; pong_tid.raw = KBENCH_SERVER.raw + 3; /* VU: calculate UTCB address -- this has to be revised */ /** @todo FIXME: Should put into arch subdir - changhua. */ #if defined(ARCH_ARM) L4_Word_t pager_utcb = (L4_Word_t) __L4_ARM_Utcb(); #elif defined(ARCH_IA32) L4_Word_t pager_utcb = (L4_Word_t) __L4_X86_Utcb(); #elif defined(ARCH_SH) L4_Word_t pager_utcb = (L4_Word_t) L4_GetUtcbBase(); #else #error "Please define arch get_Utcb()" #endif pager_utcb = no_utcb_alloc ? ~0UL : (pager_utcb & ~(utcb_size - 1)) + utcb_size; r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)pager_utcb); if (r == 0) printf("Thread create Error: %lx\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(pager_tid, "pager"); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); /* Find some area of memory to page to */ setup = true; } if (pagertimer) { /* Only create ping space and ping thread. */ r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert(r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert(r == 1); } else if (fault_test) { /* Only create pong space and pong thread. */ r = okl4_kspaceid_allocany(spaceid_pool, &pong_space); assert(r == OKL4_OK); r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert(r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &pong_th.raw); assert(r == 1); } else if (pagertimer_simulated || inter || fass || fass_buffer) { /* Create both ping, pong space, and create ping, pong thread in their own space */ L4_Word_t ctrl = 0; if (test == &bench_ipc_fass_buffer_vspace) { ctrl = (1 << 16); } r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, ctrl, NULL); if (r == 0) printf("Space control Error: 0x%lx\n", L4_ErrorCode()); assert( r == 1 ); r = okl4_kspaceid_allocany(spaceid_pool, &pong_space); assert(r == OKL4_OK); r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, (fass ? pong_utcb_area : utcb_area), ctrl, NULL); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : fass ? PONGUTCB(1) : UTCB(1); r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *)utcb); L4_StoreMR(0, &pong_th.raw); } else { /* Only Create ping space, but create both ping, pong thread in that space. */ r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert( r == 1 ); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(1); r = L4_ThreadControl(pong_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &pong_th.raw); assert( r == 1); } L4_KDB_SetThreadName(ping_tid, "ping"); if (test != &bench_ipc_pagemap) { L4_KDB_SetThreadName(pong_tid, "pong"); } }
static int CreateMaxThreads(void) { int i; int res = 1; // MIPS32 address space ends at 0x80000000 #if (defined(L4_ARCH_MIPS) && defined(L4_32BIT)) unsigned long utcb_base = 0x70000000; #else unsigned long utcb_base = 0xb0000000; #endif void * utcb = (void *)utcb_base; L4_Fpage_t utcb_area = L4_Fpage(utcb_base, 0x01000000); int max; L4_Word_t result; L4_SpaceId_t space; result = okl4_kspaceid_allocany(spaceid_pool, &space); fail_unless(result == OKL4_OK, "Failed to allocate any space id."); /* Create first thread (and address space) */ #ifdef NO_UTCB_RELOCATE utcb_area = L4_Nilpage; utcb = (void*)-1ul; #endif res = create_address_space(space, utcb_area); i = 3; // start creating threads after controlling space fail_unless(res == 1, "Failed to create controlling space\n"); /* create threads */ do { if (utcb) { utcb = (void *)(utcb_base + i * L4_GetUtcbSize()); } if (!isSystemThread(thread_offset(i))) { res = L4_ThreadControl(thread_offset(i), space, default_thread_handler, L4_nilthread, L4_nilthread, 0, (void *)utcb); } i++; } while (res == 1); max = i-3; /* delete threads */ for (; i >= 3; i--) { if (!isSystemThread(thread_offset(i))) { res = L4_ThreadControl(thread_offset(i), L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *)0); } } res = L4_SpaceControl(space, L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); okl4_kspaceid_free(spaceid_pool, space); return max; }
AddrSpace_t *task_new(L4_ThreadId_t pager) { L4_Word_t tno; L4_ThreadId_t tid; L4_ThreadId_t space_spec; L4_Word_t utcb_location; AddrSpace_t *space = NULL; slab_t *sb; list_t *li; thread_t *this; mutex_lock(&thrlock); tno = threadno_find_free(bitmap, MAX_TASKS); if (!tno) { mutex_unlock(&thrlock); return NULL; } tid = L4_GlobalId(tno, 1); utcb_location = UTCB_AREA_LOCATION; space_spec = tid; sb = slab_alloc(&thrpool); if (!sb) { mutex_unlock(&thrlock); return NULL; } if (FALSE == (L4_ThreadControl(tid, space_spec, L4_Myself(), L4_nilthread, (void *) utcb_location))) { slab_free(&thrpool, sb); mutex_unlock(&thrlock); return NULL; } space = address_space_new(tid, pager); if (!space) { L4_ThreadControl(tid, L4_nilthread, L4_nilthread, L4_nilthread, (void *) -1); slab_free(&thrpool, sb); mutex_unlock(&thrlock); return NULL; } else { /* set self space, and the specified pager * FIXME - using myself as the scheduler */ L4_ThreadControl(tid, tid, L4_Myself(), pager, (void *) -1); } li = LIST_TYPE(sb->data); this = (thread_t *) li->data; list_push(&thread_list, li); this->tid = tid; this->space = space; this->index = 0; this->creation = L4_SystemClock(); threadno_alloc(bitmap, L4_ThreadNo(tid)); threadno_alloc(space->threads, 0); mutex_unlock(&thrlock); return space; }
static void ipc_irq_setup(struct new_bench_test *test, int args[]) { int r; L4_Word_t utcb; L4_Word_t utcb_size; // L4_Word_t dummy; num_iterations = args[0]; handler_space = L4_nilspace; /* We need a maximum of two threads per task */ utcb_size = L4_GetUtcbSize(); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb =(L4_Word_t)L4_GetUtcbBase() + utcb_size; #endif /* Create pager */ master_tid = KBENCH_SERVER; pager_tid.raw = KBENCH_SERVER.raw + 1; handler_tid.raw = KBENCH_SERVER.raw + 2; interrupt = PMU_IRQ; #if SPINNER spinner_tid = L4_GlobalId (L4_ThreadNo (master_tid) + 3, 2); #endif r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); if (r == 0 && (L4_ErrorCode() == 2)) { r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert(r == 1); r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); assert(r == 1); } L4_KDB_SetThreadName(pager_tid, "pager"); //L4_Schedule(pager_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); L4_Set_Priority(pager_tid, 254); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); L4_Receive(pager_tid); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl(handler_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void *) utcb); assert(r == 1); L4_KDB_SetThreadName(handler_tid, "handler"); L4_Set_Priority(handler_tid, 100); // Startup notification, start handler thread //printf("register irq %ld, to %lx\n", interrupt, handler_tid.raw); L4_Word_t control = 0 | (0 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot register interrupt %lu\n", interrupt); } L4_Start_SpIp (handler_tid, (L4_Word_t) handler_stack + sizeof(handler_stack) - 32, START_ADDR(handler)); L4_Receive(handler_tid); #if SPINNER //Create spinner thread #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl (spinner_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void*) utcb); if (r == 0) printf("create spinner failed %ld\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(spinner_tid, "spinner"); //L4_Schedule(spinner_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); //Set priority to the lowest. L4_Set_Priority(spinner_tid, 1); L4_Start_SpIp (spinner_tid, (L4_Word_t) spinner_stack + sizeof(spinner_stack) - 32, START_ADDR (spinner)); #endif }