exchange( m, r )
repeat
LOAD_LOCKED load_temp,m
store_temp = r
STORE_CONDITIONAL store_temp,m
until store_temp = reset -- indicating success
r = load_temp
Then: Build on what you just did by outlining the entire code for
the lock() and unlock() primitives given in Lectures 4 and 5, using the Alpha
instructions instead of an exchange instruction.
lock( lk )
repeat
LOAD_LOCKED load_temp,lk
store_temp = 1
STORE_CONDITIONAL store_temp,lk
until (store_temp = reset) and (load_temp = 0)
unlock( lk )
store_temp = 0
STORE store_temp,lk
992-999 -- 8 960-991 -- 32 896-959 -- 64 768-895 -- 128 512-767 -- 256 256-512 -- 256 128-255 -- 128 112-127 -- 16 104-111 -- 8 100-103 -- 4
In the following, we assume that freelist is a pointer to a distinguished free block that is never merged with other free blocks and never allocated (size zero with status set to not free would do this!) We also assume that the free list is circularly linked.
Each block in the heap has a successor and a predecessor link to its neighbors, and each free block has a nextfree link to the next free block. The state field of each block may indicate either free or allocated.
malloc(s)
t = freelist
repeat
p = t
t = t.nextfree
if t.successor.state = free then
merge(t,t.successor)
endif
if t.predecessor.state = free then
merge(t.predecessor,t)
t = t.predecessor -- problematic!
endif
if size(t) > s+minsplit then
split(t,s)
endif
if size(t) > s then
p.nextfree = t.nextfree
t.state = allocated
return t
endif
until t = freelist
-- we've tried all free blocks and none fit!
failure
free(n)
n.nextfree = freelist.nextfree
freelist.nextfree = n
merge(a,b)
-- assert a and b are consecutive blocks in memory
-- snip b out of list of blocks
a.successor = b.successor
b.sucessor.predecessor = a