/** * FIXME: Sepecify real error conditions in failure cases - AGW. */ int pd_extension_activate(void) { void * my_utcb; L4_Word_t result; #if defined(ARCH_ARM) && ARCH_VER <= 5 my_utcb = (void *)-1UL; #else my_utcb = L4_GetUtcbBase(); #endif /* Lock the PD extension. */ okl4_libmutex_count_lock(&__pd_ext_lock); /* Check calling thread is not already in the extended PD. */ if (!L4_IsNilThread(__pd_ext_thread)) { return -1; } /* Update PD extension's state. */ __pd_ext_thread = L4_myselfconst; __pd_ext_return_utcb = my_utcb; /* Enable extended PD for calling thread. */ result = L4_SpaceSwitch(__pd_ext_thread, __pd_ext_space, __pd_ext_utcb); if (result == 0) { return -1; } return 0; /* Success. */ }
static void __exit lanaddress_exit_module( void ) { if( !L4_IsNilThread(lanaddress_tid) ) { L4VM_server_register_location( UUID_ILanAddress, L4_nilthread ); L4VM_thread_delete( lanaddress_tid ); lanaddress_tid = L4_nilthread; } }
/* * 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; } }
static void delete_all(void) { if (!L4_IsNilThread(prio7_thread)) { deleteThread(prio7_thread); } deleteThread(prio4_thread); if (!L4_IsNilThread(prio5_thread)) { deleteThread(prio5_thread); } deleteThread(prio2_thread); if (!L4_IsNilThread(prio1_thread)) { deleteThread(prio1_thread); } if (!L4_IsNilThread(prio6_thread)) { deleteThread(prio6_thread); } if (!L4_IsNilThread(prio6bis_thread)) { deleteThread(prio6bis_thread); } if (!L4_IsNilThread(prio8_thread)) { deleteThread(prio8_thread); } deleteThread(main_thread); deleteThread(measure_thread); }
/* * 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; } }
/* * 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); } }
int main( int argc, const char *argv[] ) { CORBA_Environment env = idl4_default_environment; L4_ThreadId_t tid; L4_Word_t space_id, ms, samples; if( !vmctrl_detect_l4() ) { printf( "Error: this utility must run on L4!\n" ); exit( 1 ); } if( argc != 4 ) usage( argv[0] ); space_id = atol( argv[1] ); ms = atol( argv[2] ); samples = atol( argv[3] ); printf( "Performing working set scan, space %lu, %lu ms time interval, " "and %lu samples\n", space_id, ms, samples ); vmctrl_ignore_signals(); tid = vmctrl_lookup_service( UUID_IVMControl ); if( L4_IsNilThread(tid) ) { printf( "Error: unable to locate the working set scanner.\n" ); exit( 1 ); } IVMControl_start_working_set_scan( tid, ms, samples, space_id, &env ); if( env._major != CORBA_NO_EXCEPTION ) { CORBA_exception_free( &env ); puts( "IPC failure to the resource monitor.\n" ); return 1; } return 0; }
/** * Write callback for the NFS write function in case we swap out. * Note that because we cannot write 4096 bytes in one chunk * we split the writes up in 512 byte chunks. So this function * is called multiple times by the NFS library. * * @param token pointer to the page queue item we are swapping out */ static void swap_write_callback(uintptr_t token, int status, fattr_t *attr) { page_queue_item* page = (page_queue_item*) token; page_table_entry* pte = pager_table_lookup(page->tid, page->virtual_address); file_table_entry* swap_fd = get_process(root_thread_g)->filetable[SWAP_FD]; switch (status) { case NFS_OK: { // update file attributes swap_fd->file->status.st_size = attr->size; swap_fd->file->status.st_atime = attr->atime.useconds / 1000; page->to_swap -= BATCH_SIZE; // swapping complete, can we now finally free the frame? if(page->to_swap == 0) { if(!is_referenced(page)) { dprintf(1, "page is swapped out\n"); if(!page->process_deleted) { frame_free(CLEAR_LOWER_BITS(pte->address)); mark_swapped(pte, page->swap_offset); // restart the thread who ran out of memory if(!L4_IsNilThread(page->initiator)) send_ipc_reply(page->initiator, L4_PAGEFAULT, 0); } else {} // page was killed, nothing to do TAILQ_REMOVE(&swapping_pages_head, page, entries); free(page); } else { dprintf(1, "page is swapped out but referenced in the mean time\n"); // page has been referenced inbetween swapping out // we need to restart the whole swap procedure TAILQ_REMOVE(&swapping_pages_head, page, entries); if(!L4_IsNilThread(page->initiator)) { send_ipc_reply(page->initiator, L4_PAGEFAULT, 0); } if(!page->process_deleted) { page->initiator = L4_nilthread; TAILQ_INSERT_TAIL(&active_pages_head, page, entries); } else { free(page); } } } } break; case NFSERR_NOSPC: dprintf(0, "System ran out of memory _and_ swap space (this is bad).\n"); TAILQ_REMOVE(&swapping_pages_head, page, entries); free(page); assert(FALSE); break; default: dprintf(0, "%s: Bad NFS status (%d) from callback.\n", __FUNCTION__, status); TAILQ_REMOVE(&swapping_pages_head, page, entries); free(page); assert(FALSE); // We could probably try to restart swapping here but since it failed before // we don't see much point in this. break; } }