pthread_key_t is respected to be an opaque type ...
This commit is contained in:
parent
c70fa87471
commit
90ad118219
3 changed files with 18 additions and 17 deletions
|
|
@ -320,6 +320,7 @@ when isMainModule:
|
||||||
else: assert false
|
else: assert false
|
||||||
else:
|
else:
|
||||||
Aquire(L) # lock stdout
|
Aquire(L) # lock stdout
|
||||||
|
Aquire(M)
|
||||||
|
|
||||||
echo i
|
echo i
|
||||||
os.sleep(10)
|
os.sleep(10)
|
||||||
|
|
@ -327,7 +328,7 @@ when isMainModule:
|
||||||
echo "deadlocks prevented: ", deadlocksPrevented
|
echo "deadlocks prevented: ", deadlocksPrevented
|
||||||
when nodeadlocks:
|
when nodeadlocks:
|
||||||
Release(N)
|
Release(N)
|
||||||
Release(M)
|
Release(M)
|
||||||
Release(L)
|
Release(L)
|
||||||
|
|
||||||
InitLock(L)
|
InitLock(L)
|
||||||
|
|
@ -340,7 +341,7 @@ when isMainModule:
|
||||||
for i in 0..high(thr):
|
for i in 0..high(thr):
|
||||||
joinThread(thr[i])
|
joinThread(thr[i])
|
||||||
|
|
||||||
GC_disable()
|
#GC_disable()
|
||||||
main()
|
main()
|
||||||
GC_enable()
|
#GC_enable()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,21 +67,19 @@ when hasThreadSupport:
|
||||||
else:
|
else:
|
||||||
{.passL: "-pthread".}
|
{.passL: "-pthread".}
|
||||||
{.passC: "-pthread".}
|
{.passC: "-pthread".}
|
||||||
|
|
||||||
type
|
type
|
||||||
Tpthread_key {.importc: "pthread_key_t",
|
TThreadVarSlot {.importc: "pthread_key_t", pure, final,
|
||||||
header: "<sys/types.h>".} = distinct int32
|
header: "<sys/types.h>".} = object
|
||||||
TThreadVarSlot {.compilerproc.} = Tpthread_key
|
|
||||||
|
|
||||||
proc pthread_getspecific(a1: Tpthread_key): pointer {.
|
proc pthread_getspecific(a1: TThreadVarSlot): pointer {.
|
||||||
importc: "pthread_getspecific", header: "<pthread.h>".}
|
importc: "pthread_getspecific", header: "<pthread.h>".}
|
||||||
proc pthread_key_create(a1: ptr Tpthread_key,
|
proc pthread_key_create(a1: ptr TThreadVarSlot,
|
||||||
destruct: proc (x: pointer) {.noconv.}): int32 {.
|
destruct: proc (x: pointer) {.noconv.}): int32 {.
|
||||||
importc: "pthread_key_create", header: "<pthread.h>".}
|
importc: "pthread_key_create", header: "<pthread.h>".}
|
||||||
proc pthread_key_delete(a1: Tpthread_key): int32 {.
|
proc pthread_key_delete(a1: TThreadVarSlot): int32 {.
|
||||||
importc: "pthread_key_delete", header: "<pthread.h>".}
|
importc: "pthread_key_delete", header: "<pthread.h>".}
|
||||||
|
|
||||||
proc pthread_setspecific(a1: Tpthread_key, a2: pointer): int32 {.
|
proc pthread_setspecific(a1: TThreadVarSlot, a2: pointer): int32 {.
|
||||||
importc: "pthread_setspecific", header: "<pthread.h>".}
|
importc: "pthread_setspecific", header: "<pthread.h>".}
|
||||||
|
|
||||||
proc specificDestroy(mem: pointer) {.noconv.} =
|
proc specificDestroy(mem: pointer) {.noconv.} =
|
||||||
|
|
@ -112,11 +110,12 @@ when hasThreadSupport:
|
||||||
data: float # compiler should add thread local variables here!
|
data: float # compiler should add thread local variables here!
|
||||||
PGlobals* = ptr TGlobals
|
PGlobals* = ptr TGlobals
|
||||||
|
|
||||||
# it's more efficient to not use a global variable for the thread storage
|
# XXX it'd be more efficient to not use a global variable for the
|
||||||
# slot, but to rely on the implementation to assign slot 0 for us... ;-)
|
# thread storage slot, but to rely on the implementation to assign slot 0
|
||||||
var checkSlot = ThreadVarAlloc()
|
# for us... ;-)
|
||||||
const globalsSlot = TThreadVarSlot(0)
|
var globalsSlot = ThreadVarAlloc()
|
||||||
assert checkSlot.int == globalsSlot.int
|
#const globalsSlot = TThreadVarSlot(0)
|
||||||
|
#assert checkSlot.int == globalsSlot.int
|
||||||
|
|
||||||
proc NewGlobals(): PGlobals =
|
proc NewGlobals(): PGlobals =
|
||||||
result = cast[PGlobals](alloc0(sizeof(TGlobals)))
|
result = cast[PGlobals](alloc0(sizeof(TGlobals)))
|
||||||
|
|
|
||||||
3
todo.txt
3
todo.txt
|
|
@ -2,7 +2,8 @@
|
||||||
* make GC fully thread-safe; needs:
|
* make GC fully thread-safe; needs:
|
||||||
- global list of threads
|
- global list of threads
|
||||||
- thread must store its stack boundaries
|
- thread must store its stack boundaries
|
||||||
- GC must traverse these stacks
|
- GC must traverse these stacks: Even better each thread traverses its
|
||||||
|
stack! No need to stop if you can help the GC ;-)
|
||||||
- isOnStack() needs to take them into account (SLOW?)
|
- isOnStack() needs to take them into account (SLOW?)
|
||||||
- GC must stop the world
|
- GC must stop the world
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue