diff --git a/CH/readme.md b/CH/readme.md deleted file mode 100644 index e69de29..0000000 diff --git a/CH/CH_sim.py b/Deprecated/CH/CH_sim.py similarity index 100% rename from CH/CH_sim.py rename to Deprecated/CH/CH_sim.py diff --git a/Deprecated/LLS/sim_connectLLStoCH.py b/Deprecated/LLS/sim_connectLLStoCH.py new file mode 100644 index 0000000..235a596 --- /dev/null +++ b/Deprecated/LLS/sim_connectLLStoCH.py @@ -0,0 +1,298 @@ +import math +import random +from LLS import * +from createfiles import createFiles, initFiles + +MAX_DSAST_OFFSET = 0 +dsastlist = [] + +class cache: + def __init__(self, level): + self.level = level + self.ways = 4 + self.line_size = 6 + self.level + self.level + self.block_size = int((2) * math.pow(4, self.level)) ##Block size in word L1 = 2 word L2 is 8 word + self.block_shift = 1 + self.level * 2 + self.reserve_bit = 2 + 4 * self.level + if(self.level == 0): + self.direct_size = 8 + elif(self.level == 1): + self.direct_size = 12 + elif(level == 2): + self.direct_size = 22 + elif(self.level == 3): + self.direct_size = 5 #26 # L4 #self.cache_size - log2(self.ways) #10 + elif(self.level == 4): + self.direct_size = 8 #27 # L5 #self.cache_size - log2(self.ways) #10 + self.up = level - 1 + self.down = level + 1 + self.cache_mask = (1 << (self.line_size + self.block_shift + 2 )) - 1 + self.block_mask = (self.block_size) - 1 + self.line_tag = [[0 for y in range(self.ways)] for x in range(1 << self.line_size)] #[0] * (1 << self.cache_size) + self.tag_offset = 2 + self.block_shift + self.line_size #here might be an issue + #Data segment of cache block TODO:Need change so that I can access word on each offset (set the block as word) + self.line_data = [[[0 for z in range(self.block_size)] for y in range(self.ways)] for x in range(1 << self.line_size)] #[0] * (1 << self.cache_size) + #Dirty Bit and invalid bit segment of cache block + #0 means valid non dirty, 1 means valid dirty, 2 mean invalid cache_line + self.line_state = [[0 for y in range(self.ways)] for x in range(1 << self.line_size)] #[0] * (1 << self.cache_size) + for i in range(0, self.ways): + for j in range(0, 1 << self.line_size): + self.line_state[j][i] = 2 + + def index(self, addr): + return ((addr) & self.cache_mask) >> (self.block_shift + 2) + + def block(self, addr): + return (addr >> 2) & self.block_mask + + def get_way(self, addr): + hit_way = -1 + idx = self.index(addr) + for i in range(self.ways): + if((addr >> self.tag_offset) == self.line_tag[idx][i]): + hit_way = i + return hit_way + + def lookup(self, addr): + idx = self.index(addr) + return_way = self.get_way(addr) + if return_way != -1 : + return self.line_state[idx][return_way] != 2 + else: + return False + + def find_way(self, addr, idx): + way_list = [] + for i in range(0, self.ways): + if(self.line_state[idx][i] != 1) : + way_list.append(i) + if(len(way_list) > 0): + return random.choice(way_list) + return random.randint(0, self.ways - 1) + + def replace(self,addr): + global MAX_DSAST_OFFSET + global dsastlist + x = self.index(addr) + block_index = self.block(addr) + way_to_replace = self.find_way(addr, x) + if(self.line_state[x][way_to_replace] == 1): + if(self.level != 4): + for i in range(0, self.block_size): + block_addr = addr & ~(self.block_mask << 2) ^ (i << 2) # need testing + caches[self.down].put(addr, self.line_data[x][way_to_replace][i]) + self.line_state[x][way_to_replace] = 0 + else: + for i in range(0, self.block_size): + block_addr = addr & ~(self.block_mask << 2) ^ (i << 2) # need testing + # NOTE: for now, consider bits 31:0 as the offset of the DSAST until we extend the + # cache address to 72 bits. 63:32 is the DSAST + adsast_offset = block_addr & 0x0000FFFF + global_dsast = DSAST(address=block_addr, wayLimit=way_to_replace, lineLimit=self.line_size, size=1, offset=adsast_offset) + # line_data[x][way_to_replace][i] = writeLLS(global_dsast, line_data[x][way_to_replace][i]) + if(global_dsast.offset > MAX_DSAST_OFFSET): + MAX_DSAST_OFFSET = global_dsast.offset + writeLLS(global_dsast, 0x5555) + found = 0 + for dsast in dsastlist: + if(global_dsast.dsast == dsast): + found = 1 + break + if not found: + dsastlist.append(global_dsast.dsast) + # print("Writing to LLS, line: {}".format(line_data[x][way_to_replace][i])) + # caches[self.down].put(line_tag[x][way_to_replace],line_data[x][way_to_replace][block_index]) + # + #caches[self.down].put(addr, self.line_data[x][way_to_replace][block_addr]) + # print("Miss in all Cache Levels. Going to LLS, dirty data", self.line_data[x][way_to_replace][block_addr], " is written") + self.line_state[x][way_to_replace] = 0 + + if(self.level != 4): + self.line_tag[x][way_to_replace] = addr >> self.tag_offset + # print("Replacing tag ", self.line_tag[x][way_to_replace]) + for i in range(0, self.block_size): + block_addr = addr & ~(self.block_mask << 2) ^ (i << 2) #need testing + self.line_data[x][way_to_replace][i] = caches[self.down].get(block_addr) + # print("Writing addr ", hex(addr), " with data ", self.line_data[x][way_to_replace][i], " among replacement in Cache level ", self.level) + else: + ##open the file , outbox for LLS, read, write req, out box + # print("Miss in all Cache Levels. Going to LLS, dummy data received") + #DSAST use = 71-50 bit of ADDR + #61-20 + # print("Block size {}".format(self.block_size)) + # 512 + for i in range(0, self.block_size): + block_addr = addr & ~(self.block_mask << 2) ^ (i << 2) # need testing + adsast_offset = block_addr & 0x0000FFFF + global_dsast = DSAST(address=block_addr, wayLimit=way_to_replace, lineLimit=self.line_size, size=1, offset=adsast_offset) + + if(global_dsast.offset > MAX_DSAST_OFFSET): + MAX_DSAST_OFFSET = global_dsast.offset + self.line_data[x][way_to_replace][i] = readLLS(global_dsast) + found = 0 + for dsast in dsastlist: + if(global_dsast.dsast == dsast): + found = 1 + break + if not found: + dsastlist.append(global_dsast.dsast) + # print("dsast: {}".format(global_dsast)) + # print("Reading from LLS, line: {}".format(self.line_data[x][way_to_replace][i])) + + self.line_state[x][way_to_replace] = 0 + self.line_tag[self.index(addr)][way_to_replace] = addr >> self.tag_offset + return way_to_replace + + def get(self, addr): + # print(addr) + if(not self.lookup(addr)): + # print("It's a miss in level", self.level) + #Miss list + miss[self.level] += 1 + insrt_way = self.replace(addr) + return self.line_data[self.index(addr)][insrt_way][self.block(addr)] + else: + # print("It's a hit in level ", self.level) + hits[self.level] += 1 + hit_way = self.get_way(addr) + return self.line_data[self.index(addr)][hit_way][self.block(addr)] + + def put(self,addr,data): + write_way = -1 + self.addr = addr + #self.data = data + if not self.lookup(self.addr): + insrt_way = self.replace(self.addr) + write_way = insrt_way + else: + write_way = self.get_way(addr) + print("Insert at index ",self.index(self.addr)) + self.line_data[self.index(addr)][write_way][self.block(addr)] = data + self.line_state[self.index(addr)][write_way] = 1 + print("Writing addr ", hex(addr), " with data " , data," among put in Cache level ", self.level, "at way ", write_way) + + def hit_rate(self): + print("Hit rate at level", self.level) + print(hits[0]) + print(" L1 Hit Rate = ", hits[0] /(hits[0] + miss[0])) + print(" L2 Hit Rate = ", hits[1] /(hits[1] + miss[1])) + print(" L3 Hit Rate = ", hits[2] /(hits[2] + miss[2])) + print(" L4 Hit Rate = ", hits[3] /(hits[3] + miss[3])) + if(hits[4] > 0): + print(" L5 Hit Rate = ", hits[4] /(hits[4] + miss[4])) + else: + print(" L5 Hit Rate = 0") + +# class LLScache: + +# def __init__(self, cache_size, block_size): +# #L2cache.i += 1 +# self.LLShits = 0 +# self.LLSmiss = 0 +# # def make_dsast(self, addr): +# # return(DSAST(size=0, index=addr, linelimit=0, waylimit=1)) + +# def get(self, addr): +# self.LLShits += 1 +# return readLLS(addr) +# # adsast = DSAST() + +# def put(self,addr,data): +# return writeLLS(addr, data) + +# def hit_count(self): +# print(" LLS Hits = ", self.LLShits) + + +caches = [] +miss = [] +hits = [] +global_dsast = DSAST() +mapBASTtoDSAST(global_dsast) +def main(): + createFiles(300) + initFiles(300, 80000) + + global caches + for i in range(5): + caches.append(cache(i)) + global miss + global hits + miss = [0 for x in range(5)] + hits = [0 for x in range(5)] + #filename = "gcc_ld_trace.txt" + input_addr = 0x1110 + print("test1") + caches[0].put(0x1110,230) #Do testing # Generate random address #Add another core # Generate rand addr # + #L1 block 0, index 34, tag 8 + #l2 block 8 index 68 , tag 0 + caches[0].put(0x1114,250) + caches[0].put(0x1118, 255) + caches[0].put(0x111C, 260) + print(caches[0].get(0x1110)) + print(caches[0].get(0x1114)) + print(caches[0].get(0x1118)) + print(caches[0].get(0x111C)) + caches[0].put(0x8001110, 1000) + caches[0].put(0x8001114,1024) + caches[0].put(0x8001118, 1034) + caches[0].put(0x800111C, 2000) + print(caches[0].get(0x8001110)) + print(caches[0].get(0x8001114)) + print(caches[0].get(0x8001118)) + print(caches[0].get(0x800111C)) + caches[0].put(0x4001110, 3000) + caches[0].put(0x4001114,3024) + caches[0].put(0x4001118, 3034) + caches[0].put(0x400111C, 3500) + print(caches[0].get(0x4001110)) + print(caches[0].get(0x4001114)) + print(caches[0].get(0x4001118)) + print(caches[0].get(0x400111C)) + caches[0].put(0xa001110, 5000) + caches[0].put(0xa001114,5024) + caches[0].put(0xa001118, 5034) + caches[0].put(0xa00111C, 5500) + print(caches[0].get(0xa001110)) + print(caches[0].get(0xa001114)) + print(caches[0].get(0xa001118)) + print(caches[0].get(0xa00111C)) + caches[0].put(0xd001110, 8000) + caches[0].put(0xd001114, 8024) + caches[0].put(0xd001118, 8034) + caches[0].put(0xd00111C, 8500) + print(caches[0].get(0xd001110)) + print(caches[0].get(0xd001114)) + print(caches[0].get(0xd001118)) + print(caches[0].get(0xd00111C)) + print(caches[0].get(0x1110)) + print(caches[0].get(0x1114)) + print(caches[0].get(0x1118)) + print(caches[0].get(0x111C)) +# with open("go_ld_trace.txt") as f: +# content = f.readlines() + # remove whitespace characters at the end of each line +# content = [x.strip() for x in content] + # for i in range(int(len(content))): + # caches[0].get(int(content[i], 16)) + caches[0].hit_rate() + print("Number of hits in L1", hits[0]) + print("Number of misses in L1", miss[0]) + print("Number of hits in L2", hits[1]) + print("Number of misses in L2", miss[1]) + print("Number of hits in L3", hits[2]) + print("Number of misses in L3", miss[2]) + print("Number of hits in L4", hits[3]) + print("Number of misses in L4", miss[3]) + print("Number of hits in L5", hits[4]) + print("Number of misses in L5", miss[4]) + + global MAX_DSAST_OFFSET + print("MAX_DSAST_OFFSET: {}".format(MAX_DSAST_OFFSET)) + + global dsastlist + for dsast in dsastlist: + print("dsast: {}".format(dsast)) +if __name__ == "__main__": + main() + diff --git a/Deprecated/LLS/test.py b/Deprecated/LLS/test.py new file mode 100644 index 0000000..8321984 --- /dev/null +++ b/Deprecated/LLS/test.py @@ -0,0 +1,142 @@ +from LLS import * +# TB for LLS +# Scenario based testing model. Create objects, write to them, open, close, read, write, etc... +# Make sure we can create objs and put data into them. Use 4 byte cache model for testing. +# After basic testing is implemented, randomize accesses. Add a list to keep track of BAS sizes. +# Test for invalid inputs (size is off etc.) to ensure it sends back msg to PMU/CH. +# Test case for gain a msg to retire bast + +# FNS LIST TO TEST +# mapBASTtoDSAST(dsast, gast) +# gastRequest(dsast) +# writeToBAST(dsast) # +# openFile(dsast, gast) # +# createFile(dsast) +# closeFile(dsast) # +# saveFile(dsast, permissions)# +# deleteFile(gast) +# getBASTfromDSAST(dsast) +# invalidateDSAST(dsast) # +# writeThrough(dsast, packet)# +# sendMsgRetire() # dummy implementation +# rcvOkToUnmap() # dummy implementation + +# GAST.duplicate() +# GAST.free() + +# BAST init when there is something in bastAvail list +# BAST.writeToFile() +# BAST.readFromFile() +# BAST.close() + + + +dsastList = [] # Lists of created DSASTS, mimmic PMU's knowledge of dsasts/gasts +gastList = [] # Lists of created GASTS + +def testFunc(func, funcname): + if(func==1): + print("{} success".format(funcname)) + else: + print("{} failed: {}".format(funcname, retval)) + +# Question: How to test saveFile? + +def testCreateFile(): + global sastBast + # create dsast to bast mapping + adsast = DSAST() + dsastList.append(adsast) + agast = GAST() + gastList.append(agast) + mapBASTtoDSAST(adsast, agast) + abast = bastTable[(agast.domain, agast.key)] + if not (sastBast[adsast] == abast): + return "Did not map DSAST to BAST from GAST reference" + + fp = abast.open() + string = "A"*50 + fp.write(string) + + # call create file to check if new bast is associated to given dsast + createFile(adsast) + if not (sastBast[adsast] != abast): + return "BASTS are the same after creating file" + + # check if second fp is valid + abast2 = getBASTfromDSAST(adsast) + fp2 = abast2.open() + string = "B"*50 + fp2.write(string) + if not (fp.name != fp2.name): + return "BAST file is the same after creating file" + + return 1 + +def testDeleteFile(): + global sastBast + if len(dsastList): + abast = getBASTfromDSAST(dsastList[0]) + agast = gastList[0] + else: + adsast = DSAST() + dsastList.append(adsast) + agast = GAST() + gastList.append(agast) + mapBASTtoDSAST(adsast, agast) + abast = bastTable[(agast.domain, agast.key)] + + deleteFile(agast) + if (agast.domain, agast.key) in bastTable.keys(): + print("deleteFile failed to unmap GAST to BAST") + return 0 + + # should the physical file referenced by the bast be deleted from the system as well? + # it is still innaccessible without an existing bast referencing it, so the next time + # something is written to that file it should just be overwritten, I assume, + # but need to confirm this + + return 1 + +def testReadWriteToFile(): + global dsastList + global gastList + + adsast = DSAST() + dsastList.append(adsast) + agast = GAST() + gastList.append(agast) + + # link dsast to a bast to be written + mapBASTtoDSAST(adsast, agast) + adsast.offset = 0 + writeToBAST(adsast) + abast = getBASTfromDSAST(adsast) + if not abast.readFromFile(0): + print("Nothing read from written bast") + return 0 + + return 1 + +def testInvalidate(): + if len(dsastList): + adsast = dsastList.pop() + invalidateDSAST(adsast) + global sastBast + try: + if(sastBast[adsast]): + print(" Did not unmap DSAST to BAST") + return 0 + except: + return 1 + + +def main(): + + testFunc(testCreateFile(), "testCreateFile()") + testFunc(testDeleteFile(), "testDeleteFile()") + testFunc(testReadWriteToFile(), "testReadWriteToFile()") + testFunc(testInvalidate(), "testInvalidate()") + +if __name__ == "__main__": + main() diff --git a/PMU/main.py b/Deprecated/PMU/main.py similarity index 100% rename from PMU/main.py rename to Deprecated/PMU/main.py diff --git a/PMU/process.py b/Deprecated/PMU/process.py similarity index 100% rename from PMU/process.py rename to Deprecated/PMU/process.py diff --git a/PMU/test.sh b/Deprecated/PMU/test.sh similarity index 100% rename from PMU/test.sh rename to Deprecated/PMU/test.sh diff --git a/Deprecated/SAL/SAL.py b/Deprecated/SAL/SAL.py new file mode 100644 index 0000000..29f1811 --- /dev/null +++ b/Deprecated/SAL/SAL.py @@ -0,0 +1,79 @@ +# SAL layer class model +import sys +import os +import random + +sys.path.append("../") +from lib.MN_Queue import Parts,MN_queue,MN_commons +from LLS.LLS import DSAST, GAST + + +# TODO: CAST translation table that resides in PN(DP->DS_C) //Adaptation layer? +# TODO: CAST translation cache that resides in PN(DP->DS_T) +# TODO: DSAST terminates when all of its associate bast terminates + +WAY_LIMIT = 0 # determined by pc +LARGE_LINE_LIMIT = 0 # determined by pc +SMALL_LINE_LIMIT = 0 # determined by pc +INVALID_TRANSLATION = 0x00000000 # 32 bits of zero +MAX_SOCKET = 3 + +class SysConfig: + def __init__(self, way_limit=WAY_LIMIT, large_line_limit=LARGE_LINE_LIMIT, small_line_limit=SMALL_LINE_LIMIT, + invalid_translation=INVALID_TRANSLATION,max_socket=MAX_SOCKET): + self.way_limit = way_limit + self.large_line_limit = large_line_limit + self.small_line_limit = small_line_limit + self.invalid_translation = invalid_translation + self.max_socket = max_socket + +class ProgramCAST: + def __init__(self,thread_counts=1,gast=GAST()): + self.sys_config = SysConfig() # program sysconfig + self.index = random.getrandbits(20) # actual CAST is this 20-bit tag + self.mn_commons = MN_commons() # collection of all mn_queues + self.threads = [ThreadCAST(gast=gast) for idx in range(thread_counts)] # list of ongoing threads - start with 1 + self.thread_ids = [id(thread) for thread in threads] # list of ordered thread ids + self.dpast_to_dsast = {} # dpast to dsast translation table + #self.dsast = mapBASTtoDSAST(DSAST(),gast=None) + + + #SNE features + self.npast_to_nsast = [] * self.sys_config.max_socket + self.network_addr = 0 + self.network_data = 0 + self.port_PN = 0 + + self.stdin = GAST() + self.stdout = GAST() + self.strerr = GAST() + + #def init_program(self): + # get the gast dsast info etc. + + def read_port(self): + self.port_PN = data + + + def write_port(self): + self.port_PN = data + + def get_threads(self) -> list: + return self.threads + + def get_thread_ids(self) -> list: + return self.thread_ids + + +class ThreadCAST: + def __init__(self, dsast=DSAST(), gast=GAST(), dpast=DPAST()): + self.ID = id(self) # need clearification on id + self.status = 0 # waiting = 0, running = 1, sleeping = 2 + #self.dsast = mapBASTtoDSAST(dsast=dsast,gast=gast) # from LLS + self.gast = gast + self.dpast = DPAST(size=0, DSAST=self.dsast) + self.program_counter = None + # look into thread system notification + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/Deprecated/lib/sim_sock.py b/Deprecated/lib/sim_sock.py new file mode 100644 index 0000000..d1a5609 --- /dev/null +++ b/Deprecated/lib/sim_sock.py @@ -0,0 +1,81 @@ +import socket +import select + +class DSAST: + # Structure(MSB to LSB): Way Limit, Size, Line Limit, Index, Offset, prob useless for python simulations + def __init__(self, index=0, lineLimit=0, size=0, wayLimit=0): + # Size: 0 = Large DSAST, 1 = Small DSAST + # Offset: 40 bits for small, 50 bit for large + # Index: (mb kinda the file name) indexing in a list of DSASTs + # only cache fields + # Line limit: The least significant set-bit of the this field determines the partition size and the remaining + # upper bits of the field determine to which of the possible ranges, of the indicated size, the DSAST is restricted. + # Way Limit: cache restrictions. 0=RESERVED, 1=no restriction, 2=only 1st half of the cache, 3=only second half of the cache + + self.size = size + self.index = index + self.linelimit = lineLimit + self.waylimit = wayLimit + if(size): # small DSAST + self.offset = random.getrandbits(40) + else: + self.offset = random.getrandbits(50) + +class GAST: + global bastTable + def __init__(self, permissions=bytes(2), encrypt=None, addr=None): + # permissions: permissions for given GAST, are the first half of the domain + # encrypt: is a flag for whether or not to encrypt the GAST + # addr: is the location where the GAST's data will be stored, + # assuming the processor or process manager is what allocated + # a GAST to a given process + aOIT = OIT(permissions) + # dividing the domain in half: permissions and the actual domain + self.permissions = aOIT.permissions + self.domain = aOIT.domain + self.key = aOIT.key + aBAST = BAST() # address for tagged data + bastTable[(self.domain, self.key)] = aBAST + +# Packet struct. Refer to John's Notes for component id and extra details on connections +class Pack: + def __init__(self, origin, destination, content): + self.origin = origin + self.destination = destination + self.content = content + +def open_listenfd(port, host=''): + # port: port to bind to, need to specify a port + # host: host to bind to, default is any host + + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP + s.bind((host, port)) + s.listen(5) + return s + +def on_new_client(clientsocket,addr): + while True: + msg = clientsocket.recv(1024) + #do some checks and if msg == someWeirdSignal: break: + print addr, ' >> ', msg + #msg = raw_input('SERVER >> ') + #Maybe some code to compute the last digit of PI, play game or anything else can go here and when you are done. + #clientsocket.send(msg) + clientsocket.close() + +def start_listen_conns(components=[]): + # components: list of tuples containing port and host values for each component to connect + # components = [(port, host)] + # open socket for each component and listen to all ports + socks = [] + for component in components: + socks.append(open_listenfd(port=component[0], host=component[1])) + + while True: + rdy_socks,_,_ = select.select(socks, None, None) + for sock in rdy_socks: + (conn, address) = sock.accept() + thread.start_new_thread(on_new_client,(c,addr)) + + for sock in socks: + sock.close() \ No newline at end of file diff --git a/Deprecated/lib/sockets.txt b/Deprecated/lib/sockets.txt new file mode 100644 index 0000000..4c7d3d1 --- /dev/null +++ b/Deprecated/lib/sockets.txt @@ -0,0 +1 @@ +# put sockets for each component here \ No newline at end of file diff --git a/LLS/LLS.py b/LLS/LLS.py index 9f7240f..644cd78 100644 --- a/LLS/LLS.py +++ b/LLS/LLS.py @@ -1,29 +1,27 @@ -# import numpy as np import random import sys import os -# import typing import pickle import shutil -import ctypes -from multiprocessing import Queue +# import numpy as np +# import typing +#import ctypes +#from multiprocessing import Queue +# import base64 +# import hashlib +# from Crypto import Random +# from Crypto.Cipher import AES sys.path.append('../') from lib.MN_Queue import MN_queue, Message, MN_commons, Parts -from PN.SAL import DPAST, mapDSASTtoDPAST -# from PMU.PMU import Proc +from lib.DAST import DPAST, DSAST +from lib.CAST import ThreadCAST, ProgramCAST # from PN.PN import run - -# import base64 -# import hashlib -# from Crypto import Random -# from Crypto.Cipher import AES - -# gastTable = {} # Hash table, bast to gast mapping, not in use as probably does not exist, there should probably only be +gastTable = {} # Hash table, bast to gast mapping, not in use as probably does not exist, there should probably only be # a mapping from GAST to BAST, not the inverse -oitTable = [] # could be a tree indexed by lookup uses, but functionally is just a list +oitTable = [] # could be a tree indexed by lookup uses, but functionally is just a list oatTable = {} # Hash table, index should be OIT's value bastTable = {} # List of bast, key: GAST key and domain, value: BAST bastAvail = [] # list of available bast file names @@ -35,14 +33,13 @@ # in theory, all data objects are stored linearly and accessed through tuples (DATA OBJ, ADDRESS IN HDD), there are no 'files' files = [] + OK_TO_UNMAP = 0x1 NOT_OK_TO_UNMAP = 0x2 NEW_CACHE = 0x3 CACHE_REQUEST = 0x4 GAST_REQUEST = 0x5 -MN = MN_commons() - # ch-lls communication only receives 14bits (28 bits shifted by 14) mapping to a 16k cache line # LLS deals with requests for 16k only @@ -73,49 +70,53 @@ def main(): print("sb.valid ", sb.valid) # _test_bast_persistence() # _test_run_prog() - + + newgast = GAST() print("allocated GAST: ", newgast) bastTable[(newgast.domain, newgast.key)].writeToFile("abcde", 0) print("mapped BAST: ", bastTable[(newgast.domain, newgast.key)]) - process = Proc(ID=0, gast=newgast) - print("process' allocated DSAST: ", process.DSAST) + p_cast = ProgramCAST(mapBASTtoDSAST,gast=newgast) + process = p_cast.get_threads()[0] # first threadCAST + #TODO: manual mapping to automatic mapping + print("process' allocated DSAST: ", p_cast.dsast) print("DSAST -> BAST table: ", sastBast) - print("contents of BAST: ", sastBast[process.DSAST].readFromFile()) + print("contents of BAST: ", sastBast[p_cast.dsast].readFromFile()) sb.close() -def _test_run_prog(): - newgast = GAST() - abast = bastTable[(newgast.domain, newgast.key)] - shutil.copyfile("PN/meminit.hex", ".b/" + abast.getfname) - run(newgast) - - -def _test_mnq(): - # CAST is equivalent to proc object in legacy systems - global OK_TO_UNMAP - global NOT_OK_TO_UNMAP - global NEW_CACHE - global CACHE_REQUEST - global GAST_REQUEST - msgLLS = None - msgCH = None - - # eventually, MNQ read occur in loop - msgLLS = MN.read(src=Parts.LLS, dest=Parts.CH) - msgCH = MN.read(src=Parts.CH, dest=Parts.LLS) - print("msgLLS ", msgLLS, "\nmsgCH ", msgCH) - - gastrequest = Message(msg=GAST_REQUEST, data_size=0, data=None, need_response=True) - MN.write(src=Parts.CH, dest=Parts.LLS, msg=gastrequest) - msgLLS = MN.read(src=Parts.LLS, dest=Parts.CH) - msgCH = MN.read(src=Parts.CH, dest=Parts.LLS) - if(msgLLS != None): - if(msgLLS.msg == GAST_REQUEST): - pass - #elif(msgLLS == CACHE_REQUEST): - print("msgLLS ", msgLLS, "\nmsgCH ", msgCH) +#def _test_run_prog(): +# newgast = GAST() +# abast = bastTable[(newgast.domain, newgast.key)] +# shutil.copyfile("PN/meminit.hex", ".b/" + abast.getfname) +# run(newgast) + + +#def _test_mnq(): +# # CAST is equivalent to proc object in legacy systems +# global OK_TO_UNMAP +# global NOT_OK_TO_UNMAP +# global NEW_CACHE +# global CACHE_REQUEST +# global GAST_REQUEST +# msgLLS = None +# msgCH = None +# +# # Sen Note: MN_QUEUE main function has an example of how to read it continuously +# # eventually, MNQ read occur in loop +# msgLLS = MN.read(src=Parts.LLS, dest=Parts.CH) +# msgCH = MN.read(src=Parts.CH, dest=Parts.LLS) +# print("msgLLS ", msgLLS, "\nmsgCH ", msgCH) +# +# gastrequest = Message(msg=GAST_REQUEST, data_size=0, data=None, need_response=True) +# MN.write(src=Parts.CH, dest=Parts.LLS, msg=gastrequest) +# msgLLS = MN.read(src=Parts.LLS, dest=Parts.CH) +# msgCH = MN.read(src=Parts.CH, dest=Parts.LLS) +# if(msgLLS != None): +# if(msgLLS.msg == GAST_REQUEST): +# pass +# #elif(msgLLS == CACHE_REQUEST): +# print("msgLLS ", msgLLS, "\nmsgCH ", msgCH) def _test_bast_persistence(): @@ -209,13 +210,16 @@ def __init__(self, gast=None): # self.block = None # where in disk is it stored # self.translations = [] # list of translations to other blocks +# init global superblock +sb = Superblock() + class GAST: global bastTable def __init__(self, permissions=bytes(2), encrypt=None, addr=None, bast=None): # permissions: permissions for given GAST, are the first half of the domain # encrypt: is a flag for whether or not to encrypt the GAST # addr: is the location where the GAST's data will be stored, - # assuming the processor or process manager is what allocated + # assuming the processor or process manager is what allocated # a GAST to a given process aOIT = OIT(permissions) # dividing the domain in half: permissions and the actual domain @@ -245,6 +249,7 @@ def duplicate(self): def free(self): del bastTable[(self.domain, self.key)] + class BAST: def __init__(self): # NOTE: check if max value of BAST has been used, then throw exception (realistically should never happen) @@ -282,7 +287,8 @@ def checkFileExists(self, count): # if offset is larger, create space for the write def writeToFile(self, value, offset=0): - with open("./b/"+str(hex(self.value)), 'w') as file: + #with open("./b/"+str(hex(self.value)), 'w') as file: + with open(os.path.join(os.getcwd(),"b",str(hex(self.value)) ), 'w') as file: # if we get an offset larger than file size, pad file to fit content fsize = file.seek(0, 2) - file.seek(0, 0) # if offset is larger than file size, pad out file with 0 until offset @@ -295,7 +301,8 @@ def writeToFile(self, value, offset=0): # if offset is larger, raise exception, send back msg to PMU that the process is trying to do funny stuff def readFromFile(self, length=64, offset=0): - with open("./b/"+str(hex(self.value)), 'r') as file: + #with open("./b/"+str(hex(self.value)), 'r') as file: + with open(os.path.join(os.getcwd(),"b",str(hex(self.value))) , 'r') as file: # check max offset file.seek(0, 2) # 2 == SEEK_END max_off = file.tell() @@ -337,7 +344,7 @@ def retire(self): sastBast.pop(sast.dsast) return print("Did not find dsast to bast mapping when retiring BAST") - return + return class OIT: def __init__(self, permissions): @@ -346,64 +353,16 @@ def __init__(self, permissions): self.permissions = permissions # establish domains, not random # for now, 2 domains: code or data - self.domain = random.getrandbits(16) + self.domain = random.getrandbits(16) self.key = random.getrandbits(448) - self.value = bytes(4) # 32 bit representation of BAST + self.value = bytes(4) # 32 bit representation of BAST # need to check if key does not exist in domain before addying entry to hash table # not sure if this is what goes into the oitTable... if (self.domain, self.value) not in oitTable: oitTable.append((self.domain, self.value)) -class DSAST: - # NOTE: this DSAST struct represents the entire DSR as described in page 29 of the manual_1y, - # thus self.offset and self.dsast compose the entire DSR struc and each DSAST field can - # be accessed individually as well - # Structure(MSB to LSB): Way Limit, Size, Line Limit, Index. Part of DSR: Offset, prob useless for python simulations - def __init__(self, address=None, index=0, lineLimit=0, size=1, wayLimit=0, offset=0): - # Size: 0 = Large DSAST, 1 = Small DSAST - # Offset: 40 bits for small, 50 bit for large - # Index: (mb kinda the file name) indexing in a list of DSASTs - # only cache fields - # Line limit: The least significant set-bit of the this field determines the partition size and the remaining - # upper bits of the field determine to which of the possible ranges, of the indicated size, the DSAST is restricted. - # Way Limit: cache restrictions. 0=RESERVED, 1=no restriction, 2=only 1st half of the cache, 3=only second half of the cache - if(address==None): # make new dsast - self.size = size - if(index != 0): - self.index = index - elif(size==0): # large dsast - self.index = random.getrandbits(15) - elif(size==1): # small dsast - self.index = random.getrandbits(24) - self.linelimit = lineLimit - self.waylimit = wayLimit - if(offset != 0): - self.offset = offset - else: - if(size): # small DSAST - self.offset = random.getrandbits(40) - else: - self.offset = random.getrandbits(50) - self.dsast = self.index | (self.linelimit << 24) | (self.size << 29) | (self.waylimit << 30) - else: # address passed from CH - self.size = size - self.waylimit = wayLimit - self.linelimit = lineLimit - if(self.size): # small DSAST - self.index = (address >> 39) & 0xffffff # 24 bits - self.offset = address & 0xffffffffff # 40 bits - self.dsast = self.index | (self.linelimit << 24) | (self.size << 29) | (self.waylimit << 30) - else: - self.index = (address >> 49) & 0x3fff # 14 bits - self.offset = address & 0x3ffffffffffff # 50 bits - self.dsast = self.index | (self.linelimit << 14) | (self.size << 19) | (self.waylimit << 20) - - -# init global superblock -sb = Superblock() - -# Local function to fetch superblock from disk, written using the Superblock.close() method. +# Local function to fetch superblock from disk, written using the Superblock.close() method. # Writes directly to global sb variable. Should be called during initialization of system # NOTE: moved from Superblock method to standalone function to fix some problems with variable locality def openFS(): @@ -425,6 +384,7 @@ def openFS(): sb.valid = True return True else: + os.mkdir(os.getcwd() + "/b/") print("Could not find existing superblock in disk!") return False @@ -436,6 +396,7 @@ def getBASTfromDSAST(dsast): global sastBast return sastBast[dsast] + # PMU function to map dsast to a bast # parameters: dsast(DSAST()): DSAST to be mapped # gast(GAST()): optional parameter to get bast directly from GAST @@ -446,7 +407,7 @@ def mapBASTtoDSAST(dsast, gast=None): global sastBast # Check if GAST is mapped to a BAST aBast = None - if(gast != None): + if(gast != None): if ((gast.domain, gast.key) in bastTable.keys()): aBast = bastTable[(gast.domain, gast.key)] else: @@ -476,8 +437,9 @@ def gastRequest(dsast): mapBASTtoDSAST(dsast=dsast, gast=newgast) return newgast + # FILE OPERATION FUNCTIONS -def openFile(dsast, gast): +def openFile(dsast, gast=None): # TODO: check if file already exists, if not, do createFile # this function will call mapBASTtoDSAST @@ -574,16 +536,6 @@ def rcvOkToUnmap(): else: return False -# CH function to map block address to DSAST -# parameters: addr(64-bit value): block address from CH -# returns: corresponding dsast that has same offset and index or false if no matching dsast is found -def mapAddrToDSAST(addr): - global sastBast - for dsast, bast in sastBast.items(): - if(dsast.offset == (addr & 0xffffffffff) and dsast.index == (addr & 0xffffff)): - return dsast - return False - # CH function to read from DSAST # parameters: dsast(DSAST()): DSAST() mapped to file # returns: void: data read from DSAST.offset @@ -615,27 +567,24 @@ def writeLLS(dsast, writeData): print("writeLLS: Writing {} to {}\n".format(dsast.dsast, writeData)) sastBast[adsast.dsast].writeToFile(writeData, dsast.offset) -class CAST: - def __init__(self, gast=GAST()): - self.index = random.getrandbits(20) # actual CAST is this 20-bit tag - self.mnq = MN_queue() - self.gast = gast - -class Proc: - def __init__(self, ID=0, DSAST=DSAST(), gast=GAST()): - self.ID = 0 #need to figure out CAS values - self.status = 0 # waiting = 0, running = 1, sleeping = 2 - self.DSAST = DSAST #from LLS - self.GAST = gast - self.DPAST = DPAST(size=0, DSAST=self.DSAST) - self.prog = CAST(gast=gast) - self.threads = [CAST(gast=gast)] ## need to determine how many CASTS to initialize, maybe more casts are added at runtime. one for each thread - self.priority = 0 #influences how much run time it gets - self.stdin = GAST() - self.stdout = GAST() - self.strerr = GAST() - self.DSAST = mapBASTtoDSAST(dsast=self.DSAST, gast=self.GAST) - mapDSASTtoDPAST(self.DSAST) + +# CH functions that accept a non-DSAST address +# def readLLS(addr): +# global sastBast +# # check if dsast exists +# for dsast, bast in sastBast.items(): +# if(dsast.offset == addr): +# return sastBast[dsast].readFromFile(dsast.offset) +# return False + +# def writeLLS(addr, writeData): +# global sastBast +# dsast = mapAddrToDSAST() +# if(dsast == False): # could not find corresponding dsast with addr +# dsast = mapBASTtoDSAST(dsast) +# dsast.offset = addr +# return sastBast[dsast].writeToFile(writeData, dsast.offset) + # operations for CH # read, write, write through (when L5 writes data to the LLS and line becomes clean in the L5, for the LLS it looks the same as write), @@ -688,14 +637,14 @@ def __init__(self, ID=0, DSAST=DSAST(), gast=GAST()): if __name__ == '__main__': - # global sastBast + main() + + # global sastBast # for i in range(0,10): # name = "gast"+str(i) # name = GAST() - # print(bastTable) - # dsast = DSAST() # gastlist = [gast for gast in bastTable] # agast = gastlist[0] diff --git a/LLS/__pycache__/LLS.cpython-39.pyc b/LLS/__pycache__/LLS.cpython-39.pyc new file mode 100644 index 0000000..e5fd7ce Binary files /dev/null and b/LLS/__pycache__/LLS.cpython-39.pyc differ diff --git a/PMU/process.pyc b/PMU/process.pyc deleted file mode 100644 index 64d05a0..0000000 Binary files a/PMU/process.pyc and /dev/null differ diff --git a/PN/PN.py b/PN/PN.py index d678172..e162879 100644 --- a/PN/PN.py +++ b/PN/PN.py @@ -17,6 +17,4 @@ def run(gast): simulator.main("../../LLS/b/" + bast.getfname()) # which type of address space goes into PN - # why does the PN need a DPSAT - # what is the use of the DPAST? what is its relation to the process object in the PMU - # \ No newline at end of file + # why does the PN need a DPSAT \ No newline at end of file diff --git a/PN/meminit.hex b/PN/meminit.hex index 472a296..5206629 100644 --- a/PN/meminit.hex +++ b/PN/meminit.hex @@ -1,3 +1,4 @@ + :0400000027BDFBD845 :04000100AFBE042466 :0400020003A0F02146 @@ -220,4 +221,4 @@ :0400DB0027BD00300D :0400DC0003E0000835 :0400DD00FFFFFFFF23 -:00000001FF + diff --git a/SAL/README.md b/SAL/README.md new file mode 100644 index 0000000..634b770 --- /dev/null +++ b/SAL/README.md @@ -0,0 +1 @@ +SAL diff --git a/SAL/SAFE_lib.h b/SAL/SAFE_lib.h deleted file mode 100755 index 7d78d02..0000000 --- a/SAL/SAFE_lib.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef SAFE_lib -#define SAFE_lib - -struct sockaddr { - sa_family_t sa_family; /* address family */ - char sa_data[14]; /* actually longer; address value */ -}; - -struct msghdr { - void *msg_name; /* optional address */ - socklen_t msg_namelen; /* size of address */ - struct iovec *msg_iov; /* scatter/gather array */ - int msg_iovlen; /* # elements in msg_iov */ - void *msg_control; /* ancillary data, see below */ - socklen_t msg_controllen; /* ancillary data buffer len */ - int msg_flags; /* flags on received message */ -}; - -typedef int socklen_t; -typedef int size_t; - -int accept(int, struct sockaddr *, socklen_t *); -int bind(int, const struct sockaddr *, socklen_t); -int connect(int, const struct sockaddr *, socklen_t); -int getpeername(int, struct sockaddr *, socklen_t *); -int getsockname(int, struct sockaddr *, socklen_t *); -int getsockopt(int, int, int, void *, socklen_t *); -int listen(int, int); -ssize_t recv(int, void *, size_t, int); -ssize_t recvfrc om(int, void *, size_t, int, struct sockaddr *, socklen_t *); -ssize_t recvmsg(int, struct msghdr *, int); -ssize_t send(int, const void *, size_t, int); -ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); -ssize_t sendmsg(int, const struct msghdr *, int); -int sendfile(int, int, off_t, size_t, struct sf_hdtr *, off_t *, int); -int setsockopt(int, int, int, const void *, socklen_t); -int shutdown(int, int); -int socket(int, int, int); -int socketpair(int, int, int, int *); - - - -#endif - diff --git a/SAL/SAL.py b/SAL/SAL.py deleted file mode 100644 index 64a29f7..0000000 --- a/SAL/SAL.py +++ /dev/null @@ -1,20 +0,0 @@ -#y is the addr space which is alloc to A to talk to B -#y is the system addr space -#A writes its stuff. Then, it writes a message notification to CAST_B -#B has an MN queue to pull from it and it also has a thread to pull from that address space by waking up -MAX_SOCKET = 3 -class CAST_SAL: - def __init__(self): - self.MN_queue = MN_Queue() - self.NPASTtoNSAST = [0] * MAX_SOCKET - self.pc = 0 - self.DPASTtoDSAST = [0] - self.addr = 0 - self.data = 0 - self.port_PN = 0 - def read_port(self): - self.port_PN = data - def write_port(self): - self.port_PN = data - def read_cache(self): - return diff --git a/SAL/printf.c b/TestIdeas/printf.c old mode 100755 new mode 100644 similarity index 100% rename from SAL/printf.c rename to TestIdeas/printf.c diff --git a/lib/CAST.py b/lib/CAST.py new file mode 100644 index 0000000..d026296 --- /dev/null +++ b/lib/CAST.py @@ -0,0 +1,81 @@ +# SAL layer class model +import sys +import random + +sys.path.append("../") +from lib.MN_Queue import Parts,MN_queue,MN_commons +from lib.DAST import DSAST, DPAST +#from LLS.LLS import mapBASTtoDSAST + +WAY_LIMIT = 0 # determined by pc +LARGE_LINE_LIMIT = 0 # determined by pc +SMALL_LINE_LIMIT = 0 # determined by pc +INVALID_TRANSLATION = 0x00000000 # 32 bits of zero +MAX_SOCKET = 3 + +class SysConfig: + def __init__(self, way_limit=WAY_LIMIT, large_line_limit=LARGE_LINE_LIMIT, small_line_limit=SMALL_LINE_LIMIT, + invalid_translation=INVALID_TRANSLATION,max_socket=MAX_SOCKET): + self.way_limit = way_limit + self.large_line_limit = large_line_limit + self.small_line_limit = small_line_limit + self.invalid_translation = invalid_translation + self.max_socket = max_socket + +class ProgramCAST: + ## Remember to pass in the function "mapBASTtoDSAST" when init ProgramCAST + def __init__(self,mapBASTtoDSAST,thread_counts=1,gast=None): + self.sys_config = SysConfig() # program sysconfig + self.index = random.getrandbits(20) # actual CAST is this 20-bit tag + self.mn_commons = MN_commons() # collection of all mn_queues + self.threads = [ThreadCAST(self) for idx in range(thread_counts)] # list of ongoing threads - start with 1 + #TODO: thread cast needs gast + self.thread_ids = [id(thread) for thread in self.threads] # list of ordered thread ids + self.dpast_to_dsast = {} # dpast to dsast translation table + self.dsast = mapBASTtoDSAST(DSAST(),gast=gast) + self.gast = gast + #TODO: Generate a dpast associated with the particular dsast + self.dpast = None + + #SNE features + self.npast_to_nsast = [] * self.sys_config.max_socket + self.network_addr = 0 + self.network_data = 0 + self.port_PN = 0 + + #TODO: + #self.stdin = GAST() + #self.stdout = GAST() + #self.strerr = GAST() + + def read_port(self,data): + self.port_PN = data + + def write_port(self,data): + self.port_PN = data + + def get_threads(self) -> list: + return self.threads + + def get_thread_ids(self) -> list: + return self.thread_ids + + +class ThreadCAST: + def __init__(self,ProgramCAST): + self.ID = id(self) # need clearification on id + self.status = 0 # waiting = 0, running = 1, sleeping = 2 + self.PC = None + #self.dsast = mapBASTtoDSAST(dsast=dsast,gast=gast) # from LLS + #self.gast = GAST() + #self.dpast = DPAST(size=0, DSAST=self.dsast) # is it necessary? + #self.dsast = DSAST() + self.gast = None + self.dsast = None + self.dpast = None + self.p_cast = ProgramCAST + + # look into thread system notification + +if __name__ == '__main__': + pass diff --git a/lib/DAST.py b/lib/DAST.py new file mode 100644 index 0000000..9e22eef --- /dev/null +++ b/lib/DAST.py @@ -0,0 +1,123 @@ +import random + +# TODO: hardcoded spec, need to change it to read sysconfig instead +WAY_LIMIT = 0 # determined by pc +LARGE_LINE_LIMIT = 0 # determined by pc +SMALL_LINE_LIMIT = 0 # determined by pc +INVALID_TRANSLATION = 0x00000000 # 32 bits of zero + +class DSAST: + # NOTE: this DSAST struct represents the entire DSR as described in page 29 of the manual_1y, + # thus self.offset and self.dsast compose the entire DSR struc and each DSAST field can + # be accessed individually as well + # Structure(MSB to LSB): Way Limit, Size, Line Limit, Index. Part of DSR: Offset, prob useless for python simulations + def __init__(self, address=None, index=0, lineLimit=0, size=1, wayLimit=0, offset=0): + # Size: 0 = Large DSAST, 1 = Small DSAST + # Offset: 40 bits for small, 50 bit for large + # Index: (mb kinda the file name) indexing in a list of DSASTs + # only cache fields + # Line limit: The least significant set-bit of the this field determines the partition size and the remaining + # upper bits of the field determine to which of the possible ranges, of the indicated size, the DSAST is restricted. + # Way Limit: cache restrictions. 0=RESERVED, 1=no restriction, 2=only 1st half of the cache, 3=only second half of the cache + if(address==None): # make new dsast + self.size = size + if(index != 0): + self.index = index + elif(size==0): # large dsast + self.index = random.getrandbits(15) + elif(size==1): # small dsast + self.index = random.getrandbits(24) + self.linelimit = lineLimit + self.waylimit = wayLimit + if(offset != 0): + self.offset = offset + else: + if(size): # small DSAST + self.offset = random.getrandbits(40) + else: + self.offset = random.getrandbits(50) + self.dsast = self.index | (self.linelimit << 24) | (self.size << 29) | (self.waylimit << 30) + else: # address passed from CH + self.size = size + self.waylimit = wayLimit + self.linelimit = lineLimit + if(self.size): # small DSAST + self.index = (address >> 39) & 0xffffff # 24 bits + self.offset = address & 0xffffffffff # 40 bits + self.dsast = self.index | (self.linelimit << 24) | (self.size << 29) | (self.waylimit << 30) + else: + self.index = (address >> 49) & 0x3fff # 14 bits + self.offset = address & 0x3ffffffffffff # 50 bits + self.dsast = self.index | (self.linelimit << 14) | (self.size << 19) | (self.waylimit << 20) + + +# CH function to map block address to DSAST +# parameters: addr(64-bit value): block address from CH +# returns: corresponding dsast that has same offset and index or false if no matching dsast is found +def mapAddrToDSAST(addr): + global sastBast + for dsast, bast in sastBast.items(): + if(dsast.offset == (addr & 0xffffffffff) and dsast.index == (addr & 0xffffff)): + return dsast + return False + + +class DPAST: + def __init__(self, size=0, dsast=None): + # Size: 0 = Large DPAST, 1 = Small DPAST + self.size = size + self.dsast = dsast + if (size): # small DPAST + self.offset = random.getrandbits(40) + self.data = random.getrandbits( + 18) # randomize address to keep track of or the actual data address from DSAST? + else: + self.offset = random.getrandbits(50) + self.data = random.getrandbits(8) + DPAST_process.append(self.data) + + +def mapDSASTtoDPAST(aDSAST): + pass + #if (aDSAST in DPASTDSAST): + # return + #aDPAST = DPAST(aDSAST.size, aDSAST) + #DPASTDSAST[aDSAST] = aDPAST + #return + + +def DP_translation(aDSAST): + aDPAST = DPASTDSAST[aDSAST] + if (aDPAST == None): + return INVALID_TRANSLATION + return aDPAST + + +### convert DSAST to binary DSR that cache uses +### returns a 72bit DSR +def DSAST_to_binary(aDSAST): + binary = WAY_LIMIT << 70 + # 69th bit 0 is a large dsast, bit 1 is a small dsast + if (aDPAST.size): # small dsast + binary |= (0 << 69) | (SMALL_LINE_LIMIT << 65) + binary |= (aDSAST.index << 50) | (aDPAST.offset) + else: # large dsast + binary |= (1 << 69) | (LARGE_LINE_LIMIT << 64) + binary |= (aDSAST.index << 40) | (aDST.offset) + return binary + + +### vice-versa of DSAST_to_binary +### returns an object DSAST +def binary_to_DSAST(binary): + size = binary & (1 << 69) + if (size): # sm all dsast + index = binary & (0x7fff << 50) + offset = (binary << 22) >> 22 + linelimit = SMALL_LINE_LIMIT + else: # large dsast + index = binary & (0x1ffffff << 40) + offset = (binary << 32) >> 32 + linelimit = LARGE_LINE_LIMIT + aDPAST = DPAST(index, linelimit, size, WAY_LIMIT, offset) + return aDPAST \ No newline at end of file diff --git a/lib/__pycache__/CAST.cpython-37.pyc b/lib/__pycache__/CAST.cpython-37.pyc new file mode 100644 index 0000000..79ec3cd Binary files /dev/null and b/lib/__pycache__/CAST.cpython-37.pyc differ diff --git a/lib/__pycache__/DAST.cpython-37.pyc b/lib/__pycache__/DAST.cpython-37.pyc new file mode 100644 index 0000000..d852ce7 Binary files /dev/null and b/lib/__pycache__/DAST.cpython-37.pyc differ diff --git a/lib/__pycache__/MN_Queue.cpython-37.pyc b/lib/__pycache__/MN_Queue.cpython-37.pyc new file mode 100644 index 0000000..78d029b Binary files /dev/null and b/lib/__pycache__/MN_Queue.cpython-37.pyc differ diff --git a/lib/__pycache__/MN_Queue.cpython-39.pyc b/lib/__pycache__/MN_Queue.cpython-39.pyc new file mode 100644 index 0000000..c132334 Binary files /dev/null and b/lib/__pycache__/MN_Queue.cpython-39.pyc differ