/* Allocate memory for all the frames we need */
VMBOOL allocate_drawing_resource(void) {
	do {
		/* Allocate buffers for each frame */
		if (!allocate_frame(&g_frame[0])) {
			break;
		}

		if (!allocate_frame(&g_frame[1])) {
			break;
		}

		if (!allocate_frame(&g_temp_frame)) {
			break;
		}

		/* Setup frame group for composite and display */
		g_frame_group[0] = &g_frame[0];
		g_frame_group[1] = &g_frame[1];

		return VM_TRUE;
	} while(0);

	/* Failed to allocate all buffers, free */
	return VM_FALSE;
}
Beispiel #2
0
SCM make_ffmpeg_input(SCM scm_file_name, SCM scm_debug)
{
  SCM retval;
  struct ffmpeg_t *self;
  scm_dynwind_begin(0);
  const char *file_name = scm_to_locale_string(scm_file_name);
  scm_dynwind_free(file_name);
  self = (struct ffmpeg_t *)scm_gc_calloc(sizeof(struct ffmpeg_t), "ffmpeg");
  self->video_stream_idx = -1;
  self->audio_stream_idx = -1;
  SCM_NEWSMOB(retval, ffmpeg_tag, self);

  int err;
  err = avformat_open_input(&self->fmt_ctx, file_name, NULL, NULL);
  if (err < 0) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-input", "Error opening file '~a': ~a", scm_list_2(scm_file_name, get_error_text(err)));
  };

  err = avformat_find_stream_info(self->fmt_ctx, NULL);
  if (err < 0) {
    ffmpeg_destroy(retval);
    scm_misc_error("make-ffmpeg-input", "No stream information in file '~a': ~a", scm_list_2(scm_file_name, get_error_text(err)));
  };

  // TODO: only open desired streams
  // Open video stream
  self->video_stream_idx = av_find_best_stream(self->fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
  if (self->video_stream_idx >= 0)
    self->video_codec_ctx = open_decoder(retval, scm_file_name, video_stream(self), "video");

  // Open audio stream
  self->audio_stream_idx = av_find_best_stream(self->fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
  if (self->audio_stream_idx >= 0)
    self->audio_codec_ctx = open_decoder(retval, scm_file_name, audio_stream(self), "audio");

  // Print debug information
  if (scm_is_true(scm_debug)) av_dump_format(self->fmt_ctx, 0, file_name, 0);

  // Allocate input frames
  self->video_target_frame = allocate_frame(retval);
  self->audio_target_frame = allocate_frame(retval);

  // Initialise data packet
  av_init_packet(&self->pkt);
  self->pkt.data = NULL;
  self->pkt.size = 0;

  scm_dynwind_end();
  return retval;
}
Beispiel #3
0
void* kma_malloc(kma_size_t size)
{

	if(size >= PAGE_SIZE)
		return NULL;

	if(entry_page == NULL)
		init_first_page();

	kma_frame* current = (kma_frame*)entry_page->ptr;

	//go until last in the list or we find one that fits
	bool fits = (current->occupied == FREE &&  frame_size(current) >= size);
	while(current->last == NOT_LAST && !fits){
		current = current->next;
		fits = (current->occupied == FREE &&  frame_size(current) >= size);
	}

	void* ret_addr;

	//if it fits...
	if(fits){

		allocate_frame(current,size);
		ret_addr =  data_ptr(current);

	//if not...
	}else{

		//if nothing in the resource map fits, we need to allocate a new page
		//ifwe are here, current should be last


		kma_page_t* new_page = get_page();
		void* next = ((char*) new_page->ptr) + new_page->size;
		
 		kma_frame* new_frame = write_new_frame(new_page->ptr, new_page, current, next, FREE, LAST);

 		allocate_frame(new_frame,size);

 		current->last = NOT_LAST;

 		
 		ret_addr =  data_ptr(new_frame);
	}

  //print_debug();
  return ret_addr;
  
}
Beispiel #4
0
static AVFrame *allocate_output_audio_frame(SCM scm_self, AVCodecContext *audio_codec, enum AVSampleFormat sample_fmt)
{
  AVFrame *retval = allocate_frame(scm_self);
  retval->format = sample_fmt;
  retval->channel_layout = audio_codec->channel_layout;
  retval->sample_rate = audio_codec->sample_rate;

  if (audio_codec->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
    retval->nb_samples = 2 * AV_INPUT_BUFFER_MIN_SIZE;
  else
    retval->nb_samples = audio_codec->frame_size;

#ifdef HAVE_AV_FRAME_GET_BUFFER
  int err = av_frame_get_buffer(retval, 0);
  if (err < 0) {
    ffmpeg_destroy(scm_self);
    scm_misc_error("allocate-output-audio-frame", "Error allocating audio frame memory", SCM_EOL);
  };
#else
  int channels = av_get_channel_layout_nb_channels(retval->channel_layout);
  int err = av_samples_alloc(retval->data, &retval->linesize[0], channels, retval->nb_samples, retval->format, 0);
  // TODO: need av_freep?
  if (err < 0) {
    ffmpeg_destroy(scm_self);
    scm_misc_error("allocate-output-audio-frame", "Could not allocate audio buffer", SCM_EOL);
  };
#endif
  return retval;
}
Beispiel #5
0
static AVFrame *allocate_output_video_frame(SCM scm_self, AVCodecContext *video_context)
{
  AVFrame *retval = allocate_frame(scm_self);
  int width = video_context->width;
  int height = video_context->height;
  retval->format = PIX_FMT;
  retval->width = width;
  retval->height = height;
#ifdef HAVE_AV_FRAME_GET_BUFFER
  int err = av_frame_get_buffer(retval, 32);
  if (err < 0) {
    ffmpeg_destroy(scm_self);
    scm_misc_error("allocate-output-frame", "Error allocating frame buffer: ~a",
                   scm_list_1(get_error_text(err)));
  };
#else
  int size = avpicture_get_size(PIX_FMT, width, height);
  uint8_t *frame_buffer = (uint8_t *)av_malloc(size);
  if (!frame_buffer) {
    ffmpeg_destroy(scm_self);
    scm_misc_error("allocate-output-video-frame", "Error allocating video frame memory", SCM_EOL);
  };
  avpicture_fill((AVPicture *)retval, frame_buffer, PIX_FMT, width, height);
#endif
  return retval;
}
/*
 * Locate the physical frame number for the given vaddr using the page table.
 *
 * If the entry is invalid and not on swap, then this is the first reference 
 * to the page and a (simulated) physical frame should be allocated and 
 * initialized (using init_frame).  
 *
 * If the entry is invalid and on swap, then a (simulated) physical frame
 * should be allocated and filled by reading the page data from swap.
 *
 * Counters for hit, miss and reference events should be incremented in
 * this function.
 */
char *find_physpage(addr_t vaddr, char type) {
	pgtbl_entry_t *p=NULL; // pointer to the full page table entry for vaddr
	unsigned idx = PGDIR_INDEX(vaddr); // get index into page directory

	// IMPLEMENTATION NEEDED
	// Use top-level page directory to get pointer to 2nd-level page table
	if (!(pgdir[idx].pde & PG_VALID)){
		pgdir[idx] = init_second_level();
	}

	// Use vaddr to get index into 2nd-level page table and initialize 'p'
	uintptr_t ptr_table = PAGE_MASK & pgdir[idx].pde;
	p = (pgtbl_entry_t*)(ptr_table) + PGTBL_INDEX(vaddr);

	// Check if p is valid or not, on swap or not, and handle appropriately
	
	// Page is present in the memory
	if (p->frame & PG_VALID){
		hit_count++;

	// Page is not present in the memory
	} else {
		miss_count++;
		ref_count++;
		int frame = allocate_frame(p);

		// Page on disk.
		if (p->frame & PG_ONSWAP){
			swap_pagein(frame, p->swap_off);
			p->frame = frame << PAGE_SHIFT;
			p->frame = p->frame | PG_VALID;

		// Page not on disk, first time access the page	
		} else {
			init_frame(frame, vaddr);
			p->frame = frame << PAGE_SHIFT;
			p->frame = p->frame | PG_DIRTY;			
		}
	}

	// Make sure that p is marked valid. Also mark it dirty
	// if the access type indicates that the page will be written to
	p->frame = p->frame | PG_VALID;

	if(type == 'S' || type == 'M'){
		p->frame = p->frame | PG_DIRTY;
	}

	// Call replacement algorithm's ref_fcn for this page
	ref_fcn(p);

	// p is marked referenced.
	p->frame = p->frame | PG_REF;
	
	// Return pointer into (simulated) physical memory at start of frame
	return  &physmem[(p->frame >> PAGE_SHIFT)*SIMPAGESIZE];
}
Beispiel #7
0
frame_ptr read_JPEG_file (char * filename) {
    /* This struct contains the JPEG decompression parameters and pointers to
     * working space (which is allocated as needed by the JPEG library).
     */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE * infile;		/* source file */
    frame_ptr p_info;		/* Output frame information */

    JSAMPLE *realBuffer;
    JSAMPLE **buffer;		/* Output row buffer */
    int row_stride;		/* physical row width in output buffer */

    /* Step 1: allocate and initialise JPEG decompression object */
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);

    /* Step 2: open & specify data source (eg, a file) */
    if ((infile = fopen(filename, "rb")) == NULL) {
        fprintf(stderr, "ERROR: Can't open input file %s\n", filename);
        exit(1);
    }
    jpeg_stdio_src(&cinfo, infile);

    /* Step 3: read file parameters with jpeg_read_header() */
    (void) jpeg_read_header(&cinfo, TRUE);

    /* Step 4: use default parameters for decompression */

    /* Step 5: Start decompressor */
    (void) jpeg_start_decompress(&cinfo);

    /* Step X: Create a frame struct & buffers and fill in the blanks */
    fprintf(stderr, "  Opened %s: height = %d, width = %d, c = %d\n",
            filename, cinfo.output_height, cinfo.output_width, cinfo.output_components);
    p_info = allocate_frame(cinfo.output_height, cinfo.output_width, cinfo.output_components);

    /* Step 6: while (scan lines remain to be read) */
    /*           jpeg_read_scanlines(...); */
    while (cinfo.output_scanline < cinfo.output_height) {
        (void) jpeg_read_scanlines(&cinfo, &(p_info->row_pointers[cinfo.output_scanline]), 1);
    }

    /* Step 7: Finish decompression */
    (void) jpeg_finish_decompress(&cinfo);

    /* Step 8: Release JPEG decompression object & file */
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);

    /* At this point you may want to check to see whether any corrupt-data
     * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
     */

    /* And we're done! */
    return p_info;
}
Beispiel #8
0
void* kmalloc(unsigned int size)
{
	//TODO: [PROJECT 2016 - Kernel Dynamic Allocation/Deallocation] kmalloc()
	// Write your code here, remove the panic and write your code
	//panic("kmalloc() is not implemented yet...!!");

	//NOTE: Allocation is continuous increasing virtual address
	//NOTE: All kernel heap allocations are multiples of PAGE_SIZE (4KB)
	//refer to the project documentation for the detailed steps

	//check the size
	if(size >= KERNEL_HEAP_MAX - kernelInside) return NULL;
	//--------------why not !-------------------------------
	//if(kernelInside + size >= KERNEL_HEAP_MAX) return NULL;

	//good!, let's begin
	//uint32 endVA = ROUNDUP((uint32) kernelInside + size, PAGE_SIZE);
	uint32 va;
	for(va = kernelInside; va < kernelInside + size; va += PAGE_SIZE){
		//(1) allocate a free frame
		struct Frame_Info* frameInfo = NULL;
		if(allocate_frame(&frameInfo) == E_NO_MEM) return NULL;

		//(2) map the page to the allocated frame
		if(map_frame(ptr_page_directory, frameInfo, (void*) va,
				PERM_WRITEABLE | PERM_PRESENT) == E_NO_MEM)
			return NULL;
	}

	//keep the block in my keepBlock array
	keepBlocks[nextBlock].blockStartVirtualAddress = (uint32*) kernelInside;
	keepBlocks[nextBlock++].blockSize = size;

	//TODO: [PROJECT 2016 - BONUS1] Implement a Kernel allocation strategy
	// Instead of the continuous allocation/deallocation, implement one of
	// the strategies NEXT FIT, BEST FIT, .. etc


	//change this "return" according to your answer
	//uint32 ret = kernelInside;
	kernelInside = va;
	return (void*) keepBlocks[nextBlock - 1].blockStartVirtualAddress;
}
// Allocates a new env and loads the named user program into it.
struct Env* env_create(char* user_program_name, unsigned int page_WS_size)
{
	//[1] get pointer to the start of the "user_program_name" program in memory
	// Hint: use "get_user_program_info" function,
	// you should set the following "ptr_program_start" by the start address of the user program
	uint8* ptr_program_start = 0;

