Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
bc1123536e
4 changed files with 124 additions and 15 deletions
|
|
@ -134,9 +134,9 @@ type
|
||||||
|
|
||||||
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
# https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement
|
||||||
HtmlElement* = ref object of Element
|
HtmlElement* = ref object of Element
|
||||||
contentEditable*: string
|
contentEditable*: cstring
|
||||||
isContentEditable*: bool
|
isContentEditable*: bool
|
||||||
dir*: string
|
dir*: cstring
|
||||||
offsetHeight*: int
|
offsetHeight*: int
|
||||||
offsetWidth*: int
|
offsetWidth*: int
|
||||||
offsetLeft*: int
|
offsetLeft*: int
|
||||||
|
|
|
||||||
|
|
@ -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] =
|
proc smallest*[A](t: CountTable[A]): tuple[key: A, val: int] =
|
||||||
## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n)
|
## returns the (key,val)-pair with the smallest `val`. Efficiency: O(n)
|
||||||
assert t.len > 0
|
assert t.len > 0
|
||||||
var minIdx = 0
|
var minIdx = -1
|
||||||
for h in 1..high(t.data):
|
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.key = t.data[minIdx].key
|
||||||
result.val = t.data[minIdx].val
|
result.val = t.data[minIdx].val
|
||||||
|
|
||||||
|
|
@ -1329,3 +1330,7 @@ when isMainModule:
|
||||||
assert((a == b) == true)
|
assert((a == b) == true)
|
||||||
assert((b == a) == 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
114
lib/system/genodealloc.nim
Normal 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
|
||||||
|
|
@ -78,17 +78,7 @@ when defined(emscripten):
|
||||||
munmap(mmapDescr.realPointer, mmapDescr.realSize)
|
munmap(mmapDescr.realPointer, mmapDescr.realSize)
|
||||||
|
|
||||||
elif defined(genode):
|
elif defined(genode):
|
||||||
|
include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages
|
||||||
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(#)".}
|
|
||||||
|
|
||||||
elif defined(posix):
|
elif defined(posix):
|
||||||
const
|
const
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue