Skip to content

Commit

Permalink
Pure ooc coroutines implementations on top of ucontext, based on libc…
Browse files Browse the repository at this point in the history
…oroutine. Doesn't work yet for channels, for some reason.
  • Loading branch information
nddrylliog committed Aug 14, 2010
1 parent cb51fbb commit f3cf821
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 2 deletions.
2 changes: 2 additions & 0 deletions sdk/lang/Memory.ooc
Expand Up @@ -12,6 +12,7 @@ version(!gc) {
gc_malloc_atomic: extern(malloc) func (size: SizeT) -> Pointer
gc_realloc: extern(realloc) func (ptr: Pointer, size: SizeT) -> Pointer
gc_calloc: extern(calloc) func (nmemb: SizeT, size: SizeT) -> Pointer
gc_free: extern(free) func (ptr: Pointer)
}

version(gc) {
Expand All @@ -23,6 +24,7 @@ version(gc) {
gc_calloc: func (nmemb: SizeT, size: SizeT) -> Pointer {
gc_malloc(nmemb * size)
}
gc_free: extern(GC_FREE) func (ptr: Pointer)
}

// memory management
Expand Down
5 changes: 3 additions & 2 deletions sdk/lang/Numbers.ooc
@@ -1,4 +1,4 @@
include stdlib, stdint, stdbool, float, ctype, sys/types
include stdlib, stdint, stdbool, stddef, float, ctype, sys/types

LLong: cover from signed long long {

Expand Down Expand Up @@ -26,7 +26,7 @@ LLong: cover from signed long long {
for (i in 0..this) {
fn(i)
}
}
}
}

Long: cover from signed long extends LLong
Expand Down Expand Up @@ -73,6 +73,7 @@ UInt64: cover from uint64_t extends ULLong
Octet: cover from uint8_t
SizeT: cover from size_t extends ULLong
SSizeT: cover from ssize_t extends LLong
PtrDiff: cover from ptrdiff_t extends SizeT

/**
* real types
Expand Down
126 changes: 126 additions & 0 deletions sdk/os/Coro.ooc
@@ -0,0 +1,126 @@

Coro: class {

// this was originally commented '128k needed on PPC due to parser'
// I have no idea what that means but 128k sounds reasonable.
DEFAULT_STACK_SIZE := static 128 * 1_024
MIN_STACK_SIZE := static 8_192

requestedStackSize: SizeT { get set }
allocatedStackSize: SizeT
stack: Pointer { get set }
env: UContext
isMain: Bool

init: func {
requestedStackSize = DEFAULT_STACK_SIZE
allocatedStackSize = 0
}

allocStackIfNeeded: func {
if (stack != null && allocatedStackSize > requestedStackSize) {
gc_free(stack)
stack = gc_malloc(requestedStackSize)
"Coro_%p re-allocating stack size %i" printfln(this, requestedStackSize)
}

if (stack == null) {
stack = gc_malloc(requestedStackSize)
"Coro_%p allocating stack size %i" printfln(this, requestedStackSize)
}
}

free: func {
if(stack) {
gc_free(stack)
}
"Coro_%p free" printfln(this)
}

currentStackPointer: func -> UInt8* {
a: UInt8
b := a& // to avoid compiler warning about unused variables
b
}

bytesLeftOnStack: func -> SizeT {
dummy: UChar
p1: PtrDiff = dummy&
p2: PtrDiff = currentStackPointer()

start: PtrDiff = stack
end: PtrDiff = stack + requestedStackSize

stackMovesUp := (p2 > p1)
if(stackMovesUp) { // like x86
end - p1
} else { // like OSX on PPC
p1 - start
}
}

stackSpaceAlmostGone: func -> Bool {
bytesLeftOnStack() < MIN_STACK_SIZE
}

initializeMainCoro: func {
isMain = true
}

startCoro: func (other: This, callback: Func) {
other allocStackIfNeeded()
other setup(callback)
switchTo(other)
}

setup: func (callback: Func) {
getcontext(env&)

env stack stackPointer = stack + requestedStackSize - 8
env stack stackSize = requestedStackSize
env stack flags = 0
env link = null

"Setting up Closure %p, callback thunk/context = %p/%p, env& = %p" printfln(this, callback as Closure thunk, callback as Closure context, env&)
makecontext(env&, callback as Closure thunk, 1, callback as Closure context)
}

switchTo: func (next: This) {
swapcontext(env&, next env&)
}

}

/* ------ C interfacing ------- */

include ucontext

StackT: cover from stack_t {
stackPointer: extern(ss_sp) Pointer
flags: extern(ss_flags) Int
stackSize: extern(ss_size) SizeT
}

UContext: cover from ucontext_t {
stack: extern(uc_stack) StackT
link: extern(uc_link) Pointer
}

getcontext: extern func (ucp: UContext*) -> Int
setcontext: extern func (ucp: UContext*) -> Int
makecontext: extern func (ucp: UContext*, _func: Pointer, argc: Int, ...)
swapcontext: extern func (oucp: UContext*, ucp: UContext*) -> Int














0 comments on commit f3cf821

Please sign in to comment.