X-Git-Url: https://ruin.nu/git/?a=blobdiff_plain;f=src%2Fthreadgenesorter.cpp;h=d4fe06995d2d850298cb011346c3700668d88dce;hb=refs%2Fheads%2Fthreads;hp=a45988c21dcc4a14f7717a9ef7b07d9757f81179;hpb=623097444fac1993a86e6d73b203bc3c6d731c11;p=germs.git diff --git a/src/threadgenesorter.cpp b/src/threadgenesorter.cpp index a45988c..d4fe069 100644 --- a/src/threadgenesorter.cpp +++ b/src/threadgenesorter.cpp @@ -21,6 +21,12 @@ #include "threadgenesorter.h" #include "sortaction.h" +#include "genealgorithms.h" + +#include +#include + +#include using namespace std; /** @@ -69,15 +75,41 @@ void ThreadGeneSorter::join(){ } void ThreadGeneSorter::stop(){ + Mutex m(&_queuelock); _done = true; + pthread_cond_signal(&_waiting); } size_t ThreadGeneSorter::size(){ - //TODO: thread safety.. + Mutex m(&_solutionslock); return _solutions.size(); } -double progress(int time, int solutions = 1){ +bool ThreadGeneSorter::running(){ + return !_done; +} + +double ThreadGeneSorter::wait(time_t time, size_t solutions){ + + timeval now; + gettimeofday(&now, NULL); + timespec timeout; + timeout.tv_sec = now.tv_sec + time; + timeout.tv_nsec = 0; + + int err = 0; + + Mutex m(&_solutionslock); + size_t n = _solutions.size(); + + while (!_done && err != ETIMEDOUT + && _solutions.size() - n < solutions){ + err = pthread_cond_timedwait(&_addedSolution,&_solutionslock + , &timeout); + } + if (_solutions.size() == 0) + return 0.0; + return _solutions.top().first; } ThreadGeneSorter::SolutionsQueue ThreadGeneSorter::solutions(){ @@ -131,6 +163,7 @@ void ThreadGeneSorter::sorter(const GeneOrder& go){ } void ThreadGeneSorter::worker(){ + try{ while(!_done){ Mutex m(&_queuelock); @@ -146,6 +179,33 @@ void ThreadGeneSorter::worker(){ SortUnit su = _queue.top(); _queue.pop(); m.unlock(); + + size_t dist = inversionDistance(su._go); + if (dist == 0){ + Mutex m(&_solutionslock); + _solutions.push(pair(su._score,su._al)); + pthread_cond_broadcast(&_addedSolution); + continue;; + } + + ActionList act = safeActions(su._go); + if (act.size() > 0){ + set safe(act.begin(), act.end()); + for (set::iterator sa = safe.begin(); sa != safe.end(); ++sa){ + GeneOrder go(su._go); + ActionList al(su._al); + al.push_back(*sa); + (*sa)(go); + double score = su._score + _model.score(*sa,su._go); + Mutex m(&_queuelock); + _queue.push(SortUnit(score,go,al)); + } + pthread_cond_broadcast(&_addedTask); + } //TODO: Hurdles.. + + } + }catch(const bad_alloc& e){ + _done = true; } }