mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-12-23 20:13:06 +00:00
67 lines
2.5 KiB
Python
67 lines
2.5 KiB
Python
|
#!/usr/bin/python
|
||
|
|
||
|
class Heap(object):
|
||
|
def __init__(self, start, end, block=64):
|
||
|
if start%block:
|
||
|
raise ValueError("heap start not aligned")
|
||
|
if end%block:
|
||
|
raise ValueError("heap end not aligned")
|
||
|
self.offset = start
|
||
|
self.count = (end - start) // block
|
||
|
self.blocks = [(self.count,False)]
|
||
|
self.block = block
|
||
|
def malloc(self, size):
|
||
|
size = (size + self.block - 1) // self.block
|
||
|
pos = 0
|
||
|
for i, (bsize, full) in enumerate(self.blocks):
|
||
|
if not full:
|
||
|
if bsize == size:
|
||
|
self.blocks[i] = (bsize,True)
|
||
|
return self.offset + self.block * pos
|
||
|
if bsize > size:
|
||
|
self.blocks[i] = (size,True)
|
||
|
self.blocks.insert(i+1, (bsize-size, False))
|
||
|
return self.offset + self.block * pos
|
||
|
pos += bsize
|
||
|
raise Exception("Out of memory")
|
||
|
def free(self, addr):
|
||
|
if addr%self.block:
|
||
|
raise ValueError("free address not aligned")
|
||
|
if addr<self.offset:
|
||
|
raise ValueError("free address before heap")
|
||
|
addr -= self.offset
|
||
|
addr //= self.block
|
||
|
if addr>=self.count:
|
||
|
raise ValueError("free address after heap")
|
||
|
pos = 0
|
||
|
for i, (bsize, used) in enumerate(self.blocks):
|
||
|
if pos > addr:
|
||
|
raise ValueError("bad free address")
|
||
|
if pos == addr:
|
||
|
if used == False:
|
||
|
raise ValueError("block already free")
|
||
|
if i!=0 and self.blocks[i-1][1] == False:
|
||
|
bsize += self.blocks[i-1][0]
|
||
|
del self.blocks[i]
|
||
|
i -= 1
|
||
|
if i!=(len(self.blocks)-1) and self.blocks[i+1][1] == False:
|
||
|
bsize += self.blocks[i+1][0]
|
||
|
del self.blocks[i]
|
||
|
self.blocks[i] = (bsize, False)
|
||
|
return
|
||
|
pos += bsize
|
||
|
raise ValueError("bad free address")
|
||
|
def check(self):
|
||
|
free = 0
|
||
|
inuse = 0
|
||
|
for i, (bsize, used) in enumerate(self.blocks):
|
||
|
if used:
|
||
|
inuse += bsize
|
||
|
else:
|
||
|
free += bsize
|
||
|
if free + inuse != self.count:
|
||
|
raise Exception("Total block size is inconsistent")
|
||
|
print("Heap stats:")
|
||
|
print(" In use: %8dkB"%(inuse * self.block // 1024))
|
||
|
print(" Free: %8dkB"%(free * self.block // 1024))
|