mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 10:22:15 +00:00
Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
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)
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user