/* * frame_draw_end - フレームの描画終了、フレームの最終位置を返す */ int frame_draw_end(const HWND hWnd) { HDC hdc; int draw_cnt; int ret; if (frame_rect[0].left == 0 && frame_rect[0].right == 0 && frame_rect[0].top == 0 && frame_rect[0].bottom == 0) { frame_free(); return -1; } // 前回描画分を消去 hdc = GetWindowDC(hWnd); for (draw_cnt = 0;draw_cnt < FRAME_CNT;draw_cnt++) { DrawFocusRect(hdc, (LPRECT)&frame_rect[draw_cnt]); } ReleaseDC(hWnd, hdc); // 境界位置の取得 ret = frame_rect[0].left - GetSystemMetrics(SM_CXFRAME); frame_free(); return ret; }
/*********** * returns JB_OK if a frame is available and *data points to the packet * returns JB_NOFRAME if it's no time to play voice and or no frame available * returns JB_INTERP if interpolating is required * returns JB_EMPTY if no voice frame is in the jitterbuffer (only during silence) * * if the next frame is a silence frame we will go in silence-mode * each new instance of the jitterbuffer will start in silence mode * in silence mode we will set the jitterbuffer to the size we want * when we are not in silence mode get_voicecase will handle the rest. */ static int get_voice(jitterbuffer *jb, void **data, long now, long interpl) { jb_frame *frame; long diff; int result; diff = jb->target - jb->current; //if the next frame is a silence frame, go in silence mode... if((get_next_frametype(jb, now - jb->current) == JB_TYPE_SILENCE) ) { jb_dbg("gs"); frame = get_frame(jb, now - jb->current); *data = frame->data; frame->data = NULL; jb->info.silence =1; jb->silence_begin_ts = frame->ts; frame_free(frame); result = JB_OK; } else { if(jb->info.silence) { // we are in silence /* * During silence we can set the jitterbuffer size to the size * we want... */ if (diff) { jb->current = jb->target; } frame = get_frame(jb, now - jb->current); if (frame) { if (jb->silence_begin_ts && frame->ts < jb->silence_begin_ts) { jb_dbg("gL"); /* voice frame is late, next!*/ jb->info.frames_late++; frame_free(frame); result = get_voice(jb, data, now, interpl); } else { jb_dbg("gP"); /* voice frame */ jb->info.silence = 0; jb->silence_begin_ts = 0; jb->next_voice_time = frame->ts + frame->ms; jb->info.last_voice_ms = frame->ms; *data = frame->data; frame->data = NULL; frame_free(frame); result = JB_OK; } } else { //no frame jb_dbg("gS"); result = JB_EMPTY; } } else { //voice case result = get_voicecase(jb,data,now,interpl,diff); } } return result; }
bool spage_table_load (struct spage_table_entry *spte, enum spage_types type) { // P3: reduce race condition with frame eviction process. spte->inevictable = true; if (spte->in_memory) return false; if (type == SWAP) { uint8_t *f = frame_alloc (PAL_USER, spte); if (!f) return false; if (!install_page (spte->upage, f, spte->writable)) { frame_free (f); return false; } swap_in (spte->swap_slot_id, spte->upage); spte->in_memory = true; } if (type == FILE || type == MMAP) { enum palloc_flags fg = PAL_USER; if (spte->file_read_bytes == 0) fg |= PAL_ZERO; uint8_t *f = frame_alloc (fg, spte); if (!f) return false; if (spte->file_read_bytes > 0) { lock_acquire (&lock_f); if ((int) spte->file_read_bytes != file_read_at (spte->file, f, spte->file_read_bytes, spte->file_offset)) { lock_release (&lock_f); frame_free (f); return false; } lock_release (&lock_f); memset (f + spte->file_read_bytes, 0, spte->file_zero_bytes); } if (!install_page (spte->upage, f, spte->writable)) { frame_free (f); return false; } spte->in_memory = true; } return true; }
static void _sos_page_map_5(void* token, seL4_Word kvaddr) { dprintf(3, "sos_page_map 5\n"); sos_page_map_cont_t* cont = (sos_page_map_cont_t*)token; seL4_CPtr kframe_cap, frame_cap; if (!kvaddr) { dprintf(3, "_sos_page_map_5 failed to allocate memory for frame\n"); cont->callback((void*)(cont->token), ENOMEM); free(cont); return; } int err = frame_get_cap(kvaddr, &kframe_cap); assert(!err); // There should be no error /* Copy the frame cap as we need to map it into 2 address spaces */ frame_cap = cspace_copy_cap(cur_cspace, cur_cspace, kframe_cap, cont->permissions); if (frame_cap == CSPACE_NULL) { frame_free(kvaddr); cont->callback((void*)(cont->token), EFAULT); free(cont); return; } /* Map the frame into application's address space */ err = _map_sel4_page(cont->as, frame_cap, cont->vpage, cont->permissions, seL4_ARM_Default_VMAttributes); if (err) { frame_free(kvaddr); cspace_delete_cap(cur_cspace, frame_cap); cont->callback((void*)(cont->token), err); free(cont); return; } //set frame referenced frame_set_referenced(kvaddr); /* Insert PTE into application's pagetable */ int x = PT_L1_INDEX(cont->vpage); int y = PT_L2_INDEX(cont->vpage); cont->as->as_pd_regs[x][y] = (kvaddr | PTE_IN_USE_BIT) & (~PTE_SWAPPED); cont->as->as_pd_caps[x][y] = frame_cap; dprintf(3, "_sos_page_map_5 called back up\n"); /* Calling back up */ cont->callback((void*)(cont->token), 0); free(cont); return; }
bool grow_stack (void *uaddr) { void *upage = pg_round_down (uaddr); if((size_t)(PHYS_BASE - upage) > (1 << 23)) return false; struct spage_table_entry *spte = malloc (sizeof (struct spage_table_entry)); if (!spte) return false; spte->upage = upage; spte->in_memory = true; spte->writable = true; spte->spage_type = SWAP; spte->inevictable = true; uint8_t *f = frame_alloc (PAL_USER, spte); if (!f) { free (spte); return false; } if (!install_page (spte->upage, f, spte->writable)) { free (spte); frame_free (f); return false; } if (intr_context ()) spte->inevictable = false; return hash_insert (&thread_current ()->spage_table, &spte->elem) == NULL; }
LIST * call_rule( char * rulename, FRAME * caller_frame, ... ) { va_list va; LIST * result; FRAME inner[1]; frame_init( inner ); inner->prev = caller_frame; inner->prev_user = caller_frame->module->user_module ? caller_frame : caller_frame->prev_user; inner->module = caller_frame->module; inner->procedure = 0; va_start( va, caller_frame ); for ( ; ; ) { LIST * l = va_arg( va, LIST* ); if ( !l ) break; lol_add( inner->args, l ); } va_end( va ); result = evaluate_rule( rulename, inner ); frame_free( inner ); return result; }
LIST * compile_rule( PARSE *parse, FRAME *frame ) { FRAME inner[1]; LIST *result; PARSE *p; /* Build up the list of arg lists */ frame_init( inner ); inner->prev = frame; inner->prev_user = frame->module->user_module ? frame : frame->prev_user; inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */ inner->procedure = parse; for( p = parse->left; p; p = p->left ) lol_add( inner->args, parse_evaluate( p->right, frame ) ); /* And invoke rule */ result = evaluate_rule( parse->string, inner ); frame_free( inner ); return result; }
void call_bind_rule( OBJECT * target_, OBJECT * boundname_ ) { LIST * const bind_rule = var_get( root_module(), constant_BINDRULE ); if ( !list_empty( bind_rule ) ) { OBJECT * target = object_copy( target_ ); OBJECT * boundname = object_copy( boundname_ ); if ( boundname && target ) { /* Prepare the argument list. */ FRAME frame[ 1 ]; frame_init( frame ); /* First argument is the target name. */ lol_add( frame->args, list_new( target ) ); lol_add( frame->args, list_new( boundname ) ); if ( lol_get( frame->args, 1 ) ) { OBJECT * rulename = list_front( bind_rule ); list_free( evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ) ); } /* Clean up */ frame_free( frame ); } else { if ( boundname ) object_free( boundname ); if ( target ) object_free( target ); } } }
LIST * compile_rule( PARSE * parse, FRAME * frame ) { FRAME inner[ 1 ]; LIST * result; PARSE * p; /* Build up the list of arg lists. */ frame_init( inner ); inner->prev = frame; inner->prev_user = frame->module->user_module ? frame : frame->prev_user; inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below. */ inner->procedure = parse; /* Special-case LOL of length 1 where the first list is totally empty. This is created when calling functions with no parameters, due to the way jam grammar is written. This is OK when one jam function calls another, but really not good when Jam function calls Python. */ if ( parse->left->left == NULL && parse->left->right->func == compile_null) ; else for ( p = parse->left; p; p = p->left ) lol_add( inner->args, parse_evaluate( p->right, frame ) ); /* And invoke the rule. */ result = evaluate_rule( parse->string, inner ); frame_free( inner ); return result; }
static void _sos_page_map_2_alloc_cap_pt(void* token, seL4_Word kvaddr) { dprintf(3, "sos_page_map 2\n"); sos_page_map_cont_t* cont = (sos_page_map_cont_t*)token; if (kvaddr == 0) { dprintf(3, "warning: _sos_page_map_2_alloc_cap_pt not enough memory for lvl2 pagetable\n"); cont->callback(cont->token, ENOMEM); free(cont); return; } seL4_Word vpage = PAGE_ALIGN(cont->vpage); int x = PT_L1_INDEX(vpage); cont->as->as_pd_regs[x] = (pagetable_t)kvaddr; /* Allocate memory for the 2nd level pagetable for caps */ int err = frame_alloc(0, NULL, PROC_NULL, true, _sos_page_map_3, token); if (err) { frame_free(kvaddr); cont->callback(cont->token, EFAULT); free(cont); return; } }
/* Look up the __TIMING_RULE__ variable on the given target, and if * non-empty, invoke the rule it names, passing the given * timing_info */ static void call_timing_rule(TARGET* target, timing_info* time) { LIST* timing_rule; pushsettings(target->settings); timing_rule = var_get( "__TIMING_RULE__" ); popsettings(target->settings); if (timing_rule) { /* We'll prepend $(__TIMING_RULE__[2-]) to the first argument */ LIST* initial_args = list_copy( L0, timing_rule->next ); /* Prepare the argument list */ FRAME frame[1]; frame_init( frame ); /* First argument is the name of the timed target */ lol_add( frame->args, list_new( initial_args, target->name ) ); append_double_string(frame->args, time->user); append_double_string(frame->args, time->system); if( lol_get( frame->args, 2 ) ) evaluate_rule( timing_rule->string, frame ); /* Clean up */ frame_free( frame ); } }
static addr contract(addr new_size, struct vmem_heap* heap) { /* Sanity check */ ASSERT(new_size < heap->end_address - heap->start_address); /* Get the nearest following page boundary */ if (new_size & 0x1000) { new_size &= 0x1000; new_size += 0x1000; } /* Don't contract too far */ if (new_size < VMEM_MIN_SIZE) new_size = VMEM_MIN_SIZE; addr old_size = heap->end_address - heap->start_address; addr i = old_size; while (new_size < i) { frame_free((struct page*)get_page(heap->start_address + i, 0, kernel_directory)); i -= 0x1000; } heap->end_address = heap->start_address + new_size; return new_size; }
/* Free the last page allocated to uvm */ void uvm_page_free() { uint32_t addr = (uint32_t)cur_task->uheap_end - PAGE_SIZE; frame_free(get_phys(addr, cur_task->page_dir)); page_map(addr, 0, 0, cur_task->page_dir); cur_task->uheap_end -= PAGE_SIZE; }
CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell ) { CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) ); FRAME frame[ 1 ]; assert( cmd ); cmd->rule = rule; cmd->shell = shell; cmd->next = 0; cmd->noop = 0; lol_init( &cmd->args ); lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); string_new( cmd->buf ); frame_init( frame ); frame->module = rule->module; lol_init( frame->args ); lol_add( frame->args, list_copy( targets ) ); lol_add( frame->args, list_copy( sources ) ); function_run_actions( rule->actions->command, frame, stack_global(), cmd->buf ); frame_free( frame ); return cmd; }
int main(int argc, char **argv) { struct frame_type frame; struct camera_control_block ccb; ccb.device.category = tir4_camera; ccb.diag = true; /* ccb.mode = operational_1dot; */ /* ccb.mode = operational_3dot; */ cal_init(&ccb); /* loop forever reading and printing results */ /* while (true) { */ /* cal_get_frame(&ccb, &frame); */ /* frame_print(frame); */ /* frame_free(&ccb, &frame); */ /* } */ int i; for(i=0; i<2000; i++) { cal_get_frame(&ccb, &frame); frame_print(frame); frame_free(&ccb, &frame); } /* call disconnects, turns all LEDs off */ cal_shutdown(&ccb); return 0; }
/* * Unmaps all the page table entries and pages and frees the frames for a tid */ void unmap_process(L4_ThreadId_t tid_killed) { //Clear page table for(int i=0;i<numPTE;i++) { if(L4_ThreadNo(page_table[i].tid) == L4_ThreadNo(tid_killed)) { L4_UnmapFpage(page_table[i].tid,page_table[i].pageNo); frame_free(new_low + i * PAGESIZE); page_table[i].tid = L4_nilthread; page_table[i].referenced = 0; page_table[i].dirty = 0; page_table[i].being_updated = 0; page_table[i].error_in_transfer = 0; page_table[i].pinned = 0; } } //Clear swap table for(int i=0;i<MAX_SWAP_ENTRIES;i++) { if(L4_ThreadNo(swap_table[i].tid) == L4_ThreadNo(tid_killed)) { swap_table[i].tid = L4_nilthread; swap_table[i].next_free = head_free_swap; head_free_swap = i; } } //Remove later not required L4_CacheFlushAll(); }
/*-------------------------------------------------------------------------------- * function: frame_sendWithFree * * Description: This function sends the frame to the phy layer to be sent out * then frees the allocated memory for that frame * * Argument 1: MAC data * * Argument 2: Frame --------------------------------------------------------------------------------*/ void frame_sendWithFree(frame_t *fr) { //**************************** // Add CRC //**************************** uint8_t txFrame[128]; uint8_t *ptr; uint8_t length = 0; ptr = txFrame; SET_FRAME_DATA(fr->payload, 0x0000, 2); if(fr->mac) { fr->mac->ptr = fr->mac->hdr; for(uint8_t x = 0;x<fr->mac->length; x++) { length++; *ptr++ = *fr->mac->ptr++; } } if(fr->nwk) { fr->nwk->ptr = fr->nwk->hdr; for(uint8_t x = 0;x<fr->nwk->length; x++) { length++; *ptr++ = *fr->nwk->ptr++; } } if(fr->aps) { fr->aps->ptr = fr->aps->hdr; for(uint8_t x = 0;x<fr->aps->length; x++) { length++; *ptr++ = *fr->aps->ptr++; } } if(fr->payload) { fr->payload->ptr = fr->payload->pl; for(uint8_t x = 0;x<fr->payload->length; x++) { length++; *ptr++ = *fr->payload->ptr++; } } rc_send_frame(length, txFrame); if(fr->mac){free(fr->mac);} if(fr->nwk){free(fr->nwk);} if(fr->aps){free(fr->aps);} if(fr->payload){free(fr->payload);} frame_free(fr); }
static void call_action_rule ( TARGET * target, int status, timing_info const * time, char const * executed_command, char const * command_output ) { LIST * action_rule; pushsettings( root_module(), target->settings ); action_rule = var_get( root_module(), constant_ACTION_RULE ); popsettings( root_module(), target->settings ); if ( !list_empty( action_rule ) ) { /* rule action-rule ( args * : target : command status start end user system : output ? ) */ /* Prepare the argument list. */ FRAME frame[ 1 ]; OBJECT * rulename = list_front( action_rule ); frame_init( frame ); /* args * :: $(__ACTION_RULE__[2-]) */ lol_add( frame->args, list_copy_range( action_rule, list_next( list_begin( action_rule ) ), list_end( action_rule ) ) ); /* target :: the name of the target */ lol_add( frame->args, list_new( object_copy( target->name ) ) ); /* command status start end user system :: info about the action command */ lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_push_back( list_push_back( list_new( object_new( executed_command ) ), outf_int( status ) ), outf_time( &time->start ) ), outf_time( &time->end ) ), outf_double( time->user ) ), outf_double( time->system ) ) ); /* output ? :: the output of the action command */ if ( command_output ) lol_add( frame->args, list_new( object_new( command_output ) ) ); else lol_add( frame->args, L0 ); /* Call the rule. */ evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ); /* Clean up. */ frame_free( frame ); } }
void thread_free(struct thread *thread) { uintptr_t i; /* free FPU/SSE data */ if (thread->fxdata) { heap_free(thread->fxdata, 512); thread->fxdata = NULL; } /* remove thread from scheduler */ schedule_remove(thread); /* free message packet if it exists */ if (thread->msg) { /* free packet contents */ for (i = 0; i < thread->msg->count; i++) { frame_free(thread->msg->frame[i]); } /* free the message packet structure */ heap_free(thread->msg->frame, thread->msg->count * sizeof(uint32_t)); heap_free(thread->msg, sizeof(struct msg)); } /* free thread local storage if it exists */ if (thread->stack) { i = (thread->stack - SSPACE) / SEGSZ; thread->proc->thread[i] = NULL; space_exmap(thread->proc->space); for (i = thread->stack; i < thread->stack + SEGSZ; i += PAGESZ) { if ((page_exget(i) & PF_PRES) != 0) { frame_free(page_ufmt(page_exget(i))); page_exset(i, 0); } } } /* free thread structure */ heap_free(thread, sizeof(struct thread)); }
void pt_cleanup(int pid) { assert(pid > 0 && pid <= MAX_PROCESSES); //free all the pages + revoke/delete the corresponding cap //9242_TODO unmark swapped out pages printf("Starting pt_cleanup\n"); seL4_Word** pd = proc_table[pid]->page_directory; seL4_ARM_PageTable **ct = proc_table[pid]->cap_table; if (pd) { for (int i = 0; i < PD_MAX_ENTRIES; i++) { if (pd[i]) { for (int j = 0; j < PT_MAX_ENTRIES; j++) { if (pd[i][j]) { if (pd[i][j] & SWAPPED) { printf("freeing a swap slot: %d\n", pd[i][j] & SWAP_SLOT_MASK); free_swap_slot(pd[i][j] & SWAP_SLOT_MASK); } else { int index = pd[i][j] & FRAME_INDEX_MASK; int page_pid = (frametable[index].frame_status & PROCESS_MASK) >> PROCESS_BIT_SHIFT; //if (page_pid == pid) { printf("page_pid = %d, pid = %d\n", page_pid, pid); frame_free(index); //} } } } frame_free(vaddr_to_index((seL4_Word) pd[i])); } } frame_free(vaddr_to_index((seL4_Word) pd)); } //free the cap table if (ct) { for (int i = 0; i < CAP_TABLE_PAGES; i++) { for (int j = 0; j < CT_MAX_ENTRIES; j++) { if ((seL4_Word) ct[i][j]) { seL4_ARM_Page_Unmap(ct[i][j]); } } frame_free(vaddr_to_index((seL4_Word) ct[i])); } } printf("pt cleanup ended\n"); }
/** * Deallocate space associated with slab * * @return number of freed frames */ static count_t slab_space_free(slab_cache_t *cache, slab_t *slab) { frame_free(KA2PA(slab->start)); if (! (cache->flags & SLAB_CACHE_SLINSIDE)) slab_free(slab_cache, slab); // atomic_dec(&cache->allocated_slabs); return 1 << cache->order; }
void headers( TARGET * t ) { LIST * hdrscan; LIST * hdrrule; #ifndef OPT_HEADER_CACHE_EXT LIST * headlist = L0; #endif regexp * re[ MAXINC ]; int rec = 0; LISTITER iter, end; hdrscan = var_get( root_module(), constant_HDRSCAN ); if ( list_empty( hdrscan ) ) return; hdrrule = var_get( root_module(), constant_HDRRULE ); if ( list_empty( hdrrule ) ) return; if ( DEBUG_HEADER ) printf( "header scan %s\n", object_str( t->name ) ); /* Compile all regular expressions in HDRSCAN */ iter = list_begin( hdrscan ), end = list_end( hdrscan ); for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) ) { re[ rec++ ] = regex_compile( list_item( iter ) ); } /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ { FRAME frame[1]; frame_init( frame ); lol_add( frame->args, list_new( object_copy( t->name ) ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); #else lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); #endif if ( lol_get( frame->args, 1 ) ) { /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( frame->args, list_new( object_copy( t->boundname ) ) ); list_free( evaluate_rule( list_front( hdrrule ), frame ) ); } /* Clean up. */ frame_free( frame ); } }
static void frame_command_remove_guts(frame_t *frame, char *hdr) { /* Remove attached patterns */ match_remove_frame(frame); /* Remove frame from Display Tool */ frame_display_frame_remove(frame_command_display, frame); /* Destroy frame */ frame_free(frame, hdr); }
static void type_check ( char * type_name, LIST * values, FRAME * caller, RULE * called, LIST * arg_name ) { static module_t * typecheck = 0; /* If nothing to check, bail now. */ if ( !values || !type_name ) return; if ( !typecheck ) typecheck = bindmodule( ".typecheck" ); /* If the checking rule can not be found, also bail. */ { RULE checker_, *checker = &checker_; checker->name = type_name; if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA * *)&checker ) ) return; } exit_module( caller->module ); while ( values != 0 ) { LIST *error; FRAME frame[1]; frame_init( frame ); frame->module = typecheck; frame->prev = caller; frame->prev_user = caller->module->user_module ? caller : caller->prev_user; enter_module( typecheck ); /* Prepare the argument list */ lol_add( frame->args, list_new( L0, values->string ) ); error = evaluate_rule( type_name, frame ); exit_module( typecheck ); if ( error ) argument_error( error->string, called, caller, arg_name ); frame_free( frame ); values = values->next; } enter_module( caller->module ); }
static void _process_dispose_thread_map(uint32_t pid) { // Unmap thread map uintptr_t thread_map = MEMORY_THREAD_MAP_VADDR + pid * THREAD_MAP_SIZE; size_t offset = 0; for (offset = 0; offset < THREAD_MAP_SIZE; offset += 0x1000) { uintptr_t phys = memory_physical(thread_map + offset); memory_unmap(thread_map + offset); frame_free(phys); } }
int as_destructor_arch(as_t *as) { #ifdef CONFIG_TSB size_t frames = SIZE2FRAMES((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t)); frame_free(KA2PA((uintptr_t) as->arch.itsb), frames); return frames; #else return 0; #endif }
static void spage_hash_remove (struct hash_elem *e, void *aux) { struct spage_table_entry *spte = hash_entry (e, struct spage_table_entry, elem); struct thread *t = thread_current (); if (spte->in_memory) { frame_free (pagedir_get_page (t->pagedir, spte->upage)); pagedir_clear_page (t->pagedir, spte->upage); } free (spte); }
void test_frame_init() { struct frame *frame; frame_malloc(&frame); frame_init(frame); assert(frame->window == NULL); assert(frame->begin_y == 0); assert(frame->begin_x == 0); frame_free(frame); }
/** * This function will select a page (based on second chance) * and swap it out to file system. However if the selected page * was not dirty then we just need to mark it swapped again and * can return immediatly. * We stop the initiator thread as long as we're swapping * data out to the file system. The thread is restarted in the * write callback function (above). * * @param initiator ID of the thread who caused the swapping to happen * @return SWAPPING_PENDING in case we need to write the page to the disk * SWAPPING_COMPLETE in case the page was not dirty * OUT_OF_SWAP_SPACE if our swap space is already full * NO_PAGE_AVAILABLE if second_chance_select did not find a page */ int swap_out(L4_ThreadId_t initiator) { page_queue_item* page = second_chance_select(&active_pages_head); if(page == NULL) { return NO_PAGE_AVAILABLE; } assert(!is_referenced(page)); // decide where in the swap file our page will be if(page->swap_offset < 0 && (page->swap_offset = allocate_swap_entry()) < 0) return OUT_OF_SWAP_SPACE; dprintf(1, "swap_out: Second chance selected page: thread:0x%X vaddr:0x%X swap_offset:0x%X\n", page->tid, page->virtual_address, page->swap_offset); if(is_dirty(page)) { dprintf(1, "Selected page is dirty, need to write to swap space\n"); page->to_swap = PAGESIZE; page->initiator = initiator; TAILQ_INSERT_TAIL(&swapping_pages_head, page, entries); file_table_entry* swap_fd = get_process(root_thread_g)->filetable[SWAP_FD]; assert(swap_fd != NULL); data_ptr physical_page = pager_physical_lookup(page->tid, page->virtual_address); assert(physical_page != NULL); // write page in swap file assert(PAGESIZE % BATCH_SIZE == 0); for(int write_offset=0; write_offset < page->to_swap; write_offset += BATCH_SIZE) { nfs_write( &swap_fd->file->nfs_handle, page->swap_offset + write_offset, BATCH_SIZE, physical_page + write_offset, &swap_write_callback, (int)page ); } return SWAPPING_PENDING; } else { assert(page->swap_offset >= 0); page_table_entry* pte = pager_table_lookup(page->tid, page->virtual_address); frame_free(CLEAR_LOWER_BITS(pte->address)); mark_swapped(pte, page->swap_offset); free(page); return SWAPPING_COMPLETE; } }
void test_frame_set() { struct frame *frame; int begin_y = 5; int begin_x = 10; frame_malloc(&frame); frame_init(frame); frame_set(frame, begin_y, begin_x); assert(frame->begin_y == begin_y); assert(frame->begin_x == begin_x); frame_free(frame); }