	struct UserProgramInfo* ptr_user_program_info = get_user_program_info(user_program_name);
	if(ptr_user_program_info == 0) return NULL;
	ptr_program_start = ptr_user_program_info->ptr_start ;
	//	if(ptr_user_program_info->environment != NULL)
	//	{
	//		cprintf("env_create: an old environment already exist for [%s]!! \nfreeing the old one by calling start_env_free....\n", ptr_user_program_info->environment->prog_name);
	//		start_env_free(ptr_user_program_info->environment);
	//
	//		//return ptr_user_program_info;
	//	}


	//[2] allocate new environment, (from the free environment list)
	//if there's no one, return NULL
	// Hint: use "allocate_environment" function
	struct Env* e = NULL;
	if(allocate_environment(&e) < 0)
	{
		return 0;
	}

	//[2.5 - 2012] Set program name inside the environment
	e->prog_name = ptr_user_program_info->name ;

	//[3] allocate a frame for the page directory, Don't forget to set the references of the allocated frame.
	//REMEMBER: "allocate_frame" should always return a free frame
	uint32* ptr_user_page_directory;
	unsigned int phys_user_page_directory;
	if(USE_KHEAP)
	{
		ptr_user_page_directory = create_user_directory();
		phys_user_page_directory = kheap_physical_address((uint32)ptr_user_page_directory);
	}
	else
	{
		int r;
		struct Frame_Info *p = NULL;

		allocate_frame(&p) ;
		p->references = 1;

		ptr_user_page_directory = STATIC_KERNEL_VIRTUAL_ADDRESS(to_physical_address(p));
		phys_user_page_directory = to_physical_address(p);
	}

