forked from remzi-arpacidusseau/ostep-homework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsegmentation.py
executable file
·183 lines (154 loc) · 6.87 KB
/
segmentation.py
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#! /usr/bin/env python
from __future__ import print_function
import sys
from optparse import OptionParser
import random
import math
# to make Python2 and Python3 act the same -- how dumb
def random_seed(seed):
try:
random.seed(seed, version=1)
except:
random.seed(seed)
return
def convert(size):
length = len(size)
lastchar = size[length-1]
if (lastchar == 'k') or (lastchar == 'K'):
m = 1024
nsize = int(size[0:length-1]) * m
elif (lastchar == 'm') or (lastchar == 'M'):
m = 1024*1024
nsize = int(size[0:length-1]) * m
elif (lastchar == 'g') or (lastchar == 'G'):
m = 1024*1024*1024
nsize = int(size[0:length-1]) * m
else:
nsize = int(size)
return nsize
def abort_if(condition, message):
if condition:
print('Error:', message)
exit(1)
return
#
# main program
#
parser = OptionParser()
parser.add_option("-s", "--seed", default=0, help="the random seed", action="store", type="int", dest="seed")
parser.add_option("-A", "--addresses", default="-1", help="a set of comma-separated pages to access; -1 means randomly generate", action="store", type="string", dest="addresses")
parser.add_option("-a", "--asize", default="1k", help="address space size (e.g., 16, 64k, 32m, 1g)", action="store", type="string", dest="asize")
parser.add_option("-p", "--physmem", default="16k", help="physical memory size (e.g., 16, 64k, 32m, 1g)", action="store", type="string", dest="psize")
parser.add_option("-n", "--numaddrs", default=5, help="number of virtual addresses to generate", action="store", type="int", dest="num")
parser.add_option("-b", "--b0", default="-1", help="value of segment 0 base register", action="store", type="string", dest="base0")
parser.add_option("-l", "--l0", default="-1", help="value of segment 0 limit register", action="store", type="string", dest="len0")
parser.add_option("-B", "--b1", default="-1", help="value of segment 1 base register", action="store", type="string", dest="base1")
parser.add_option("-L", "--l1", default="-1", help="value of segment 1 limit register", action="store", type="string", dest="len1")
parser.add_option("-c", help="compute answers for me", action="store_true", default=False, dest="solve")
(options, args) = parser.parse_args()
print('ARG seed', options.seed)
print('ARG address space size', options.asize)
print('ARG phys mem size', options.psize)
print('')
random_seed(options.seed)
asize = convert(options.asize)
psize = convert(options.psize)
addresses = str(options.addresses)
abort_if(psize <= 4, 'must specify a bigger physical memory size')
abort_if(asize == 0, 'must specify a non-zero address-space size')
abort_if(psize <= asize, 'physical memory size > address space size (for this simulation)')
#
# need to generate base, bounds for segment registers
#
len0 = convert(options.len0)
len1 = convert(options.len1)
base0 = convert(options.base0)
base1 = convert(options.base1)
# if randomly generating length, make it 1/4-1/2 the address space size (roughly)
if len0 == -1:
len0 = int(asize/4.0 + (asize/4.0 * random.random()))
if len1 == -1:
len1 = int(asize/4.0 + (asize/4.0 * random.random()))
if base0 == -1 or base1 == -1:
# this restriction just makes it easier to place randomly-placed segments
abort_if(psize <= 2 * asize, 'physical memory must be 2x GREATER than address space size (if randomly generating base registers)')
# if randomly generate base, have to find room for them
if base0 == -1:
done = 0
while done == 0:
base0 = int(psize * random.random())
if (base0 + len0) < psize:
done = 1
# internally, base1 points to the lower address, and base1+len1 the higher address
# (this differs from what the user would pass in)
if base1 == -1:
done = 0
while done == 0:
base1 = int(psize * random.random())
if (base1 + len1) < psize:
if (base1 > (base0 + len0)) or ((base1 + len1) < base0):
done = 1
else:
base1 = base1 - len1
abort_if(psize < base0 + len0 - 1, 'seg0 is not in physical memory')
abort_if(psize < base1, 'seg1 is not in physical memory')
abort_if(len0 > asize/2.0, 'length0 register is too large for this address space')
abort_if(len1 > asize/2.0, 'length1 register is too large for this address space')
print('Segment register information:')
print('')
print(' Segment 0 base (grows positive) : 0x%08x (decimal %d)' % (base0, base0))
print(' Segment 0 limit : %d' % (len0))
print('')
print(' Segment 1 base (grows negative) : 0x%08x (decimal %d)' % (base1+len1, base1+len1))
print(' Segment 1 limit : %d' % (len1))
print('')
nbase1 = base1 + len1
abort_if((len0 + base0) > base1 and (base1 > base0), 'segments overlap in physical memory')
addrList = []
if addresses == '-1':
# need to generate addresses
for i in range(0, options.num):
n = int(asize * random.random())
addrList.append(n)
else:
addrList = addresses.split(',')
#
# now, need to generate virtual address trace
#
print('Virtual Address Trace')
i = 0
for vstr in addrList:
vaddr = int(vstr)
if vaddr < 0 or vaddr >= asize:
print('Error: virtual address %d cannot be generated in an address space of size %d' % (vaddr, asize))
exit(1)
if options.solve == False:
print(' VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr))
else:
paddr = 0
if (vaddr >= (asize / 2)):
# seg 1
# [base1+len1] [negative offset]
paddr = nbase1 + (vaddr - asize)
if paddr < base1:
print(' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG1)' % (i, vaddr, vaddr))
else:
print(' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG1: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr))
else:
# seg 0
if (vaddr >= len0):
print(' VA %2d: 0x%08x (decimal: %4d) --> SEGMENTATION VIOLATION (SEG0)' % (i, vaddr, vaddr))
else:
paddr = vaddr + base0
print(' VA %2d: 0x%08x (decimal: %4d) --> VALID in SEG0: 0x%08x (decimal: %4d)' % (i, vaddr, vaddr, paddr, paddr))
i += 1
print('')
if options.solve == False:
print('For each virtual address, either write down the physical address it translates to')
print('OR write down that it is an out-of-bounds address (a segmentation violation). For')
print('this problem, you should assume a simple address space with two segments: the top')
print('bit of the virtual address can thus be used to check whether the virtual address')
print('is in segment 0 (topbit=0) or segment 1 (topbit=1). Note that the base/limit pairs')
print('given to you grow in different directions, depending on the segment, i.e., segment 0')
print('grows in the positive direction, whereas segment 1 in the negative. ')
print('')