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