-
Notifications
You must be signed in to change notification settings - Fork 1
/
segment.c
158 lines (148 loc) · 4.07 KB
/
segment.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* By: Alex Shankland and Aditya Hurry
* Date:11/23/15
* Project 6: Universal Machine
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include "seq.h"
#include "uarray.h"
#include "segment.h"
/*
* 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;
}
/*
* Effectively a constructor for the Segment_Manager struct
* Return value: An initialized Segment_Manager
*/
Segment_Manager new_Manager()
{
Seq_T Segment_Table = Seq_new(8);
Seq_T ID_Stack = Seq_new(8);
unsigned ID_counter = 0;
Segment_Manager manager = (Segment_Manager)malloc(
sizeof(struct Segment_Manager));
assert(manager);
manager->Segment_Table = Segment_Table;
manager->ID_Stack = ID_Stack;
manager->ID_counter = ID_counter;
return manager;
}
/*
* Creates a new segment of length given as a parameter
* Parameters: sm - Segment manager struct
* length - length of segment to create
*/
unsigned map_Segment(Segment_Manager sm, int length)
{
Segment segment = (Segment)UArray_new(length, sizeof(uint32_t));
for (int i=0; i<length; i++)
{
*((uint32_t *)UArray_at(segment, i)) = 0;
}
unsigned id = insert_Segment(sm, segment);
return id;
}
/*
* 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);
}
/*
* Copies and inserts the segment at the given ID into the Segment_Table
* Parameters: sm - Segment manager struct
* id - ID of segment to copy
* Return value: The id of the newly inserted segment
*/
unsigned copy_Segment(Segment_Manager sm, unsigned id)
{
Segment original = Seq_get(sm->Segment_Table, id);
unsigned length = UArray_length(original);
Segment copy = UArray_copy(original, length);
return insert_Segment(sm, copy);
}
/*
* Sets the value of segment[id][offset] to the given value
* Parameters: sm - Segment manager struct
* id - ID of segment to set
* offset - Offset within the segment
* value - Value to set
* Return value: the old value of the specified segment[id][offset]
*/
uint32_t seg_Set(Segment_Manager sm,
unsigned id,
unsigned offset,
uint32_t value)
{
uint32_t old_value;
Segment segment = Seq_get(sm->Segment_Table, id);
uint32_t *location = UArray_at(segment, offset);
old_value = *location;
*location = value;
return old_value;
}
/*
* Gets the value at segment[id][offset]
* Parameters: sm - Segment manager struct
* id - ID of segment to get from
* offset - Offset of segment[ID] to get from
* Return Value: The value at segment[id][offset]
*/
uint32_t seg_Get(Segment_Manager sm, unsigned id, unsigned offset)
{
Segment segment = Seq_get(sm->Segment_Table, id);
return *(uint32_t*)UArray_at(segment, offset);
}
/*
* Frees all the memory associated with the Segment Manager
* Parameter: sm - The Segment Manager Struct
*/
void segment_Free(Segment_Manager sm)
{
Segment nextsegment;
while (Seq_length(sm->Segment_Table) != 0) {
nextsegment = (UArray_T)Seq_remhi(sm->Segment_Table);
if (nextsegment != NULL)
UArray_free(&nextsegment);
};
Seq_free(&(sm->Segment_Table));
Seq_free(&(sm->ID_Stack));
free(sm);
return;
}
/*
* Returns the pointer to the code, which must live in segment[0]
*/
void *get_Code(Segment_Manager sm)
{
return Seq_get(sm->Segment_Table, 0);
}