static int processExpired(void *node, void *key) { utimer_entry_t *t = (utimer_entry_t *) node; L4_Word_t now = *((L4_Word_t *) key); if (t->fDiff <= (now - t->fStart)) { L4_Reply(t->fTid); return 1; } return 0; }
void session_add_buffer(struct session *session, void *call_buf, void *return_buf) { assert(session->call_buf == NULL); assert(session->return_buf == NULL); session->call_buf = call_buf; session->return_buf = return_buf; /* Now tell the server about this development */ { /* * Zero timeout ping -- FIXME: This should be handled by idl upcall * code, but do this later */ struct pd *other = session->server->owner; L4_Msg_t msg; uintptr_t *size; uintptr_t *addr; /* Now notify client and server prot domains */ size = cb_alloc(other->cba, sizeof(uintptr_t)); if (size == NULL) { ERROR_PRINT("Couldn't do upcall"); return; } *size = 3 * sizeof(uintptr_t); addr = cb_alloc(other->cba, *size); addr[0] = 0x38; addr[1] = (uintptr_t)call_buf; addr[2] = (uintptr_t)return_buf; cb_sync_alloc(other->cba); L4_MsgClear(&msg); L4_MsgLoad(&msg); (void)L4_Reply(other->threads.first->data.id); } }
int main(void) { int i = 0; int res = 1; L4_SpaceId_t space; okl4_allocator_attr_t attr; L4_Word_t end, result; L4_CapId_t sender; L4_MsgTag_t tag; L4_Msg_t msg; struct okl4_bitmap_allocator *spaceid_pool = okl4_env_get("MAIN_SPACE_ID_POOL"); HEAP_EXHAUSTION_CLIST = L4_ClistId(*(OKL4_ENV_GET_MAIN_CLISTID("MAIN_CLIST_ID"))); while(res == 1) { result = okl4_kspaceid_allocany(spaceid_pool, &space); if (result != OKL4_OK) { printf("Failed to allocate space id\n"); } res = create_address_space(space, L4_Fpage(0xb10000, 0x1000)); if (res != 1) { printf("SpaceControl failed, space id=%lu, Error code: %lu\n", space.space_no, L4_ErrorCode()); break; } /* 2gb mapping of 512k pages*/ res = map_series(space, 0x80000, 4096, 0, 0); i++; } printf("Created %d address spaces\n", i); if (i == 0) { okl4_kspaceid_free(spaceid_pool, space); res = 0; goto ipc_ktest; } /* clean up */ okl4_kspaceid_getattribute(spaceid_pool, &attr); end = attr.base + attr.size; for (i = attr.base; i < end; i++) { L4_SpaceId_t id = L4_SpaceId(i); if (okl4_kspaceid_isallocated(spaceid_pool, id)) { L4_SpaceControl(id, L4_SpaceCtrl_delete, HEAP_EXHAUSTION_CLIST, L4_Nilpage, 0, NULL); okl4_kspaceid_free(spaceid_pool, id); } } res = 1; ipc_ktest: tag = L4_Wait(&sender); L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t)res); L4_MsgLoad(&msg); L4_Reply(sender); assert(L4_IpcSucceeded(tag)); L4_WaitForever(); }
/* * Callback function to nfs_read from swapfile * Always replies to the thread */ void pager_read_callback(uintptr_t token,int status, fattr_t *attr, int bytes_read,char *data) { struct page_token *token_val = (struct page_token *) token; int pagetableIndex = token_val -> pageIndex; int byte_index = token_val -> chunk_index; int swapIndex = token_val -> swapIndex; if(status != 0) { page_table[pagetableIndex].error_in_transfer = 1; } else { //Copy the data read to memory char *memstart = (char *) (new_low + pagetableIndex * PAGESIZE + byte_index*NFS_READ_SIZE); memcpy(memstart,data,NFS_READ_SIZE); } page_table[pagetableIndex].read_bytes_transferred += NFS_READ_SIZE; //Check if all the callbacks have been received if(page_table[pagetableIndex].read_bytes_transferred == PAGESIZE) { if(page_table[pagetableIndex].error_in_transfer == 1) { //The memory in pagetable is inconsistent so the best thing would be to mark the //page table entry as unreferenced and hopefully its evicted soon //If this occurs for a free frame its best to free the frame //This condition is not required we would always want to free the frame(think and remove) if(!token_val -> writeToSwapIssued) { frame_free(new_low + pagetableIndex * PAGESIZE); } //Unmap the page table page whose memory we corrupted L4_UnmapFpage(page_table[pagetableIndex].tid,page_table[pagetableIndex].pageNo); page_table[pagetableIndex].tid = L4_nilthread; page_table[pagetableIndex].referenced = 0; page_table[pagetableIndex].dirty = 0; } else { //Free up the swap entry from which we read in swap_table[swapIndex].tid = L4_nilthread; swap_table[swapIndex].next_free = head_free_swap; head_free_swap = swapIndex; //Update page table page_table[pagetableIndex].tid = token_val -> destination_tid; page_table[pagetableIndex].pageNo = token_val -> destination_page; page_table[pagetableIndex].referenced = 1; page_table[pagetableIndex].dirty = 0; //Unmap the page which was written out if(token_val -> writeToSwapIssued) { L4_UnmapFpage(token_val -> source_tid,token_val -> source_page); } L4_Set_Rights(&(token_val -> destination_page),L4_Readable); L4_PhysDesc_t phys = L4_PhysDesc(new_low + pagetableIndex * PAGESIZE, L4_DefaultMemory); L4_MapFpage(token_val -> destination_tid, token_val -> destination_page, phys); L4_CacheFlushAll(); //Everything went fine } L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgLoad(&msg); L4_Reply(token_val -> destination_tid); //Update the process table size update_process_table_size(token_val -> destination_tid,1); page_table[pagetableIndex].being_updated = page_table[pagetableIndex].error_in_transfer = 0; } free(token_val); }
/* * Callback function to nfs_write to swapfile, Issues a read from swap if necessary * Replies to the thread if only swapout need to be done and no swapin */ void pager_write_callback(uintptr_t token, int status, fattr_t *attr) { struct page_token *token_val = (struct page_token *) token; int pageIndex = token_val -> pageIndex; int swapIndex = token_val -> swapIndex; if(status != 0) { //Something bad happened so we cannot overwrite the page content, lets delay for //next page fault page_table[pageIndex].error_in_transfer = 1; } //Increment the bytes transferred for each callback page_table[pageIndex].write_bytes_transferred += NFS_WRITE_SIZE; //If all callbacks have been received without an error we have a successful write if(page_table[pageIndex].write_bytes_transferred == PAGESIZE) { if(!page_table[pageIndex].error_in_transfer) { //Update the swap table swap_table[swapIndex].tid = token_val -> source_tid; swap_table[swapIndex].pageNo = token_val -> source_page; //Check if swapin needs to be done if(token_val -> send_reply) { L4_PhysDesc_t phys = L4_PhysDesc(new_low + pageIndex * PAGESIZE, L4_DefaultMemory); L4_Set_Rights(&(token_val -> destination_page),L4_Readable); //Map the page to the new tid L4_MapFpage(token_val -> destination_tid, token_val -> destination_page,phys); //Update page table page_table[pageIndex].tid = token_val -> destination_tid; page_table[pageIndex].pageNo = token_val -> destination_page; page_table[pageIndex].referenced = 1; page_table[pageIndex].dirty = 0; } else { //There is a read coming up readFromSwap(token_val -> swapIndexToBeReadIn,pageIndex,1,token_val -> destination_tid,token_val -> destination_page); } } else { // If there is an error in transfer, currently we have nothing to do //Since this write was invalidated we undo the change swap_file_size -= PAGESIZE; //Undo the swap that was allocated swap_table[swapIndex].next_free = head_free_swap; head_free_swap = swapIndex; } //If there was an error in transfer (we dont issue swapin even if needed) or //there was no swapin after swapoff we reply to faulting tid if(token_val -> send_reply || page_table[pageIndex].error_in_transfer) { //We clear the error in transfer value and being updated since the work is done page_table[pageIndex].being_updated = page_table[pageIndex].error_in_transfer = 0; //Now send the reply message //Update the process table size update_process_table_size(token_val -> source_tid,0); L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgLoad(&msg); L4_Reply(token_val ->destination_tid); } } //Free up the token free(token_val); }