-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
334 additions
and
201 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
from alloc import malloc | ||
|
||
def disk_init(n_blocks) returns disk: | ||
const BITS_PER_BLOCK = 4 | ||
|
||
def new(n_blocks) returns disk: | ||
disk = malloc([ None, ] * n_blocks) | ||
|
||
def disk_getsize(disk) returns size: | ||
def getsize(disk) returns size: | ||
size = len !disk | ||
|
||
def disk_read(disk, bno) returns block: | ||
def read(disk, bno) returns block: | ||
block = (!disk)[bno] | ||
|
||
def disk_write(disk, bno, block): | ||
def write(disk, bno, block): | ||
(!disk)[bno] = block |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,17 @@ | ||
import lock | ||
from lock import Lock, acquire, release | ||
|
||
thelock = lock.Lock() | ||
const NTHREADS = 5 | ||
|
||
thelock = Lock() | ||
count = 0 | ||
invariant 0 <= count <= 1 | ||
|
||
def thread(): | ||
lock.acquire(?thelock) | ||
|
||
atomically count += 1 | ||
|
||
# critical section is here | ||
assert count == 1 | ||
|
||
atomically count -= 1 | ||
|
||
lock.release(?thelock) | ||
|
||
for i in {1..5}: | ||
while choose { False, True }: | ||
acquire(?thelock) | ||
atomically count += 1 | ||
assert count == 1 | ||
atomically count -= 1 | ||
release(?thelock) | ||
|
||
for i in {1..NTHREADS}: | ||
spawn thread() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import synch | ||
|
||
const F = 1 | ||
const N = (2*F) + 1 | ||
const MAX_BALLOT = N | ||
|
||
channels = [[],] * N | ||
|
||
def send(p, m): | ||
channels[p][len channels[p]] = m | ||
|
||
def process(self, proposal): | ||
var leader_ballot = self | ||
var last_accepted = () | ||
var ballot = 0 | ||
var phase1 = True | ||
var estimate = proposal | ||
var max_accepted = () | ||
|
||
while leader_ballot < MAX_BALLOT: | ||
for i in { 0 .. N-1 }: | ||
if phase1: | ||
atomically send(i, { .type: "p1a", .src: self, .ballot: leader_ballot }) | ||
else: | ||
atomically send(i, { .type: "p2a", .src: self, .ballot: leader_ballot, .value: estimate }) | ||
|
||
var responses = {} | ||
while len(responses) < (N - F): | ||
atomically let msgs = channels[self] when msgs != []: | ||
channels[self] = [] | ||
for msg in msgs: | ||
if msg.type == "p1a": | ||
if msg.ballot > ballot: | ||
ballot = msg.ballot | ||
send(msg.src, { .type: "p1b", .src: self, .ballot: ballot, .last: last_accepted }) | ||
elif msg.type == "p1b": | ||
if phase1 and (msg.ballot >= ballot): | ||
responses |= { msg.src } | ||
if (max_accepted == ()) or (msg.last > max_accepted): | ||
max_accepted = msg.last | ||
elif msg.type == "p2a": | ||
assert msg.ballot <= ballot, (msg.ballot, ballot) | ||
if msg.ballot == ballot: | ||
last_accepted = (ballot, msg.value) | ||
send(msg.src, { .type: "p2b", .src: self, .ballot: ballot }) | ||
else: | ||
assert msg.type == "p2b" | ||
if msg.ballot >= ballot: | ||
ballot = msg.ballot | ||
if not phase1: | ||
responses |= { msg.src } | ||
|
||
# See if my ballot succeeded | ||
if ballot == leader_ballot: | ||
if phase1: | ||
if max_accepted != (): | ||
_, estimate = max_accepted | ||
phase1 = False | ||
else: | ||
phase1 = True | ||
leader_ballot += N | ||
else: | ||
phase1 = True | ||
leader_ballot += N | ||
|
||
for i in { 0 .. N-1 }: | ||
spawn eternal process(i, choose { "red", "blue" }) |
Oops, something went wrong.