diff -u python.ORIG/disk.py python/disk.py --- python.ORIG/disk.py 2021-03-01 13:09:07.000000000 -0500 +++ python/disk.py 2021-06-06 09:40:04.803631655 -0400 @@ -1,11 +1,20 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - comment out Tkinter import, no GUI in web version +# - comment out extraneous debug print statements +# - add -d,--dups option to avoid consecutive duplicate block requests +# - bugfix: change self.maxBlock initial value from pblock to block+1 +# - bugfix: in MakeRequests, convert list from string to int when addr != -1, +# otherwise -l doesn't work + from __future__ import print_function from __future__ import division -try: - from Tkinter import * -except: - from tkinter import * +#no GUI in web version +#try: +# from Tkinter import * +#except: +# from tkinter import * from types import * import math, random, time, sys, os from optparse import OptionParser @@ -276,14 +285,14 @@ zones = self.zoning.split(',') assert(len(zones) == 3) for i in range(len(zones)): - print('z', i, zones[i]) + #print('z', i, zones[i]) self.blockAngleOffset.append(int(zones[i]) // 2) track = 0 # outer track angleOffset = 2 * self.blockAngleOffset[track] for angle in range(0, 360, angleOffset): block = angle // angleOffset - print(track, angleOffset, block) + #print(track, angleOffset, block) self.blockToTrackMap[block] = track self.blockToAngleMap[block] = angle self.blockInfoList.append((track, angle, block)) @@ -295,7 +304,7 @@ angleOffset = 2 * self.blockAngleOffset[track] for angle in range(0, 360, angleOffset): block = (angle // angleOffset) + pblock - print(track, skew, angleOffset, block) + #print(track, skew, angleOffset, block) self.blockToTrackMap[block] = track self.blockToAngleMap[block] = angle + (angleOffset * skew) self.blockInfoList.append((track, angle + (angleOffset * skew), block)) @@ -307,12 +316,12 @@ angleOffset = 2 * self.blockAngleOffset[track] for angle in range(0, 360, angleOffset): block = (angle // angleOffset) + pblock - print(track, skew, angleOffset, block) + #print(track, skew, angleOffset, block) self.blockToTrackMap[block] = track self.blockToAngleMap[block] = angle + (angleOffset * skew) self.blockInfoList.append((track, angle + (angleOffset * skew), block)) self.tracksBeginEnd[track] = (pblock, block) - self.maxBlock = pblock + self.maxBlock = block + 1 # print 'MAX BLOCK:', self.maxBlock # adjust angle to starting position relative @@ -335,11 +344,19 @@ maxRequest = self.maxBlock # now make list tmpList = [] + prev = -1 for i in range(numRequests): - tmpList.append(int(random.random() * maxRequest) + minRequest) + cur = int(random.random() * maxRequest) + minRequest + while options.dups and cur == prev: cur = int(random.random() * maxRequest) + minRequest + tmpList.append(cur) + prev = cur + return tmpList + else: # convert list from string to int, otherwise -l doesn't work + slist = addr.split(',') + tmpList = [] + for s in slist: + tmpList.append(int(s)) return tmpList - else: - return addr.split(',') # # BUTTONS @@ -723,6 +740,10 @@ parser.add_option('-l', '--lateAddr', default='-1', help='Late: request list (comma-separated) [-1 -> random]', action='store', type='string', dest='lateAddr') parser.add_option('-L', '--lateAddrDesc', default='0,-1,0', help='Num requests, max request (-1->all), min request', action='store', type='string', dest='lateAddrDesc') parser.add_option('-c', '--compute', default=False, help='Compute the answers', action='store_true', dest='compute') + +parser.add_option('-d', '--dups', default=False, help='Avoid consecutive duplicates', + action='store_true', dest='dups') + (options, args) = parser.parse_args() print('OPTIONS seed', options.seed) @@ -738,6 +759,7 @@ print('OPTIONS zoning', options.zoning) print('OPTIONS lateAddr', options.lateAddr) print('OPTIONS lateAddrDesc', options.lateAddrDesc) +print('OPTIONS dups', options.dups) print('') if options.window == 0: diff -u python.ORIG/fsck.py python/fsck.py --- python.ORIG/fsck.py 2021-03-01 13:09:07.000000000 -0500 +++ python/fsck.py 2021-06-06 08:36:58.594298851 -0400 @@ -1,5 +1,11 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - when creating orphan ("new fake inode", num = 3 or 9) mark the inode as allocated +# - fix message for case where inode gets its type switched, +# could be "was type file, now dir" or "was type dir, now file". +# - in pickRandom(), handle case with no 'f' files (not good if num == 5 or num == 11) + from __future__ import print_function import random import string @@ -507,6 +513,8 @@ for i in range(len(self.inodes)): if self.inodes[i].getType() == match: inodes.append(i) + # handle case with no 'f' files (not good if num == 5 or num == 11): + if len(inodes) == 0 and match == 'f': return self.pickRandom('d') assert(len(inodes) > 0) return random_choice(inodes) @@ -561,6 +569,7 @@ elif num == 3 or num == 9: # create new fake inode badInode = self.pickRandom('free') + self.ibitmap.markAllocated(badInode); if self.solve: print('INODE %d orphan' % badInode) if num == 3: @@ -581,13 +590,13 @@ # normal inode gets its type switched if num == 5: badInode = self.pickRandom('f') - else: - badInode = self.pickRandom('d') - if self.solve: - print('INODE %d was type file, now dir' % badInode) - if num == 5: + if self.solve: + print('INODE %d was type file, now dir' % badInode) self.inodes[badInode].setType('d') else: + badInode = self.pickRandom('d') + if self.solve: + print('INODE %d was type dir, now file' % badInode) self.inodes[badInode].setType('f') elif num == 6: # corrupt a directory block by making one tuple refer to a BAD INODE diff -u python.ORIG/malloc.py python/malloc.py --- python.ORIG/malloc.py 2021-03-01 13:09:07.000000000 -0500 +++ python/malloc.py 2021-06-06 08:35:04.515332700 -0400 @@ -1,5 +1,8 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - change end='' to end=' ' in two places for compatibility with older version + from __future__ import print_function import random from optparse import OptionParser @@ -135,7 +138,7 @@ def dump(self): print('Free List [ Size %d ]: ' % len(self.freelist), end='') for e in self.freelist: - print('[ addr:%d sz:%d ]' % (e[0], e[1]), end='') + print('[ addr:%d sz:%d ]' % (e[0], e[1]), end=' ') print('') @@ -209,7 +212,7 @@ # pick random one to delete d = int(random.random() * len(L)) rc = m.free(p[L[d]]) - print('Free(ptr[%d])' % L[d], ) + print('Free(ptr[%d])' % L[d], end=' ') if options.solve == True: print('returned %d' % rc) else: diff -u python.ORIG/mlfq.py python/mlfq.py --- python.ORIG/mlfq.py 2021-03-01 13:09:07.000000000 -0500 +++ python/mlfq.py 2021-06-06 08:38:44.274046617 -0400 @@ -1,5 +1,9 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - add options: maxstart, minlen, minio +# - bugfix: with boost, job ticksLeft should be allotment TIMES quantum + from __future__ import print_function import sys from optparse import OptionParser @@ -83,6 +87,16 @@ parser.add_option('-c', help='compute answers for me', action='store_true', default=False, dest='solve') +parser.add_option('--maxstart', default=0, help='max start-time of a job ' + + '(if randomly generating)', action='store', type='int', + dest='maxstart') +parser.add_option('--minlen', default=1, help='min run-time of a job ' + + '(if randomly generating)', action='store', type='int', + dest='minlen') +parser.add_option('--minio', default=1, + help='min I/O frequency of a job (if randomly generating)', + action='store', type='int', dest='minio') + (options, args) = parser.parse_args() random.seed(options.seed) @@ -160,9 +174,9 @@ else: # do something random for j in range(options.numJobs): - startTime = 0 - runTime = int(random.random() * (options.maxlen - 1) + 1) - ioFreq = int(random.random() * (options.maxio - 1) + 1) + startTime = int(random.random() * options.maxstart) + runTime = int(random.random() * (options.maxlen - options.minlen) + options.minlen) + ioFreq = int(random.random() * (options.maxio - options.minio) + options.minio) job[jobCnt] = {'currPri':hiQueue, 'ticksLeft':quantum[hiQueue], 'allotLeft':allotment[hiQueue], 'startTime':startTime, @@ -246,7 +260,7 @@ if job[j]['timeLeft'] > 0: # print('-> FinalBoost %d (timeLeft %d)' % (j, job[j]['timeLeft'])) job[j]['currPri'] = hiQueue - job[j]['ticksLeft'] = allotment[hiQueue] + job[j]['ticksLeft'] = allotment[hiQueue] * quantum[hiQueue] # print('BOOST END: QUEUES look like:', queue) # check for any I/Os done diff -u python.ORIG/paging-linear-translate.py python/paging-linear-translate.py --- python.ORIG/paging-linear-translate.py 2021-03-01 13:09:07.000000000 -0500 +++ python/paging-linear-translate.py 2021-06-06 08:39:43.671591005 -0400 @@ -1,5 +1,10 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - make virtual address always odd, so physical address will never be 0, +# and PA 0 can be used to mark an invalid virtual address. +# - always print 0x in front of hex. + from __future__ import print_function import sys from optparse import OptionParser @@ -156,7 +161,7 @@ if addresses == '-1': # need to generate addresses for i in range(0, options.num): - n = int(asize * random.random()) + n = int(asize * random.random()) | 1 addrList.append(n) else: addrList = addresses.split(',') @@ -178,7 +183,7 @@ pfn = pt[vpn] offset = vaddr & pagemask paddr = (pfn << pagebits) | offset - print(' VA 0x%08x (decimal: %8d) --> %08x (decimal %8d) [VPN %d]' % (vaddr, vaddr, paddr, paddr, vpn)) + print(' VA 0x%08x (decimal: %8d) --> 0x%08x (decimal %8d) [VPN %d]' % (vaddr, vaddr, paddr, paddr, vpn)) print('') if options.solve == False: diff -u python.ORIG/paging-multilevel-translate.py python/paging-multilevel-translate.py --- python.ORIG/paging-multilevel-translate.py 2021-03-01 13:09:07.000000000 -0500 +++ python/paging-multilevel-translate.py 2021-06-06 08:41:23.791194199 -0400 @@ -1,5 +1,11 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - make virtual address always odd, so physical address will never be 0, +# and PA 0 can be used to indicate an invalid virtual address. +# - print memory dump column headings +# - print page numbers and PDBR in hex + from __future__ import print_function import sys from optparse import OptionParser @@ -193,11 +199,19 @@ print(self.memory[(i * self.pageSize) + j], end='') print('') + def colheadings(self): + print(' ', end='') + for j in range(0, self.pageSize): + print('%02x ' % j, end='') + print('') + def memoryDump(self): + print(' offset:') for i in range(0, int(self.physMem / self.pageSize)): - print('page %3d:' % i, end='') + if i % 16 == 0: self.colheadings() + print('page %02x: ' % i, end='') for j in range(0, self.pageSize): - print('%02x' % self.memory[(i * self.pageSize) + j], end='') + print('%02x ' % self.memory[(i * self.pageSize) + j], end='') print('') def getPDBR(self, pid): @@ -243,13 +257,13 @@ os.memoryDump() -print('\nPDBR:', os.getPDBR(1), ' (decimal) [This means the page directory is held in this page]\n') +print('\nPDBR:', '%02x' % os.getPDBR(1), ' [This means the page directory is held in this page]\n') for i in range(0, options.num): if (random.random() * 100) > 50.0 or i >= len(used): - vaddr = int(random.random() * 1024 * 32) + vaddr = int(random.random() * 1024 * 32) | 1 else: - vaddr = (used[i] << 5) | int(random.random() * 32) + vaddr = (used[i] << 5) | int(random.random() * 32) | 1 if options.solve == True: print('Virtual Address %04x:' % vaddr) r = os.translate(1, vaddr) diff -u python.ORIG/raid.py python/raid.py --- python.ORIG/raid.py 2021-03-01 13:09:07.000000000 -0500 +++ python/raid.py 2021-06-06 09:38:59.079927359 -0400 @@ -1,5 +1,8 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - add -d,--dups option to avoid duplicate addresses + from __future__ import print_function import math import random @@ -376,6 +379,9 @@ parser.add_option('-t', '--timing', default=False, help='use timing mode, instead of mapping mode', action='store_true', dest='timing') parser.add_option('-c', '--compute', default=False, help='compute answers for me', action='store_true', dest='solve') +parser.add_option('-d', '--dups', default=False, help='avoid duplicate addresses', + action='store_true', dest='dups') + (options, args) = parser.parse_args() print('ARG blockSize', BLOCKSIZE) @@ -391,11 +397,14 @@ print('ARG raid5', options.raid5type) print('ARG reverse', options.reverse) print('ARG timing', options.timing) +print('ARG dups', options.dups) print('') writeFrac = float(options.writeFrac) / 100.0 assert(writeFrac >= 0.0 and writeFrac <= 1.0) +assert( not options.dups or options.numRequests < options.range) + random_seed(options.seed) size = convert(options.size) @@ -427,12 +436,15 @@ # generate requests off = 0 +blkList = [] for i in range(options.numRequests): if workloadIsSequential == True: blk = off off += size else: blk = int(random.random() * options.range) + while options.dups and blk in blkList: blk = int(random.random() * options.range) + blkList.append(blk) if random.random() < writeFrac: print(blk, size) r.enqueue(blk, size, True) diff -u python.ORIG/relocation.py python/relocation.py --- python.ORIG/relocation.py 2021-03-01 13:09:07.000000000 -0500 +++ python/relocation.py 2021-06-06 08:44:40.197300930 -0400 @@ -1,5 +1,10 @@ #! /usr/bin/env python +# RP 2021-06-06, change some limits: +# - asize*7/16 <= limit < asize*9/16 +# - vaddr >= 1 +# - base + asize < psize + from __future__ import print_function import sys from optparse import OptionParser @@ -75,14 +80,14 @@ base = convert(options.base) if limit == -1: - limit = int(asize/4.0 + (asize/4.0 * random.random())) + limit = int(7.0*asize/16.0 + (asize/8.0 * random.random())) # now have to find room for them if base == -1: done = 0 while done == 0: base = int(psize * random.random()) - if (base + limit) < psize: + if (base + asize) < psize: done = 1 print('Base-and-Bounds register information:') @@ -101,7 +106,7 @@ # print('Virtual Address Trace') for i in range(0,options.num): - vaddr = int(asize * random.random()) + vaddr = 1 + int((asize-1) * random.random()) if options.solve == False: print(' VA %2d: 0x%08x (decimal: %4d) --> PA or segmentation violation?' % (i, vaddr, vaddr)) else: diff -u python.ORIG/segmentation.py python/segmentation.py --- python.ORIG/segmentation.py 2021-03-01 13:09:07.000000000 -0500 +++ python/segmentation.py 2021-06-06 09:39:43.164070516 -0400 @@ -1,5 +1,8 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - make vaddr non-zero + from __future__ import print_function import sys from optparse import OptionParser @@ -129,7 +132,7 @@ if addresses == '-1': # need to generate addresses for i in range(0, options.num): - n = int(asize * random.random()) + n = 1 + int((asize-1) * random.random()) addrList.append(n) else: addrList = addresses.split(',') diff -u python.ORIG/ssd.py python/ssd.py --- python.ORIG/ssd.py 2021-03-01 13:09:07.000000000 -0500 +++ python/ssd.py 2021-06-06 08:48:35.659423150 -0400 @@ -1,5 +1,8 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - set ftl_columns = 1000 so FTL list will always print on one line + from __future__ import print_function from collections import * from optparse import OptionParser @@ -373,7 +376,8 @@ # FTL print('FTL ', end='') count = 0 - ftl_columns = int((self.pages_per_block * self.num_blocks) / 7) + # make FTL list print on one line + ftl_columns = 1000 # int((self.pages_per_block * self.num_blocks) / 7) for i in range(self.num_logical_pages): if self.forward_map[i] == -1: continue diff -u python.ORIG/vsfs.py python/vsfs.py --- python.ORIG/vsfs.py 2021-03-01 13:09:07.000000000 -0500 +++ python/vsfs.py 2021-06-06 08:53:42.788408772 -0400 @@ -1,5 +1,9 @@ #! /usr/bin/env python +# RP 2021-06-06: +# - change end='' to end=' ' in five places for compatibility with older version +# - when writing data, show the data value, otherwise can't answer the question + from __future__ import print_function import random from optparse import OptionParser @@ -214,18 +218,18 @@ def dump(self): print('inode bitmap ', self.ibitmap.dump()) - print('inodes ', end='') + print('inodes ', end=' ') for i in range(0,self.numInodes): ftype = self.inodes[i].getType() if ftype == 'free': - print('[]', end='') + print('[]', end=' ') else: - print('[%s a:%s r:%d]' % (ftype, self.inodes[i].getAddr(), self.inodes[i].getRefCnt()), end='') + print('[%s a:%s r:%d]' % (ftype, self.inodes[i].getAddr(), self.inodes[i].getRefCnt()), end=' ') print('') print('data bitmap ', self.dbitmap.dump()) - print('data ', end='') + print('data ', end=' ') for i in range(self.numData): - print(self.data[i].dump(), end='') + print(self.data[i].dump(), end=' ') print('') def makeName(self): @@ -389,7 +393,7 @@ self.data[fblock].addData(data) self.inodes[inum].setAddr(fblock) if printOps: - print('fd=open("%s", O_WRONLY|O_APPEND); write(fd, buf, BLOCKSIZE); close(fd);' % tfile) + print('fd=open("%s", O_WRONLY|O_APPEND); write(fd, "%c", BLOCKSIZE); close(fd);' % (tfile,data)) return 0 def doDelete(self):