PageRenderTime 1514ms CodeModel.GetById 1499ms RepoModel.GetById 1ms app.codeStats 0ms

/source/core/frontend/ParsingPool.ooc

http://github.com/nddrylliog/oc
Unknown | 125 lines | 98 code | 27 blank | 0 comment | 0 complexity | 53f0364ca5c67579171e1ae3d51e055b MD5 | raw file
  1. import Frontend, BuildParams
  2. import ast/[Module, Import]
  3. import middle/Resolver
  4. import ../DynamicLoader
  5. import threading/Thread, structs/[List, ArrayList], os/[Time, System]
  6. ParsingJob: class {
  7. path: String
  8. module: Module
  9. _import: Import
  10. init: func (=path, =_import) {}
  11. }
  12. ParsingPool: class {
  13. todo := ArrayList<ParsingJob> new()
  14. done := ArrayList<ParsingJob> new()
  15. workers := ArrayList<ParserWorker> new()
  16. factory: FrontendFactory
  17. active := true
  18. doneMutex, todoMutex: Mutex
  19. init: func (params: BuildParams) {
  20. doneMutex = Mutex new()
  21. todoMutex = Mutex new()
  22. factory = DynamicLoader loadFrontend(params frontendString, params, this)
  23. if(!factory) {
  24. fprintf(stderr, "Couldn't load frontend nagaqueen, bailing out\n")
  25. exit(1)
  26. }
  27. }
  28. push: func (j: ParsingJob) {
  29. todoMutex lock()
  30. todo add(j)
  31. todoMutex unlock()
  32. }
  33. done: func (j: ParsingJob) {
  34. doneMutex lock()
  35. done add(j)
  36. doneMutex unlock()
  37. }
  38. pop: func -> ParsingJob {
  39. job: ParsingJob = null
  40. todoMutex lock()
  41. if(todo size > 0) {
  42. job = todo removeAt(0)
  43. } else {
  44. stillActive := false
  45. workers each(|worker|
  46. if(worker busy) {
  47. // still might have a chance of getting an import
  48. stillActive = true
  49. }
  50. )
  51. active = stillActive
  52. }
  53. todoMutex unlock()
  54. job
  55. }
  56. exhaust: func {
  57. active = true
  58. numCores := numProcessors()
  59. for(i in 0..(numCores + 1)) {
  60. worker := ParserWorker new(this). run()
  61. workers add(worker)
  62. }
  63. while (active) {
  64. Time sleepMilli(10)
  65. }
  66. }
  67. }
  68. ParserWorker: class {
  69. idSeed : static Int = 0
  70. id: Int
  71. busy := false
  72. pool: ParsingPool
  73. init: func (=pool) {
  74. idSeed += 1
  75. id = idSeed
  76. }
  77. run: func {
  78. Thread new(||
  79. //"Born [%d]" printfln(id)
  80. while (pool active) {
  81. job := pool pop()
  82. if(job) {
  83. busy = true
  84. "Parsing %s [%d]" printfln(job path, id)
  85. builder := pool factory create()
  86. builder parse(job path)
  87. job module = builder module
  88. if(job _import) job _import module = builder module
  89. pool done(job)
  90. busy = false
  91. } else {
  92. Time sleepMilli(10)
  93. }
  94. }
  95. //"Dying [%d]" printfln(id)
  96. ) start()
  97. }
  98. }