ccgthreadvars.nim 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Thread var support for architectures that lack native support for
  10. ## thread local storage.
  11. # included from cgen.nim
  12. proc emulatedThreadVars(conf: ConfigRef): bool =
  13. result = {optThreads, optTlsEmulation} <= conf.globalOptions
  14. proc accessThreadLocalVar(p: BProc, s: PSym) =
  15. if emulatedThreadVars(p.config) and threadVarAccessed notin p.flags:
  16. p.flags.incl threadVarAccessed
  17. incl p.module.flags, usesThreadVars
  18. p.procSec(cpsLocals).addVar(kind = Local,
  19. name = "NimTV_",
  20. typ = ptrType("NimThreadVars"))
  21. p.procSec(cpsInit).addAssignment("NimTV_",
  22. cCast(ptrType("NimThreadVars"),
  23. cCall(cgsymValue(p.module, "GetThreadLocalVars"))))
  24. proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
  25. if emulatedThreadVars(m.config):
  26. # we gather all thread locals var into a struct; we need to allocate
  27. # storage for that somehow, can't use the thread local storage
  28. # allocator for it :-(
  29. if not containsOrIncl(m.g.nimtvDeclared, s.id):
  30. m.g.nimtvDeps.add(s.loc.t)
  31. m.g.nimtv.addField(name = s.loc.snippet, typ = getTypeDesc(m, s.loc.t))
  32. else:
  33. let vis =
  34. if isExtern: Extern
  35. elif lfExportLib in s.loc.flags: ExportLibVar
  36. else: Private
  37. m.s[cfsVars].addVar(m, s,
  38. name = s.loc.snippet,
  39. typ = getTypeDesc(m, s.loc.t),
  40. kind = Threadvar,
  41. visibility = vis)
  42. proc generateThreadLocalStorage(m: BModule) =
  43. if m.g.nimtv.buf.len != 0 and (usesThreadVars in m.flags or sfMainModule in m.module.flags):
  44. for t in items(m.g.nimtvDeps): discard getTypeDesc(m, t)
  45. finishTypeDescriptions(m)
  46. m.s[cfsSeqTypes].addTypedef(name = "NimThreadVars"):
  47. m.s[cfsSeqTypes].addSimpleStruct(m, name = "", baseType = ""):
  48. m.s[cfsSeqTypes].add(extract(m.g.nimtv))
  49. proc generateThreadVarsSize(m: BModule) =
  50. if m.g.nimtv.buf.len != 0:
  51. let externc = if m.config.backend == backendCpp or
  52. sfCompileToCpp in m.module.flags: ExternC
  53. else: None
  54. m.s[cfsProcs].addDeclWithVisibility(externc):
  55. m.s[cfsProcs].addProcHeader("NimThreadVarsSize", NimInt, cProcParams())
  56. m.s[cfsProcs].finishProcHeaderWithBody():
  57. m.s[cfsProcs].addReturn(cCast(NimInt, cSizeof("NimThreadVars")))