I've written my first small module that uses locks. My simple test seems to
work, but I have no experience with using locks in C/C++, so I thought I should
better ask anyway. Also, I had to realize that, "if you're lucky" bad code
still works (I used alloc instead of allocShared, and my first test worked
anyway...).
I'm skipping the test code, and the 'mylist' module to keep this short (and
because my test worked). newList() from "mylist" is like a fixed-size array, on
the shared heap.
import locks
import mylist
import typetraits
var mappingLock {.global.}: Lock
initLock(mappingLock)
# All registered types until now
var types {.global, guard: mappingLock.} = newList[cstring](0)
# Creates a copy of a (temporary) cstring into the shared-heap
proc copyCString(s: cstring, len: int): cstring =
result = cast[cstring](allocShared(len+1))
copyMem(cast[pointer](result), cast[pointer](s), len+1)
# Returns the ID of a type
proc typeID*(T: typedesc): uint16 =
let typName: cstring = T.name
withLock(mappingLock):
let size = len(types)
for i in 0..<size:
# == compares cstring like strcmp, not like pointers
if typName == types[i]:
return uint16(i)
assert(size < high(uint16).int32)
let newTypes = newList[cstring](size+1)
for i in 0..<size:
newTypes[i] = types[i]
newTypes[size] = copyCString(typName, len(typName))
types = newTypes
return uint16(size)
# Returns the name of a type, from it's ID
proc typeName*(id: uint16): cstring =
withLock(mappingLock):
let size = len(types)
assert(id.int32 < size)
return types[id.int32]
Finally, is there more documentation somewhere about "atomic" (or "volatile",
like in Java) usage? The Nim manual shows a short example of "atomicRead(x)",
but uses a "memoryReadBarrier()" procedure which doesn't seem to exist (Google
returned nothing on it, I assume this is "left as an exercise", but idk how it
should be implemented, as I have not used concurrency in C/C++ yet).