summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2017-12-14 10:55:12 +0100
committerAndreas Rumpf <rumpf_a@web.de>2017-12-14 10:55:12 +0100
commitbc1123536e36a222dc3bf65c40c6ceee07da6499 (patch)
tree5c2f45f3beabbe0720913b0fe14feae4f2326188 /lib
parentbe16dfd19576ac972031006bbfdb1c881ab4fdfd (diff)
parent9e87531f041525b23ca12c7886412d762930005a (diff)
downloadNim-bc1123536e36a222dc3bf65c40c6ceee07da6499.tar.gz
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib')
-rw-r--r--lib/js/dom.nim4
-rw-r--r--lib/pure/collections/tables.nim9
-rw-r--r--lib/system/genodealloc.nim114
-rw-r--r--lib/system/osalloc.nim12
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