diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-06-09 09:38:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-09 09:38:53 +0200 |
commit | e00e7fec541220fcdd5c21c5a563a9bffe670b32 (patch) | |
tree | 864cd71d2213502c81b465e46a76753d158868c6 | |
parent | d4543500ee3be17f8c1738f271f2fe9fc23162c9 (diff) | |
parent | 5e54cd9fc9ce21311a4991f550e420f5bf1bd726 (diff) | |
download | Nim-e00e7fec541220fcdd5c21c5a563a9bffe670b32.tar.gz |
Merge pull request #7873 from ehmry/GenodeEnv
Native access to Genode environment
-rw-r--r-- | compiler/cgen.nim | 10 | ||||
-rw-r--r-- | lib/genode/alloc.nim (renamed from lib/system/genodealloc.nim) | 43 | ||||
-rw-r--r-- | lib/genode/env.nim | 29 | ||||
-rw-r--r-- | lib/genode_cpp/threads.h | 1 | ||||
-rw-r--r-- | lib/nimbase.h | 5 | ||||
-rw-r--r-- | lib/pure/concurrency/cpuinfo.nim | 8 | ||||
-rw-r--r-- | lib/pure/os.nim | 2 | ||||
-rw-r--r-- | lib/system.nim | 37 | ||||
-rw-r--r-- | lib/system/osalloc.nim | 2 | ||||
-rw-r--r-- | lib/system/threads.nim | 7 | ||||
-rw-r--r-- | lib/wrappers/openssl.nim | 4 |
11 files changed, 111 insertions, 37 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 6a16474c0..e749c78db 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1035,14 +1035,19 @@ proc genMainProc(m: BModule) = "}$N$N" GenodeNimMain = - "Libc::Env *genodeEnv;$N" & + "extern Genode::Env *nim_runtime_env;$N" & + "extern void nim_component_construct(Genode::Env*);$N$N" & NimMainBody ComponentConstruct = "void Libc::Component::construct(Libc::Env &env) {$N" & - "\tgenodeEnv = &env;$N" & + "\t// Set Env used during runtime initialization$N" & + "\tnim_runtime_env = &env;$N" & "\tLibc::with_libc([&] () {$N\t" & + "\t// Initialize runtime and globals$N" & MainProcs & + "\t// Call application construct$N" & + "\t\tnim_component_construct(&env);$N" & "\t});$N" & "}$N$N" @@ -1059,6 +1064,7 @@ proc genMainProc(m: BModule) = elif platform.targetOS == osGenode: nimMain = GenodeNimMain otherMain = ComponentConstruct + m.includeHeader("<libc/component.h>") elif optGenDynLib in m.config.globalOptions: nimMain = PosixNimDllMain otherMain = PosixCDllMain diff --git a/lib/system/genodealloc.nim b/lib/genode/alloc.nim index 3646a842d..52dc1c32c 100644 --- a/lib/system/genodealloc.nim +++ b/lib/genode/alloc.nim @@ -8,10 +8,15 @@ # # Low level dataspace allocator for Genode. +# For interacting with dataspaces outside of the +# standard library see the Genode Nimble package. when not defined(genode): {.error: "Genode only module".} +when not declared(GenodeEnv): + include genode/env + type DataspaceCapability {. importcpp: "Genode::Dataspace_capability", pure.} = object @@ -31,35 +36,35 @@ type const SlabBackendSize = 4096 -proc ramAvail(): int {. - importcpp: "genodeEnv->pd().avail_ram().value".} +proc ramAvail(env: GenodeEnv): int {. + importcpp: "#->pd().avail_ram().value".} ## Return number of bytes available for allocation. -proc capsAvail(): int {. - importcpp: "genodeEnv->pd().avail_caps().value".} +proc capsAvail(env: GenodeEnv): int {. + importcpp: "#->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(@)".} +proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {. + importcpp: "#->pd().alloc(@)".} ## Allocate a dataspace and its capability. -proc attachDataspace(ds: DataspaceCapability): pointer {. - importcpp: "genodeEnv->rm().attach(@)".} +proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {. + importcpp: "#->rm().attach(@)".} ## Attach a dataspace into the component address-space. -proc detachAddress(p: pointer) {. - importcpp: "genodeEnv->rm().detach(@)".} +proc detachAddress(env: GenodeEnv; p: pointer) {. + importcpp: "#->rm().detach(@)".} ## Detach a dataspace from the component address-space. -proc freeDataspace(ds: DataspaceCapability) {. - importcpp: "genodeEnv->pd().free(@)".} +proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {. + importcpp: "#->pd().free(@)".} ## Free a dataspace. proc newMapSlab(): ptr MapSlab = let - ds = allocDataspace SlabBackendSize - p = attachDataspace ds + ds = runtimeEnv.allocDataspace SlabBackendSize + p = runtimeEnv.attachDataspace ds result = cast[ptr MapSlab](p) result.meta.ds = ds @@ -89,13 +94,13 @@ proc osAllocPages(size: int): pointer = # tack a new slab on the tail slab = slab.meta.next # move to next slab in linked list - map.ds = allocDataspace size + map.ds = runtimeEnv.allocDataspace size map.size = size - map.attachment = attachDataspace map.ds + map.attachment = runtimeEnv.attachDataspace map.ds result = map.attachment proc osTryAllocPages(size: int): pointer = - if ramAvail() >= size and capsAvail() > 1: + if runtimeEnv.ramAvail() >= size and runtimeEnv.capsAvail() > 4: result = osAllocPages size proc osDeallocPages(p: pointer; size: int) = @@ -107,8 +112,8 @@ proc osDeallocPages(p: pointer; size: int) = if m.size != size: echo "cannot partially detach dataspace" quit -1 - detachAddress m.attachment - freeDataspace m.ds + runtimeEnv.detachAddress m.attachment + runtimeEnv.freeDataspace m.ds m[] = Map() return slab = slab.meta.next diff --git a/lib/genode/env.nim b/lib/genode/env.nim new file mode 100644 index 000000000..2b180d1b3 --- /dev/null +++ b/lib/genode/env.nim @@ -0,0 +1,29 @@ +# +# +# Nim's Runtime Library +# (c) Copyright 2018 Emery Hemingway +# +# See the file "copying.txt", included in this +# distribution, for details about the copyright. +# + +# +# This file contains the minimum required definitions +# for interacting with the initial Genode environment. +# It is reserved for use only within the standard +# library. See ``componentConstructHook`` in the system +# module for accessing the Genode environment after the +# standard library has finished initializating. +# + +when not defined(genode): + {.error: "Genode only include".} + +type + GenodeEnvObj {.importcpp: "Genode::Env", header: "<base/env.h>", pure.} = object + GenodeEnvPtr = ptr GenodeEnvObj + +const runtimeEnvSym = "nim_runtime_env" + +when not defined(nimscript): + var runtimeEnv {.importcpp: runtimeEnvSym.}: GenodeEnvPtr diff --git a/lib/genode_cpp/threads.h b/lib/genode_cpp/threads.h index a7cb2f17b..c901efb45 100644 --- a/lib/genode_cpp/threads.h +++ b/lib/genode_cpp/threads.h @@ -13,6 +13,7 @@ #define _GENODE_CPP__THREAD_H_ #include <base/thread.h> +#include <base/env.h> #include <util/reconstructible.h> namespace Nim { struct SysThread; } diff --git a/lib/nimbase.h b/lib/nimbase.h index 20ac9979b..6dc742910 100644 --- a/lib/nimbase.h +++ b/lib/nimbase.h @@ -502,11 +502,6 @@ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == siz # include <sys/types.h> #endif -#if defined(__GENODE__) -#include <libc/component.h> -extern Libc::Env *genodeEnv; -#endif - /* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */ #define NIM_CHECK_SIZE(typ, sz) \ _Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size") diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim index f01488811..6d41aa1b2 100644 --- a/lib/pure/concurrency/cpuinfo.nim +++ b/lib/pure/concurrency/cpuinfo.nim @@ -38,8 +38,10 @@ when defined(macosx) or defined(bsd): importc: "sysctl", nodecl.} when defined(genode): - proc affinitySpaceTotal(): cuint {. - importcpp: "genodeEnv->cpu().affinity_space().total()".} + include genode/env + + proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {. + importcpp: "@->cpu().affinity_space().total()".} proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = ## returns the numer of the processors/cores the machine has. @@ -83,7 +85,7 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} = var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint result = sysconf(SC_NPROC_ONLN) elif defined(genode): - result = affinitySpaceTotal().int + result = runtimeEnv.affinitySpaceTotal().int else: result = sysconf(SC_NPROCESSORS_ONLN) if result <= 0: result = 0 diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 04afb1eff..5008b904c 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1440,7 +1440,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} = elif defined(solaris): result = getApplAux("/proc/" & $getpid() & "/path/a.out") elif defined(genode): - raiseOSError("POSIX command line not supported") + raiseOSError(OSErrorCode(-1), "POSIX command line not supported") elif defined(freebsd) or defined(dragonfly): result = getApplFreebsd() # little heuristic that may work on other POSIX-like systems: diff --git a/lib/system.nim b/lib/system.nim index fee9dc314..fb02fde23 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1498,11 +1498,21 @@ when defined(nimdoc): ## macro, use the `error <manual.html#error-pragma>`_ or `fatal ## <manual.html#fatal-pragma>`_ pragmas. - elif defined(genode): - proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn, - importcpp: "genodeEnv->parent().exit(@); Genode::sleep_forever()", - header: "<base/sleep.h>".} + include genode/env + + var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr + + type GenodeEnv* = GenodeEnvPtr + ## Opaque type representing Genode environment. + + proc quit*(env: GenodeEnv; errorcode: int) {.magic: "Exit", noreturn, + importcpp: "#->parent().exit(@); Genode::sleep_forever()", header: "<base/sleep.h>".} + + proc quit*(errorcode: int = QuitSuccess) = + systemEnv.quit(errorCode) + + elif defined(nodejs): proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", @@ -4215,3 +4225,22 @@ when not defined(js): type ForLoopStmt* {.compilerProc.} = object ## special type that marks a macro ## as a `for-loop macro`:idx: + +when defined(genode): + var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.} + ## Hook into the Genode component bootstrap process. + ## This hook is called after all globals are initialized. + ## When this hook is set the component will not automatically exit, + ## call ``quit`` explicitly to do so. This is the only available method + ## of accessing the initial Genode environment. + + proc nim_component_construct(env: GenodeEnv) {.exportc.} = + ## Procedure called during ``Component::construct`` by the loader. + if componentConstructHook.isNil: + env.quit(programResult) + # No native Genode application initialization, + # exit as would POSIX. + else: + componentConstructHook(env) + # Perform application initialization + # and return to thread entrypoint. diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index 9609b6d39..a63eadf8e 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -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 diff --git a/lib/system/threads.nim b/lib/system/threads.nim index 861bde13f..c8ea03f92 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -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 diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim index a24575d11..de3bfa616 100644 --- a/lib/wrappers/openssl.nim +++ b/lib/wrappers/openssl.nim @@ -44,6 +44,10 @@ else: const DLLSSLName* = "libssl" & versions & ".dylib" DLLUtilName* = "libcrypto" & versions & ".dylib" + elif defined(genode): + const + DLLSSLName* = "libssl.lib.so" + DLLUtilName* = "libcrypto.lib.so" else: const DLLSSLName* = "libssl.so" & versions |