summary refs log tree commit diff stats
path: root/compiler/ccgthreadvars.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ccgthreadvars.nim')
-rw-r--r--compiler/ccgthreadvars.nim54
1 files changed, 54 insertions, 0 deletions
diff --git a/compiler/ccgthreadvars.nim b/compiler/ccgthreadvars.nim
new file mode 100644
index 000000000..e92e955c5
--- /dev/null
+++ b/compiler/ccgthreadvars.nim
@@ -0,0 +1,54 @@
+#
+#
+#           The Nimrod Compiler
+#        (c) Copyright 2011 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+## Thread var support for crappy architectures that lack native support for 
+## thread local storage.
+
+proc AccessThreadLocalVar(p: BProc, s: PSym) =
+  if optThreads in gGlobalOptions:
+    if platform.OS[targetOS].props.contains(ospLacksThreadVars):
+      if not p.ThreadVarAccessed:
+        p.ThreadVarAccessed = true
+        p.module.usesThreadVars = true
+        appf(p.s[cpsLocals], "NimThreadVars* NimTV;$n")
+        appcg(p, cpsInit, "NimTV=(NimThreadVars*)#GetThreadLocalVars();$n")
+
+var
+  nimtv: PRope # nimrod thread vars
+  nimtvDeps: seq[PType] = @[]
+  nimtvDeclared = initIntSet()
+
+proc emulatedThreadVars(): bool {.inline.} =
+  result = optThreads in gGlobalOptions and
+    platform.OS[targetOS].props.contains(ospLacksThreadVars)
+
+proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
+  if emulatedThreadVars():
+    # we gather all thread locals var into a struct; we need to allocate
+    # storage for that somehow, can't use the thread local storage
+    # allocator for it :-(
+    if not containsOrIncl(nimtvDeclared, s.id):
+      nimtvDeps.add(s.loc.t)
+      appf(nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
+  else:
+    if isExtern: app(m.s[cfsVars], "extern ")
+    if optThreads in gGlobalOptions: app(m.s[cfsVars], "NIM_THREADVAR ")
+    app(m.s[cfsVars], getTypeDesc(m, s.loc.t))
+    appf(m.s[cfsVars], " $1;$n", [s.loc.r])
+  
+proc generateThreadLocalStorage(m: BModule) =
+  if nimtv != nil and (m.usesThreadVars or sfMainModule in m.module.flags):
+    for t in items(nimtvDeps): discard getTypeDesc(m, t)
+    appf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv])
+
+proc GenerateThreadVarsSize(m: BModule) =
+  if nimtv != nil:
+    app(m.s[cfsProcs], 
+      "NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}" & tnl)
+