Some tweaks to Lua docs
[lsnes.git] / src / library / workthread.cpp
blob8d5c7cb4da41d1be47f46831bd260f0b3a25630f
1 #include "workthread.hpp"
2 #include <stdexcept>
3 #include <sys/time.h>
5 namespace
7 uint64_t ticks()
9 struct timeval tv;
10 gettimeofday(&tv, NULL);
11 return static_cast<uint64_t>(tv.tv_sec) * 1000000 + tv.tv_usec;
15 struct worker_thread_reflector
17 int operator()(worker_thread* x)
19 (*x)(42);
20 return 0;
24 worker_thread::worker_thread()
26 thread = NULL;
27 reflector = NULL;
28 workflag = 0;
29 busy = false;
30 waitamt_busy = 0;
31 waitamt_work = 0;
32 exception_caught = false;
33 exception_oom = false;
34 joined = false;
37 worker_thread::~worker_thread()
39 set_workflag(WORKFLAG_QUIT_REQUEST);
40 if(!joined && thread)
41 thread->join();
42 delete thread;
43 delete reflector;
46 void worker_thread::request_quit()
49 //If the thread isn't there yet, wait for it.
50 umutex_class h(mutex);
51 if(!thread)
52 condition.wait(h);
54 set_workflag(WORKFLAG_QUIT_REQUEST);
55 if(!joined)
56 thread->join();
57 joined = true;
60 void worker_thread::set_busy()
62 busy = true;
65 void worker_thread::clear_busy()
67 umutex_class h(mutex);
68 busy = false;
69 condition.notify_all();
72 void worker_thread::wait_busy()
74 umutex_class h(mutex);
75 if(busy) {
76 uint64_t tmp = ticks();
77 while(busy)
78 condition.wait(h);
79 waitamt_busy += (ticks() - tmp);
83 void worker_thread::rethrow()
85 if(exception_caught) {
86 if(exception_oom)
87 throw std::bad_alloc();
88 else
89 throw std::runtime_error(exception_text);
93 void worker_thread::set_workflag(uint32_t flag)
95 umutex_class h(mutex);
96 workflag |= flag;
97 condition.notify_all();
100 uint32_t worker_thread::clear_workflag(uint32_t flag)
102 umutex_class h(mutex);
103 uint32_t tmp = workflag;
104 workflag &= ~flag;
105 return tmp;
108 uint32_t worker_thread::wait_workflag()
110 umutex_class h(mutex);
111 if(!workflag) {
112 uint64_t tmp = ticks();
113 while(!workflag)
114 condition.wait(h);
115 waitamt_work += (ticks() - tmp);
117 return workflag;
120 std::pair<uint64_t, uint64_t> worker_thread::get_wait_count()
122 umutex_class h(mutex);
123 return std::make_pair(waitamt_busy, waitamt_work);
126 int worker_thread::operator()(int dummy)
128 try {
129 entry();
130 } catch(std::bad_alloc& e) {
131 exception_oom = true;
132 exception_caught = true;
133 return 1;
134 } catch(std::exception& e) {
135 exception_text = e.what();
136 exception_caught = true;
137 return 1;
139 return 0;
142 void worker_thread::fire()
144 reflector = new worker_thread_reflector;
145 thread = new thread_class(*reflector, this);