diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-12-14 10:55:12 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-12-14 10:55:12 +0100 |
commit | bc1123536e36a222dc3bf65c40c6ceee07da6499 (patch) | |
tree | 5c2f45f3beabbe0720913b0fe14feae4f2326188 /lib | |
parent | be16dfd19576ac972031006bbfdb1c881ab4fdfd (diff) | |
parent | 9e87531f041525b23ca12c7886412d762930005a (diff) | |
download | Nim-bc1123536e36a222dc3bf65c40c6ceee07da6499.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib')
-rw-r--r-- | lib/js/dom.nim | 4 | ||||
-rw-r--r-- | lib/pure/collections/tables.nim | 9 | ||||
-rw-r--r-- | lib/system/genodealloc.nim | 114 | ||||
-rw-r--r-- | lib/system/osalloc.nim | 12 |
4 files changed, 124 insertions, 15 deletions
diff --git a/lib/js/dom.nim b/lib/js/dom.nim index cdefc772c..aa7f5d839 100644 --- a/lib/js/dom.nim +++ b/lib/js/dom.nim @@ -134,9 +134,9 @@ type # https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement HtmlElement* = ref object of Element - contentEditable*: string + contentEditable*: cstring isContentEditable*: bool - dir*: string + dir*: cstring offsetHeight*: int offsetWidth*: int offsetLeft*: int diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 48f8eed67..28fbaa632 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -993,9 +993,10 @@ proc inc*[A](t: var CountTable[A], key: A, val = 1) = proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] = ## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n) assert t.len > 0 - var minIdx = 0 + var minIdx = -1 for h in 1..high(t.data): - if t.data[h].val > 0 and t.data[minIdx].val > t.data[h].val: minIdx = h + if t.data[h].val > 0 and (minIdx == -1 or t.data[minIdx].val > t.data[h].val): + minIdx = h result.key = t.data[minIdx].key result.val = t.data[minIdx].val @@ -1329,3 +1330,7 @@ when isMainModule: assert((a == b) == true) assert((b == a) == true) + block: # CountTable.smallest + var t = initCountTable[int]() + for v in items([4, 4, 5, 5, 5]): t.inc(v) + doAssert t.smallest == (4, 2) diff --git a/lib/system/genodealloc.nim b/lib/system/genodealloc.nim new file mode 100644 index 000000000..3646a842d --- /dev/null +++ b/lib/system/genodealloc.nim @@ -0,0 +1,114 @@ +# +# +# 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 diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index 444f11306..1ad4cf695 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -78,17 +78,7 @@ when defined(emscripten): munmap(mmapDescr.realPointer, mmapDescr.realSize) elif defined(genode): - - proc osAllocPages(size: int): pointer {. - importcpp: "genodeEnv->rm().attach(genodeEnv->ram().alloc(@))".} - - proc osTryAllocPages(size: int): pointer = - {.emit: """try {""".} - result = osAllocPages size - {.emit: """} catch (...) { }""".} - - proc osDeallocPages(p: pointer, size: int) {. - importcpp: "genodeEnv->rm().detach(#)".} + include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages elif defined(posix): const |