/* * Input: Mem_T structure, 32 bit word, unsigned segment index and an unsigned * offset * Output: void * Purpose: Puts a word into a segment in memory at index segIndex with an * offset. Used to execute the segmented store instruction and to put * put words into segment 0 during initialization */ void store_word(Mem_T memory, uint32_t word, unsigned segIndex, unsigned offset) { Seq_T segment = (Seq_T)Seq_get(memory->segment_seq, segIndex); assert(segment != NULL); Seq_put(segment, offset, (void *)(uintptr_t)word); Seq_put(memory->segment_seq, segIndex, segment); }
/* Creates a segment of desired size, intializes all words to 0 and returns the * identifier. */ ID_SIZE Segment_map(T seg_memory, unsigned size) { //Invariant at work here in the 'if' case WORD_SIZE *seg = malloc(sizeof(WORD_SIZE) * (size + 1)); for (WORD_SIZE i = 0; i < (size + 1); i++) { seg[i] = 0; } assert(seg != NULL); seg[0] = size; ID_SIZE id, i; Seq_T segments = seg_memory->segments; Seq_T unmapped = seg_memory->unmapped_ids; ID_SIZE unmapped_length = Seq_length(unmapped); ID_SIZE segs_length = Seq_length(segments); /* If there aren't any more unmapped id's, we replenish the unmapped id * sequence with MAP_INCREMENT amount. */ if (unmapped_length == 0) { for (i = segs_length; i < segs_length + MAP_INCREMENT; i++) { Seq_addhi(unmapped, (void *)(uintptr_t)i); } } id = (ID_SIZE)(uintptr_t)Seq_remlo(unmapped); if (id >= segs_length) { Seq_addhi(segments, seg); } else { Seq_put(segments, id, seg); } return id; }
/* * Input: Mem_T structure, unsigned integer * Output: returns the index at which the segment was stored. * Purpose: Adds a segment to memory with numWords words. */ int map_segment(Mem_T memory, unsigned numWords) { int segIndex; int reusedTest = 0; if(Seq_length(memory->reusable_indices) > 0){ segIndex = (int)(intptr_t)Seq_remlo(memory->reusable_indices); reusedTest = 1; } else segIndex = Seq_length(memory->segment_seq); Seq_T segment = Seq_new(numWords); uint32_t initializer = 0; for(unsigned i = 0; i < numWords; i++){ Seq_addhi(segment, (void *)(uintptr_t)initializer); } if(reusedTest) { Seq_put(memory->segment_seq, segIndex, segment); } else { Seq_addhi(memory->segment_seq, segment); } return segIndex; }
static void copy_segment_to_m0(UM_machine machine, UM_segment_ID segment_ID) { Seq_T mapped_segments = machine->address_space->mapped_segments; UM_segment temp = Seq_get(mapped_segments, segment_ID); int temp_length = UArray_length(temp->words); UM_segment duplicate = get_new_segment_of_size(temp_length); /* copy words into the new segment */ for(int i=0; i<temp_length; i++){ UM_word *word_i_p = UArray_at(temp->words, i); UM_word *duplicate_word_i_p = UArray_at(duplicate->words, i); *duplicate_word_i_p = *word_i_p; } duplicate->ID = 0; /* free the old program segment */ UM_segment program = Seq_get(mapped_segments, 0); free_segment_memory(&program); /* put the duplicate segment in the place of the old program segment */ Seq_put(mapped_segments, 0, duplicate); /* update num_instructions */ machine->num_instructions = temp_length; }
/* Unmaps identified segment from memory, allows unchecked runtime error if * segment doesn't exist. */ void Segment_unmap(T seg_memory, ID_SIZE id) { WORD_SIZE *temp; Seq_addlo(seg_memory->unmapped_ids, (void *)(uintptr_t)id); temp = Seq_get(seg_memory->segments, id); free(temp); Seq_put(seg_memory->segments, id, NULL); }
/* deletes the memory contained in a segment and replaces it with a new sequence */ bool clear_seg(Segment s, uint32_t ID) { TRY assert(s); UArray_T to_rmv = Seq_put(s, ID, UArray_new(0, sizeof(uint32_t))); UArray_free(&to_rmv); EXCEPT(Mem_Failed) return false; END_TRY; return true; }
/* * Helper function: Takes in a segment manager and a segment to insert, grabs * an id to associate with that segment, and puts it in the * table. * Parameters: sm - Segment Manager struct * segment - Segment to insert * Return value: The id of the newly inserted segment */ unsigned insert_Segment(Segment_Manager sm, Segment segment) { unsigned id; if (Seq_length(sm->ID_Stack) != 0) { id = (unsigned)(uintptr_t)Seq_remhi(sm->ID_Stack); Seq_put(sm->Segment_Table, id, segment); } else { Seq_addhi(sm->Segment_Table, segment); id = sm->ID_counter; sm->ID_counter++; } return id; }
/* * Input: Mem_T structure, unsigned integer * Ouput: void * Purpose: Copies the segment located at segIndex and stores it in segment 0 * The segment previously at index 0 is freed. */ void load_program(Mem_T memory, unsigned segIndex) { /*Segment that will become new program*/ Seq_T program_to_load_temp = Seq_get(memory->segment_seq, segIndex); int length = Seq_length(program_to_load_temp); /*New sequence that will be put in segment 0*/ Seq_T program_to_load = Seq_new(length); /*Copies program_to_load_temp to program_to_load*/ for(int i = 0; i < length; i++) { Seq_addhi(program_to_load, Seq_get(program_to_load_temp, i)); } Seq_T old_program = Seq_put(memory->segment_seq, 0, program_to_load); Seq_free(&old_program); }
/* * create a segment with the size of nums, and return the index of the segs of * the mapped segment. There are two conditons, if the unmapped stack is not * empty, we reuse the segment index stored in unmapped stack and pop that out. * otherwise we just create a new segments and addhi into segs, the return index * is the length of segs. */ uint32_t map_segment(Mem myMem, uint32_t nums) { assert(myMem != NULL); Segment_T newSeg = Seg_new(nums); for (uint32_t i = 0; i < nums; i++) { Seq_addhi((Seq_T)newSeg, (void*) (uintptr_t) 0); } uint32_t index; if (Stack_empty(myMem->unmapped) == 1) { Seq_addhi(myMem->segs, (void*) newSeg); index = Seq_length(myMem->segs) - 1; } else { index = (int) (uintptr_t) Stack_pop(myMem->unmapped); Seg_free(Seq_put(myMem->segs, index, (void*) newSeg)); }; return index; }
/* * Input: Mem_T structure, unsigned integer * Output: void * Purpose: Unmaps a segment from memory at the given segment index and frees * all memory associated with it. */ void unmap_segment(Mem_T memory, unsigned segIndex) { Seq_T unmapped_segment = Seq_put(memory->segment_seq, segIndex, NULL); Seq_free(&unmapped_segment); Seq_addhi(memory->reusable_indices, (void *)(intptr_t)segIndex); }
static inline void put_inst(Seq_T stream, int i, Um_instruction inst) { assert(sizeof(inst) <= sizeof(uintptr_t)); Seq_put(stream, i, (void *)(uintptr_t) inst); }
/* * Unmaps the segment at the specified ID, freeing the associated memory * Parameters: sm - Segment manager struct * id - ID of segment to unmap */ void unmap_Segment(Segment_Manager sm, unsigned id) { Segment segment = Seq_put(sm->Segment_Table, id, NULL); UArray_free(&segment); Seq_addhi(sm->ID_Stack, (void*)(uintptr_t)id); }