	//[4] initialize the new environment by the virtual address of the page directory
	// Hint: use "initialize_environment" function

	//2016
	e->page_WS_max_size = page_WS_size;

	initialize_environment(e, ptr_user_page_directory, phys_user_page_directory);

	// We want to load the program into the user virtual space
	// each program is constructed from one or more segments,
	// each segment has the following information grouped in "struct ProgramSegment"
	//	1- uint8 *ptr_start: 	start address of this segment in memory
	//	2- uint32 size_in_file: size occupied by this segment inside the program file,
	//	3- uint32 size_in_memory: actual size required by this segment in memory
	// 	usually size_in_file < or = size_in_memory
	//	4- uint8 *virtual_address: start virtual address that this segment should be copied to it

	//[6] switch to user page directory
	// Hint: use rcr3() and lcr3()
	uint32 kern_phys_pgdir = rcr3() ;
	lcr3(e->env_cr3) ;

	//[7] load each program segment into user virtual space
	struct ProgramSegment* seg = NULL;  //use inside PROGRAM_SEGMENT_FOREACH as current segment information
	int segment_counter=0;
	uint32 remaining_ws_pages = (e->page_WS_max_size)-1; // we are reserving 1 page of WS for the stack that will be allocated just before the end of this function
	uint32 lastTableNumber=0xffffffff;

