END_TEST /* \begin{test}{SIGRAPH0401} \TestDescription{Schedule inheritance graph: mutex release test} \TestImplementationProcess{ Thread 3 (main thread) releases mutex1, effective priority of main thread should be 7. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(SIGRAPH0401) { L4_MsgTag_t tag; setup_graph(); L4_Receive(main_thread); tag = L4_Make_MsgTag(0x3, 0); L4_Set_MsgTag(tag); L4_Send(main_thread); L4_Receive(main_thread); L4_LoadMR(0, 0); L4_Send(main_thread); measure_effective_prio(7); delete_all(); }
/* * The Philosopher thread tries to take the 2 chopsticks closest to him * (according to its number and the number of each chopstick) in order to eat. */ void philosopher(int argc, char **argv) { int left, right, first, second, mynum = 0; L4_Word_t me = L4_Myself().raw; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { mynum = atoi(argv[0]); } else { printf("(Philosopher 0x%lx) Error: Argument(s) missing!\n", me); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(dp_main); } // Have to take chopsticks according to "my number" left = mynum; if (chopstick[mynum + 1]) { right = mynum + 1; } else { right = 0; } // This should allow to avoid deadlock when trying to grab the chopsticks. first = left < right ? left : right; second = first == left ? right : left; //printf("Philosopher %d: %lx, managed by %lx\n", mynum, me, dp_main.raw); //printf("Philosopher %d: chopsticks %d and %d\n", mynum, left, right); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); while (meal_served == 0) ; okl4_libmutex_count_lock(chopstick[first]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, first, chopstick[first]); okl4_libmutex_count_lock(chopstick[second]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, second, chopstick[second]); //printf("Philosopher %d/%lx is eating\n", mynum, me); okl4_libmutex_count_unlock(chopstick[second]); okl4_libmutex_count_unlock(chopstick[first]); //printf("Philosopher %d: %lx/%lx finished eating\n", mynum, me, dp_main.raw); L4_Set_Label(&tag, 0xfed); L4_Set_MsgTag(tag); L4_Send(dp_main); L4_Send(L4_Myself()); }
static void ping_thread_simulated (void) { volatile L4_Word_t x; /* Wait for pong thread to come up */ L4_Msg_t msg; L4_MsgTag_t tag; for (int i=0; i < num_iterations; i++) { L4_Fpage_t ppage = L4_Fpage((L4_Word_t)&fault_area[i*1024], 4096); L4_Set_Rights(&ppage, L4_FullyAccessible); /* accept fpages */ L4_Accept(L4_UntypedWordsAcceptor); /* send it to our pager */ L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) ppage.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, L4_PAGEFAULT); L4_MsgLoad(&msg); /* make the call */ tag = L4_Call(pager_tid); x = fault_area[i*1024]; } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
void thread_start(L4_ThreadId_t tid, L4_Word_t ip, char *cmdline, int npaths, char **paths, HpfCapability *caps) { list_t *li; L4_Word_t sp; mutex_lock(&thrlock); li = list_find(thread_list, &tid, sizeof(L4_ThreadId_t)); if (!li) { mutex_unlock(&thrlock); return; } sp = STACK_BASE - (THREAD_TYPE(li->data)->index * STACK_SIZE); sp -= thread_prepare_stack(THREAD_TYPE(li->data)->space, sp, cmdline, npaths, paths, caps); /* send "start" message */ L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_Set_Propagation(&msg.tag); L4_Set_VirtualSender(THREAD_TYPE(li->data)->space->pager); L4_MsgLoad(&msg); L4_Send(tid); mutex_unlock(&thrlock); }
static void zone0150_thread1_routine(void) { L4_MsgTag_t result; L4_ThreadId_t thread0_tid; okl4_init_thread(); while (zone0150_children_can_run == 0) { /* spin */ } thread0_tid.raw = thread0_cap.raw; result = L4_Receive(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Receive() failed."); result = L4_Send(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Send() failed."); result = L4_Call(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Call() failed."); zone0150_child_thread_run++; L4_WaitForever(); }
static void waiting_notify_thread(void *arg) { L4_Word_t notifybits; L4_MsgTag_t tag; L4_Word_t mask; tag = L4_Receive(main_tid); notifybits = L4_Label(tag); L4_Set_NotifyMask(notifybits); L4_Accept(L4_NotifyMsgAcceptor); L4_LoadMR(0, 0); L4_Send(main_tid); tag = L4_WaitNotify(&mask); if (L4_IpcFailed(tag)) { FAILED(); return; } L4_Set_Label(&tag, notifybits); L4_Set_MsgTag(tag); L4_Call(main_tid); while (1) { } }
static void ipc_test_fault(struct bench_test *test, int args[]) { /* Send empty message to notify pager to startup both threads */ L4_LoadMR (0, 0); L4_Send (pager_tid); L4_Receive (pager_tid); }
static void ipc_irq_test(struct new_bench_test *test, int args[], volatile uint64_t *count) { results = count; /* Send empty message to notify pager to startup test thread */ L4_LoadMR (0, 0); L4_Send (handler_tid); L4_Receive (handler_tid); }
static void time_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { printf("Got time packet?!\n"); memcpy(&time_of_day, p->payload, sizeof(time_of_day)); printf("Sending blah\n"); L4_Send((L4_ThreadId_t) (uintptr_t) arg); }
static void other_sending_thread(void) { L4_LoadMR(0, 0); L4_Send(prio5_thread); L4_WaitForever(); while(1) ; }
/* * The lowest priority thread acquires a mutex at initialisation time, releases * it the next it is run in scenario 1. It increments a counter on success. * It sends IPC to medium thread in scenario 2. It increments a counter on success. */ void mixed_pi_low(int argc, char **argv) { L4_ThreadId_t tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium3_prio_thread)) ; tid = medium3_prio_thread; //printf("Low thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initalisation if (scenario1) { //printf("Low thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_l++; } //printf("(Initialisation) Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); L4_Send(tid); //printf("(Initialisation) Low thread %lx/%lx sent to Medium thread\n", me, pi_main.raw); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { okl4_libmutex_count_unlock(resource_mutex); } else if (scenario2) { cnt_l++; //printf("Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcFailed(tag)) cnt_l--; } L4_Yield(); tid = medium2_prio_thread; } }
static void send_startup_ipc (L4_ThreadId_t tid, L4_Word_t ip, L4_Word_t sp) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_MsgLoad(&msg); L4_Send(tid); }
static void pager (void) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_Send(master_tid); for (;;) { tag = L4_Wait(&tid); for (;;) { L4_Word_t faddr, fip; L4_MsgStore(tag, &msg); if (L4_UntypedWords (tag) != 2 || !L4_IpcSucceeded (tag)) { printf ("Malformed pagefault IPC from %p (tag=%p)\n", (void *) tid.raw, (void *) tag.raw); L4_KDB_Enter ("malformed pf"); break; } faddr = L4_MsgWord(&msg, 0); fip = L4_MsgWord (&msg, 1); L4_MsgClear(&msg); { L4_MapItem_t map; L4_SpaceId_t space; L4_Word_t seg, offset, cache, rwx, size; int r; seg = get_seg(KBENCH_SPACE, faddr, &offset, &cache, &rwx); assert(seg != ~0UL); size = L4_GetMinPageBits(); faddr &= ~((1ul << size)-1); offset &= ~((1ul << size)-1); space.raw = __L4_TCR_SenderSpace(); L4_MapItem_Map(&map, seg, offset, faddr, size, cache, rwx); r = L4_ProcessMapItem(space, map); assert(r == 1); } L4_MsgLoad(&msg); // tag = L4_ReplyWait (tid, &tid); tag = L4_MsgTag(); L4_Set_SendBlock(&tag); L4_Set_ReceiveBlock(&tag); tag = L4_Ipc(tid, L4_anythread, tag, &tid); } } }
static void mutex0705_high_thread(void) { /* Acquire the mutex. */ L4_Lock(m); L4_Unlock(m); /* Inform master thread we have the lock. */ L4_Send(main_thread); L4_WaitForever(); }
static void measure_effective_prio_thread(void) { L4_MsgTag_t tag; while (1) { tag = L4_Make_MsgTag(0x2, 0); L4_Set_MsgTag(tag); L4_Send(setup_thread); } }
/* * The medium thread tries to acquire a mutex, releases it once acquired and then * receives from highest priority thread in scenario 1. It increments 2 counters * on success, one for each operation. * It acquires a mutex at initialisation time and waits for any thread before * releasing the mutex in scenario 2. It increments 2 counters on success, * one for each operation. */ void mixed_pi_medium(int argc, char **argv) { L4_ThreadId_t any_thread, tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium1_prio_thread)) ; tid = medium1_prio_thread; //printf("Middle thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initialisation if (scenario2) { //printf("Middle thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_m1++; } //printf("(Initialisation) Medium thread %lx/%lx blocks open receiving\n", me, pi_main.raw); L4_Wait(&any_thread); //printf("(Initialisation) Medium thread %lx/%lx received from 0x%lx\n", me, pi_main.raw, any_thread.raw); L4_LoadMR(0, 0); L4_Send(tid); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (scenario1) { okl4_libmutex_count_lock(resource_mutex); cnt_m1++; wait_a_bit(counter); } else if (scenario2) { //printf("Middle thread %lx/%lx blocks open receiving\n", me, pi_main.raw); tag = L4_Wait(&any_thread); if (L4_IpcSucceeded(tag) && (any_thread.raw == low_prio_thread.raw)) cnt_m2++; wait_a_bit(counter); } okl4_libmutex_count_unlock(resource_mutex); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { cnt_m2++; tag = L4_Receive(high_prio_thread); if (L4_IpcFailed(tag)) cnt_m2--; } L4_Yield(); tid = pi_main; } }
END_TEST static void mutex0405_child_thread(void) { L4_Word_t res; res = L4_Lock(m); fail_unless(res == 1, "L4_Lock() failed"); L4_Send(main_thread); L4_WaitForever(); }
static void ipc_test(struct bench_test *test, int args[]) { L4_ThreadId_t tid; /* Send "begin" message to notify pager to startup both threads */ L4_MsgTag_t tag = L4_Niltag; L4_Set_Label(&tag, START_LABEL); L4_Set_MsgTag(tag); L4_Send(pager_tid); L4_Wait(&tid); }
/* * Intermediate thread 1 has priority in between highest and medium thread. * Intermediate thread 2 has priority in between medium and lowest thread. * They set their flag each time they run during the PI test. */ void mixed_pi_intermediate(int argc, char **argv) { int num = 0; L4_ThreadId_t any_thread; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { num = atoi(argv[0]); } else { printf("(%s Intermediate Thread) Error: Argument(s) missing!\n", test_name); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(pi_main); } // Initialisation if (num == 1) { L4_Wait(&any_thread); L4_LoadMR(0, 0); L4_Send(pi_main); } else if (num == 2) { L4_Wait(&any_thread); while (L4_IsNilThread(medium2_prio_thread)) ; L4_LoadMR(0, 0); L4_Send(medium2_prio_thread); } L4_Yield(); // Thread is now ready to set the flag the next time it is run. while(1) { if (num == 1) { flag1 = 1; } else if (num == 2) { flag3 = 1; } L4_LoadMR(0, 0); L4_Send(high_prio_thread); } }
static void sending_thread(void) { L4_Word_t result; L4_MsgTag_t tag; if (L4_UserDefinedHandle()) { result = L4_Lock(mutex2); fail_unless(result == 1, "L4_Lock() failed"); } L4_LoadMR(0, 0); L4_Send(main_thread); tag = L4_Receive(setup_thread); if (L4_Label(tag) == 0x3) { L4_Unlock(mutex2); L4_LoadMR(0, 0); L4_Send(main_thread); } L4_WaitForever(); while(1) ; }
void sos_debug_flush(void) { // Send a syscall to the root thread, which unmaps the user address space. L4_Msg_t msg; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, MAKETAG_SYSLAB(SOS_SYSCALL_UNMAP_USER_ADDRESS_SPACE)); L4_MsgLoad(&msg); L4_MsgTag_t tag = L4_Send(sSystemId); if (L4_IpcFailed(tag)) { printf("Error sending unmap address space syscall."); } }
int __USER_TEXT L4_Map(L4_ThreadId_t where, memptr_t base, size_t size) { L4_Msg_t msg; L4_Word_t page[2] = { (base & 0xFFFFFFC0) | 0xA, size & 0xFFFFFFC0 }; L4_MsgPut(&msg, 0, 0, NULL, 2, page); L4_MsgLoad(&msg); L4_Send(where); return 0; }
static void pong_thread_ovh (void) { L4_Word_t untyped = 0; for (int i = 0; i < num_iterations; i++) { pingpong_ipc_ovh(ping_tid, untyped); } L4_Send(ping_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
static void mutex0403_worker_thread(void) { int i; for (i = 0; i < 100; i++) { L4_Lock(m); mutex0403_lock_holder = L4_Myself(); L4_Yield(); fail_unless(mutex0403_lock_holder.raw == L4_Myself().raw, "Protected counter changed while we held the lock."); L4_Unlock(m); L4_Yield(); } L4_Send(main_thread); L4_WaitForever(); }
static void ping_thread_async_ovh (void) { for (int i=0; i < num_iterations; i++) { ; } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
static void sos_debug_flush(void) { L4_Msg_t msg; L4_MsgTag_t tag; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, TAG_SETSYSCALL(SOS_UNMAP_ALL)); L4_MsgLoad(&msg); tag = L4_Send(L4_Pager()); if (L4_IpcFailed(tag)) { L4_Word_t err = L4_ErrorCode(); printf("sos_debug_flush failed (error: %lx)\n", err); } }
static void __USER_TEXT start_thread(L4_ThreadId_t t, L4_Word_t ip, L4_Word_t sp, L4_Word_t stack_size) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_MsgAppendWord(&msg, stack_size); L4_MsgAppendWord(&msg, 0); L4_MsgAppendWord(&msg, 0); L4_MsgLoad(&msg); L4_Send(t); }
static void synch_pong (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; VERBOSE_HIGH("Pong running\n"); while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; L4_LoadMR (0, 0); L4_Send(caller); } L4_Call(L4_Myself()); }
static void ping_thread_ovh (void) { /* Wait for pong thread to come up */ L4_Receive (pong_tid); for (int i=0; i < num_iterations; i++) { pingpong_ipc_ovh (pong_tid, num_mrs); } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
size_t sos_write(const void *vData, long int position, size_t count, void *handle) { size_t i; const char *realdata = vData; // send over serial for (i = 0; i < count; i++) L4_KDB_PrintChar(realdata[i]); // send to syscall in chunks of 5 words // so that we use all 6 ARM registers //for (i = position; i < count;) // well looks like this is not what position is for. for (i = 0; i < count;) // i incremented in the loop { L4_Msg_t msg; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, MAKETAG_SYSLAB(SOS_SYSCALL_SERIAL_SEND)); // add the words to the message for (int j = 0; j < WORDS_SENT_PER_IPC && i < count; j++) { // initialize to 0 so we send 0-chars if the message // is not word-padded L4_Word_t word = 0; // add bytes one by one char* writeTo = (char*) &word; for (int k = 0; k < sizeof(L4_Word_t) && i < count; k++) { *(writeTo++) = realdata[i++]; } L4_MsgAppendWord(&msg, word); } L4_MsgLoad(&msg); L4_MsgTag_t tag = L4_Send(sSystemId); if (L4_IpcFailed(tag)) { // FIXME: actually useful debug message L4_KDB_PrintChar('E'); L4_KDB_PrintChar('S'); L4_KDB_PrintChar('M'); break; } } return i; }