Merge pull request #7873 from ehmry/GenodeEnv
Native access to Genode environment
This commit is contained in:
commit
e00e7fec54
11 changed files with 111 additions and 37 deletions
|
|
@ -1,114 +0,0 @@
|
|||
#
|
||||
#
|
||||
# Nim's Runtime Library
|
||||
# (c) Copyright 2017 Emery Hemingway
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# Low level dataspace allocator for Genode.
|
||||
|
||||
when not defined(genode):
|
||||
{.error: "Genode only module".}
|
||||
|
||||
type DataspaceCapability {.
|
||||
importcpp: "Genode::Dataspace_capability", pure.} = object
|
||||
|
||||
type
|
||||
Map = object
|
||||
attachment: pointer
|
||||
size: int
|
||||
ds: DataspaceCapability
|
||||
|
||||
SlabMeta = object
|
||||
next: ptr MapSlab
|
||||
ds: DataspaceCapability
|
||||
|
||||
MapSlab = object
|
||||
meta: SlabMeta
|
||||
maps: array[1,Map]
|
||||
|
||||
const SlabBackendSize = 4096
|
||||
|
||||
proc ramAvail(): int {.
|
||||
importcpp: "genodeEnv->pd().avail_ram().value".}
|
||||
## Return number of bytes available for allocation.
|
||||
|
||||
proc capsAvail(): int {.
|
||||
importcpp: "genodeEnv->pd().avail_caps().value".}
|
||||
## Return the number of available capabilities.
|
||||
## Each dataspace allocation consumes a capability.
|
||||
|
||||
proc allocDataspace(size: int): DataspaceCapability {.
|
||||
importcpp: "genodeEnv->pd().alloc(@)".}
|
||||
## Allocate a dataspace and its capability.
|
||||
|
||||
proc attachDataspace(ds: DataspaceCapability): pointer {.
|
||||
importcpp: "genodeEnv->rm().attach(@)".}
|
||||
## Attach a dataspace into the component address-space.
|
||||
|
||||
proc detachAddress(p: pointer) {.
|
||||
importcpp: "genodeEnv->rm().detach(@)".}
|
||||
## Detach a dataspace from the component address-space.
|
||||
|
||||
proc freeDataspace(ds: DataspaceCapability) {.
|
||||
importcpp: "genodeEnv->pd().free(@)".}
|
||||
## Free a dataspace.
|
||||
|
||||
proc newMapSlab(): ptr MapSlab =
|
||||
let
|
||||
ds = allocDataspace SlabBackendSize
|
||||
p = attachDataspace ds
|
||||
result = cast[ptr MapSlab](p)
|
||||
result.meta.ds = ds
|
||||
|
||||
iterator items(s: ptr MapSlab): ptr Map =
|
||||
let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map)
|
||||
for i in 0 .. <mapCount:
|
||||
yield s.maps[i].addr
|
||||
|
||||
var slabs: ptr MapSlab
|
||||
|
||||
proc osAllocPages(size: int): pointer =
|
||||
if slabs.isNil:
|
||||
slabs = newMapSlab()
|
||||
var
|
||||
slab = slabs
|
||||
map: ptr Map
|
||||
let mapCount = (SlabBackendSize - sizeof(SlabMeta)) div sizeof(Map)
|
||||
block findFreeMap:
|
||||
while true:
|
||||
# lookup first free spot in slabs
|
||||
for m in slab.items:
|
||||
if m.attachment.isNil:
|
||||
map = m
|
||||
break findFreeMap
|
||||
if slab.meta.next.isNil:
|
||||
slab.meta.next = newMapSlab()
|
||||
# tack a new slab on the tail
|
||||
slab = slab.meta.next
|
||||
# move to next slab in linked list
|
||||
map.ds = allocDataspace size
|
||||
map.size = size
|
||||
map.attachment = attachDataspace map.ds
|
||||
result = map.attachment
|
||||
|
||||
proc osTryAllocPages(size: int): pointer =
|
||||
if ramAvail() >= size and capsAvail() > 1:
|
||||
result = osAllocPages size
|
||||
|
||||
proc osDeallocPages(p: pointer; size: int) =
|
||||
var slab = slabs
|
||||
while not slab.isNil:
|
||||
# lookup first free spot in slabs
|
||||
for m in slab.items:
|
||||
if m.attachment == p:
|
||||
if m.size != size:
|
||||
echo "cannot partially detach dataspace"
|
||||
quit -1
|
||||
detachAddress m.attachment
|
||||
freeDataspace m.ds
|
||||
m[] = Map()
|
||||
return
|
||||
slab = slab.meta.next
|
||||
|
|
@ -78,7 +78,7 @@ when defined(emscripten):
|
|||
munmap(mmapDescr.realPointer, mmapDescr.realSize)
|
||||
|
||||
elif defined(genode):
|
||||
include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages
|
||||
include genode/alloc # osAllocPages, osTryAllocPages, osDeallocPages
|
||||
|
||||
elif defined(posix):
|
||||
const
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ when defined(windows):
|
|||
importc: "SetThreadAffinityMask", stdcall, header: "<windows.h>".}
|
||||
|
||||
elif defined(genode):
|
||||
import genode/env
|
||||
const
|
||||
GenodeHeader = "genode_cpp/threads.h"
|
||||
type
|
||||
|
|
@ -125,11 +126,12 @@ elif defined(genode):
|
|||
ThreadVarSlot = int
|
||||
|
||||
proc initThread(s: var SysThread,
|
||||
env: GenodeEnv,
|
||||
stackSize: culonglong,
|
||||
entry: GenodeThreadProc,
|
||||
arg: pointer,
|
||||
affinity: cuint) {.
|
||||
importcpp: "#.initThread(genodeEnv, @)".}
|
||||
importcpp: "#.initThread(@)".}
|
||||
|
||||
proc threadVarAlloc(): ThreadVarSlot = 0
|
||||
|
||||
|
|
@ -569,7 +571,7 @@ when hostOS == "windows":
|
|||
|
||||
elif defined(genode):
|
||||
var affinityOffset: cuint = 1
|
||||
# CPU affinity offset for next thread, safe to roll-over
|
||||
## CPU affinity offset for next thread, safe to roll-over
|
||||
|
||||
proc createThread*[TArg](t: var Thread[TArg],
|
||||
tp: proc (arg: TArg) {.thread, nimcall.},
|
||||
|
|
@ -580,6 +582,7 @@ elif defined(genode):
|
|||
t.dataFn = tp
|
||||
when hasSharedHeap: t.stackSize = ThreadStackSize
|
||||
t.sys.initThread(
|
||||
runtimeEnv,
|
||||
ThreadStackSize.culonglong,
|
||||
threadProcWrapper[TArg], addr(t), affinityOffset)
|
||||
inc affinityOffset
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue