1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
#
#
# Nim's Runtime Library
# (c) Copyright 2012 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# Low level system locks and condition vars.
{.push stackTrace: off.}
when defined(Windows):
type
Handle = int
SysLock {.importc: "CRITICAL_SECTION",
header: "<windows.h>", final, pure.} = object # CRITICAL_SECTION in WinApi
DebugInfo: pointer
LockCount: int32
RecursionCount: int32
OwningThread: int
LockSemaphore: int
SpinCount: int
SysCond = Handle
{.deprecated: [THandle: Handle, TSysLock: SysLock, TSysCond: SysCond].}
proc initSysLock(L: var SysLock) {.importc: "InitializeCriticalSection",
header: "<windows.h>".}
## Initializes the lock `L`.
proc tryAcquireSysAux(L: var SysLock): int32 {.importc: "TryEnterCriticalSection",
header: "<windows.h>".}
## Tries to acquire the lock `L`.
proc tryAcquireSys(L: var SysLock): bool {.inline.} =
result = tryAcquireSysAux(L) != 0'i32
proc acquireSys(L: var SysLock) {.importc: "EnterCriticalSection",
header: "<windows.h>".}
## Acquires the lock `L`.
proc releaseSys(L: var SysLock) {.importc: "LeaveCriticalSection",
header: "<windows.h>".}
## Releases the lock `L`.
proc deinitSys(L: var SysLock) {.importc: "DeleteCriticalSection",
header: "<windows.h>".}
proc createEvent(lpEventAttributes: pointer,
bManualReset, bInitialState: int32,
lpName: cstring): SysCond {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "CreateEventA".}
proc closeHandle(hObject: Handle) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "CloseHandle".}
proc waitForSingleObject(hHandle: Handle, dwMilliseconds: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject", noSideEffect.}
proc signalSysCond(hEvent: SysCond) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "SetEvent".}
proc initSysCond(cond: var SysCond) {.inline.} =
cond = createEvent(nil, 0'i32, 0'i32, nil)
proc deinitSysCond(cond: var SysCond) {.inline.} =
closeHandle(cond)
proc waitSysCond(cond: var SysCond, lock: var SysLock) =
releaseSys(lock)
discard waitForSingleObject(cond, -1'i32)
acquireSys(lock)
proc waitSysCondWindows(cond: var SysCond) =
discard waitForSingleObject(cond, -1'i32)
elif defined(genode):
const
Header = "genode_cpp/syslocks.h"
type
SysLock {.importcpp: "Nim::SysLock", pure, final,
header: Header.} = object
SysCond {.importcpp: "Nim::SysCond", pure, final,
header: Header.} = object
proc initSysLock(L: var SysLock) = discard
proc deinitSys(L: var SysLock) = discard
proc acquireSys(L: var SysLock) {.noSideEffect, importcpp.}
proc tryAcquireSys(L: var SysLock): bool {.noSideEffect, importcpp.}
proc releaseSys(L: var SysLock) {.noSideEffect, importcpp.}
proc initSysCond(L: var SysCond) = discard
proc deinitSysCond(L: var SysCond) = discard
proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
noSideEffect, importcpp.}
proc signalSysCond(cond: var SysCond) {.
noSideEffect, importcpp.}
else:
type
SysLock {.importc: "pthread_mutex_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
abi: array[40 div sizeof(clong), clong]
SysLockAttr {.importc: "pthread_mutexattr_t", pure, final
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
abi: array[4 div sizeof(cint), cint] # actually a cint
SysCond {.importc: "pthread_cond_t", pure, final,
header: """#include <sys/types.h>
#include <pthread.h>""".} = object
when defined(linux) and defined(amd64):
abi: array[48 div sizeof(clonglong), clonglong]
SysLockType = distinct cint
proc initSysLock(L: var SysLock, attr: ptr SysLockAttr = nil) {.
importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
when insideRLocksModule:
proc SysLockType_Reentrant: SysLockType =
{.emit: "`result` = PTHREAD_MUTEX_RECURSIVE;".}
proc initSysLockAttr(a: var SysLockAttr) {.
importc: "pthread_mutexattr_init", header: "<pthread.h>", noSideEffect.}
proc setSysLockType(a: var SysLockAttr, t: SysLockType) {.
importc: "pthread_mutexattr_settype", header: "<pthread.h>", noSideEffect.}
proc acquireSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc tryAcquireSysAux(L: var SysLock): cint {.noSideEffect,
importc: "pthread_mutex_trylock", header: "<pthread.h>".}
proc tryAcquireSys(L: var SysLock): bool {.inline.} =
result = tryAcquireSysAux(L) == 0'i32
proc releaseSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
proc deinitSys(L: var SysLock) {.noSideEffect,
importc: "pthread_mutex_destroy", header: "<pthread.h>".}
when not insideRLocksModule:
proc initSysCond(cond: var SysCond, cond_attr: pointer = nil) {.
importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
proc waitSysCond(cond: var SysCond, lock: var SysLock) {.
importc: "pthread_cond_wait", header: "<pthread.h>", noSideEffect.}
proc signalSysCond(cond: var SysCond) {.
importc: "pthread_cond_signal", header: "<pthread.h>", noSideEffect.}
proc deinitSysCond(cond: var SysCond) {.noSideEffect,
importc: "pthread_cond_destroy", header: "<pthread.h>".}
{.pop.}
|