	PROGRAM_SEGMENT_FOREACH(seg, ptr_program_start)
	{
		segment_counter++;
		//allocate space for current program segment and map it at seg->virtual_address then copy its content
		// from seg->ptr_start to seg->virtual_address
		//Hint: use program_segment_alloc_map_copy_workingset()

		//cprintf("SEGMENT #%d, dest start va = %x, dest end va = %x\n",segment_counter, seg->virtual_address, (seg->virtual_address + seg->size_in_memory));
		LOG_STRING("===============================================================================");
		LOG_STATMENT(cprintf("SEGMENT #%d, size_in_file = %d, size_in_memory= %d, dest va = %x",segment_counter,seg->size_in_file,
				seg->size_in_memory, seg->virtual_address));
		LOG_STRING("===============================================================================");

		uint32 allocated_pages=0;
		program_segment_alloc_map_copy_workingset(e, seg, &allocated_pages, remaining_ws_pages, &lastTableNumber);

		remaining_ws_pages -= allocated_pages;
		LOG_STATMENT(cprintf("SEGMENT: allocated pages in WS = %d",allocated_pages));
		LOG_STATMENT(cprintf("SEGMENT: remaining WS pages after allocation = %d",remaining_ws_pages));


		///[1] temporary initialize 1st page in memory then writing it on page file
		uint32 dataSrc_va = (uint32) seg->ptr_start;
		uint32 seg_va = (uint32) seg->virtual_address ;

		uint32 start_first_page = ROUNDDOWN(seg_va , PAGE_SIZE);
		uint32 end_first_page = ROUNDUP(seg_va , PAGE_SIZE);
		uint32 offset_first_page = seg_va  - start_first_page ;

		memset(ptr_temp_page , 0, PAGE_SIZE);
		uint8 *src_ptr =  (uint8*) dataSrc_va;
		uint8 *dst_ptr =  (uint8*) (ptr_temp_page + offset_first_page);
		int i;
		for (i = seg_va ; i < end_first_page ; i++, src_ptr++,dst_ptr++ )
		{
			*dst_ptr = *src_ptr ;
		}

		if (pf_add_env_page(e, start_first_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE)
			panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");

		//LOG_STRING(" -------------------- PAGE FILE: 1st page is written");


		///[2] Start writing the segment ,from 2nd page until before last page, to page file ...

		uint32 start_last_page = ROUNDDOWN(seg_va  + seg->size_in_file, PAGE_SIZE) ;
		uint32 end_last_page = seg_va  + seg->size_in_file;

		for (i = end_first_page ; i < start_last_page ; i+= PAGE_SIZE, src_ptr+= PAGE_SIZE)
		{
			if (pf_add_env_page(e, i, src_ptr) == E_NO_PAGE_FILE_SPACE)
				panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");

		}
		//LOG_STRING(" -------------------- PAGE FILE: 2nd page --> before last page are written");

		///[3] temporary initialize last page in memory then writing it on page file

		dst_ptr =  (uint8*) ptr_temp_page;
		memset(dst_ptr, 0, PAGE_SIZE);

		for (i = start_last_page ; i < end_last_page ; i++, src_ptr++,dst_ptr++ )
		{
			*dst_ptr = *src_ptr;
		}
		if (pf_add_env_page(e, start_last_page, ptr_temp_page) == E_NO_PAGE_FILE_SPACE)
			panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");


		//LOG_STRING(" -------------------- PAGE FILE: last page is written");

		///[4] writing the remaining seg->size_in_memory pages to disk

		uint32 start_remaining_area = ROUNDUP(seg_va + seg->size_in_file,PAGE_SIZE) ;
		uint32 remainingLength = (seg_va + seg->size_in_memory) - start_remaining_area ;

		for (i=0 ; i < ROUNDUP(remainingLength,PAGE_SIZE) ;i+= PAGE_SIZE, start_remaining_area += PAGE_SIZE)
		{
			if (pf_add_empty_env_page(e, start_remaining_area, 1) == E_NO_PAGE_FILE_SPACE)
				panic("ERROR: Page File OUT OF SPACE. can't load the program in Page file!!");
		}
		//LOG_STRING(" -------------------- PAGE FILE: segment remaining area is written (the zeros) ");
	}
//
// Allocate length bytes of physical memory for environment env,
// and map it at virtual address va in the environment's address space.
// Does not zero or otherwise initialize the mapped pages in any way.
// Pages should be writable by user and kernel.
//
// The allocation shouldn't failed
// return 0
//
static int program_segment_alloc_map_copy_workingset(struct Env *e, struct ProgramSegment* seg, uint32* allocated_pages, uint32 remaining_ws_pages, uint32* lastTableNumber)
{
	void *vaddr = seg->virtual_address;
	uint32 length = seg->size_in_memory;

	uint32 end_vaddr = ROUNDUP((uint32)vaddr + length,PAGE_SIZE) ;
	uint32 iVA = ROUNDDOWN((uint32)vaddr,PAGE_SIZE) ;
	int r ;
	uint32 i = 0 ;
	struct Frame_Info *p = NULL;

	*allocated_pages = 0;

	/*2015*/// Load max of 6 pages only for the segment that start with va = 200000 [EXCEPT tpp]
	if (iVA == 0x200000 && strcmp(e->prog_name, "tpp")!=0)
		remaining_ws_pages = remaining_ws_pages < 6 ? remaining_ws_pages:6 ;
	/*==========================================================================================*/
	for (; iVA < end_vaddr && i<remaining_ws_pages; i++, iVA += PAGE_SIZE)
	{
		// Allocate a page
		allocate_frame(&p) ;

		LOG_STRING("segment page allocated");
		loadtime_map_frame(e->env_page_directory, p, (void *)iVA, PERM_USER | PERM_WRITEABLE);
		LOG_STRING("segment page mapped");

		LOG_STATMENT(cprintf("Updating working set entry # %d",e->page_last_WS_index));

		e->ptr_pageWorkingSet[e->page_last_WS_index].virtual_address = iVA;
		e->ptr_pageWorkingSet[e->page_last_WS_index].empty = 0;
		e->ptr_pageWorkingSet[e->page_last_WS_index].time_stamp = 0;

		e->page_last_WS_index ++;
		e->page_last_WS_index %= (e->page_WS_max_size);

		//if a new table is created during the mapping, add it to the table working set
		if(PDX(iVA) != (*lastTableNumber))
		{
			addTableToTableWorkingSet(e, ROUNDDOWN(iVA, PAGE_SIZE*1024));
			if (e->table_last_WS_index == 0)
				panic("\nenv_create: Table working set become FULL during the application loading. Please increase the table working set size to be able to load the program successfully\n");
			(*lastTableNumber) = PDX(iVA);
		}

		/// TAKE CARE !!!! this was an destructive error
		/// DON'T MAKE IT " *allocated_pages ++ " EVER !
		(*allocated_pages) ++;
	}

	uint8 *src_ptr = (uint8 *)(seg->ptr_start) ;
	uint8 *dst_ptr = (uint8 *) seg->virtual_address;

	//copy program segment page from (seg->ptr_start) to (seg->virtual_address)

	LOG_STATMENT(cprintf("copying data to allocated area VA %x from source %x",dst_ptr,src_ptr));
	while((uint32)dst_ptr < (ROUNDDOWN((uint32)vaddr,PAGE_SIZE) + (*allocated_pages)*PAGE_SIZE) &&
			((uint32)dst_ptr< ((uint32)vaddr+ seg->size_in_file)) )
	{
		*dst_ptr = *src_ptr ;
		dst_ptr++ ;
		src_ptr++ ;
	}
	LOG_STRING("zeroing remaining page space");
	while((uint32)dst_ptr < (ROUNDDOWN((uint32)vaddr,PAGE_SIZE) + (*allocated_pages)*PAGE_SIZE) )
	{
		*dst_ptr = 0;
		dst_ptr++ ;
	}

	//============================================

	//	LOG_STRING("creating page tables");
	//	iVA = ROUNDDOWN((uint32)vaddr,PAGE_SIZE) ;
	//	i = 0 ;
	//	for (; iVA < end_vaddr; i++, iVA += PAGE_SIZE)
	//	{
	//		uint32 *ptr_page_table;
	//		get_page_table(e->env_pgdir, (void *)iVA, 1, &ptr_page_table);
	//	}
	//	LOG_STRING("page tables created successfully");
	return 0;
}
Beispiel #11
0
/*
 * Locate the physical frame number for the given vaddr using the page table.
 *
 * If the entry is invalid and not on swap, then this is the first reference 
 * to the page and a (simulated) physical frame should be allocated and 
 * initialized (using init_frame).  
 *
 * If the entry is invalid and on swap, then a (simulated) physical frame
 * should be allocated and filled by reading the page data from swap.
 *
 * Counters for hit, miss and reference events should be incremented in
 * this function.
 */
char *find_physpage(addr_t vaddr, char type) {

	pgtbl_entry_t *p=NULL; // pointer to the full page table entry for vaddr
	unsigned idx = PGDIR_INDEX(vaddr); // get index into page directory

	// IMPLEMENTATION NEEDED
	// Use top-level page directory to get pointer to 2nd-level page table

	// Check if it's valid
	unsigned int valid_pde = pgdir[idx].pde & PG_VALID;

	// Not Valid, initialize a 2nd pagetable
	if (!valid_pde) {

		pgdir[idx] = init_second_level();

	}

	// Use vaddr to get index into 2nd-level page table and initialize 'p'
	unsigned pgtbl_index =  PGTBL_INDEX(vaddr);
	p = (pgtbl_entry_t *) (pgdir[idx].pde & PAGE_MASK);
	p = p + pgtbl_index;

	// Check if p is valid or not, on swap or not, and handle appropriately
	// Find the valid bit and the on-swap bit
	unsigned int valid = p->frame & PG_VALID;
	unsigned int on_swap = p->frame & PG_ONSWAP;

	// Check if it's valid
	if (!valid) {

		// Allocate a frame for p
		int frame = allocate_frame(p);

		// Update fields for OPT
		coremap[frame].pgtbl_idx = (int) pgtbl_index;
		coremap[frame].pgdir_idx = (int) idx;

		// On swap
		if (on_swap) {
			// Read the page from swap
			int success = swap_pagein(frame, p->swap_off);
			assert(success == 0);

		}
 
		// Not on swap
		if (!on_swap) { 
			// Initialize the frame
			init_frame(frame, vaddr);

			// Mark it as dirty
			p->frame = p->frame | PG_DIRTY;

		}

		// Not Valid, so increment miss
		miss_count++;
	
	} 


	// Make sure that p is marked valid and referenced. Also mark it
	// dirty if the access type indicates that the page will be written to.

	// Mark p as valid and referenced
	p->frame = p->frame | PG_VALID;
	p->frame = p->frame | PG_REF;

	unsigned int check =  p->frame & PG_VALID;
	assert(check);

	// Check the access type
	if ((type == 'S') || (type == 'M')) {

		// Set the dirty bit
		p->frame = p->frame | PG_DIRTY;

	} 

	// Increment ref, hit
	if (valid) {
		hit_count++;
	}

	ref_count++;


	// Call replacement algorithm's ref_fcn for this page
	ref_fcn(p);

	// Return pointer into (simulated) physical memory at start of frame
	return  &physmem[(p->frame >> PAGE_SHIFT)*SIMPAGESIZE];
}
Beispiel #12
0
/* The shell's main routine.  Consists of several steps:
 *  1> Reads JPEGs using first command-line parameter(s)
 *  2> Records the process's elapsed time
 *  3> Lets the user play with the images
 *  4> Checks the elapsed time again, prints out the difference
 *  5> Writes JPEGs out using last command-line parameter(s)
 */
int main(int argc, char *argv[]) {
    int i;
    int num_inputs; /* Number of JPEG input-output files */
    int num_runs, run;  /* Number of runs, for multi-run code */
    double run_time, total_time; /* Amount of time we've run */
    struct timeval start_time, end_time; /* Time before/after user code */

    /* Step 0A: Check & process command line */
    if (argc != 1 + NUM_INPUTS + NUM_OUTPUTS + RUNS_COMMAND + RUNS_PROCS) {
        fprintf(stderr, "Usage: %s runs procs input1.jpg %soutput.jpg\n",
                argv[0],
                NUM_INPUTS > 1 ? "input2.jpg " : "");
        exit(1);
    }

    num_inputs = argc - 1 - NUM_OUTPUTS - RUNS_COMMAND - RUNS_PROCS;

    num_runs = atoi(argv[1]);
    if (num_runs < 1) num_runs = 1;
    if (num_runs > 10) num_runs = 10; /* Change if you like LOTS of runs */
    fprintf(stderr, "Making %d runs . . .\n", num_runs);
    num_procs = atoi(argv[1 + RUNS_COMMAND]);
    if (num_procs < 1) num_procs = 1;
    if (num_procs > 256) num_procs = 256;
    fprintf(stderr, "Using %d processors . . .\n", num_procs);

    /* Step 1: Get some JPEGs into memory, uncompressed */
    for (i=0; i < num_inputs; i++)
        input_frames[i] = read_JPEG_file(argv[i+1+RUNS_COMMAND+RUNS_PROCS]);

    /* Step 2: Allocate output frames */
    for (i=0; i < NUM_OUTPUTS; i++)
        output_frames[i] = allocate_frame(input_frames[i]->image_height,
                                          input_frames[i]->image_width,
                                          input_frames[i]->num_components);

    /* Loop over multiple runs, if desired */

    total_time = 0.0;
    run = 0;
    while ((run < num_runs)) {
        /* Step 3: Record elapsed time */
        gettimeofday(&start_time, NULL);

        /* Step 4: Call a user function! */
        EEE4084F_parallel();

        /* Step 5: Check & print elapsed time */
        gettimeofday(&end_time, NULL);
        run_time = ((double)(end_time.tv_sec) + (double)(end_time.tv_usec)/1000000.0)
                   - ((double)(start_time.tv_sec) + (double)(start_time.tv_usec)/1000000.0);

        fprintf(stderr, "%d. ELAPSED  TIME = %20.3f sec\n", run, run_time);
        total_time += run_time;
#ifdef NO_FIRST
        if (run == 0) {
            fprintf(stderr, "  . . . first run discarded\n");
            total_time = 0.0;
        }
#endif
        run++;
    }

    /* Print out final, average time, if desired */
#ifdef NO_FIRST
    fprintf(stderr, "AVERAGE ELAPSED TIME = %20.3f seconds\n",
            total_time / ((double)(run - 1)));
#else
    fprintf(stderr, "AVERAGE ELAPSED TIME = %20.3f seconds\n",
            total_time / ((double)run));
#endif

    /* Step 6: Write JPEGs out from memory buffers */
    for (i=0; i < NUM_OUTPUTS; i++)
        write_JPEG_file(argv[argc - NUM_OUTPUTS + i], output_frames[i], OUT_QUALITY);

    destroy_frame(input_frames[0]);
    printf("input_frame[0]!\n");
    destroy_frame(output_frames[0]);
    printf("output_frame[0]!\n");

}
Beispiel #13
0
void h2o_http2_encode_goaway_frame(h2o_buffer_t **buf, uint32_t last_stream_id, int errnum)
{
    uint8_t *dst = allocate_frame(buf, 8, H2O_HTTP2_FRAME_TYPE_GOAWAY, 0, 0);
    dst = encode32u(dst, last_stream_id);
    dst = encode32u(dst, errnum);
}
Beispiel #14
0
void h2o_http2_encode_ping_frame(h2o_buffer_t **buf, int is_ack, const uint8_t *data)
{
    uint8_t *dst = allocate_frame(buf, 8, H2O_HTTP2_FRAME_TYPE_PING, is_ack ? H2O_HTTP2_FRAME_FLAG_ACK : 0, 0);
    memcpy(dst, data, 8);
    dst += 8;
}
Beispiel #15
0
void h2o_http2_encode_rst_stream_frame(h2o_buffer_t **buf, uint32_t stream_id, int errnum)
{
    uint8_t *dst = allocate_frame(buf, 4, H2O_HTTP2_FRAME_TYPE_RST_STREAM, 0, stream_id);
    dst = encode32u(dst, errnum);
}
Beispiel #16
0
void h2o_http2_encode_window_update_frame(h2o_buffer_t **buf, uint32_t stream_id, int32_t window_size_increment)
{
    uint8_t *dst = allocate_frame(buf, 4, H2O_HTTP2_FRAME_TYPE_WINDOW_UPDATE, 0, stream_id);
    dst = encode32u(dst, window_size_increment);
}