Native access to Genode environment
Add a 'GenodeEnv' type and a 'componentConstructHook' to the system module. The 'componentConstructHook' allows for detection of POSIX style programs that exit implicitly or native Genode components that initialize to serve RPC requests and OS signals. This hook takes a 'GenodeEnv' argument so that the environment interface is passed cleanly to application code after globals are initialized. This is an typed pointer to a C++ object, procedures for accessing the environment will be available from a Nimble library and not included in the standard library. The standard library has an internal pointer to the environment object but this is not for external use, the undocumented global environment pointer has been removed.
This commit is contained in:
parent
bf394ed1a1
commit
22f714585b
10 changed files with 107 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