Merge branch 'devel' of github.com:nim-lang/Nim into devel

This commit is contained in:
Andreas Rumpf
2017-12-14 10:55:12 +01:00
4 changed files with 124 additions and 15 deletions

View File

@@ -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

View File

@@ -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)

114
lib/system/genodealloc.nim Normal file
View File

@@ -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

View File

@@ -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