summaryrefslogtreecommitdiff
path: root/mthread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mthread.cpp')
-rw-r--r--mthread.cpp36
1 files changed, 35 insertions, 1 deletions
diff --git a/mthread.cpp b/mthread.cpp
index 796055e..269155d 100644
--- a/mthread.cpp
+++ b/mthread.cpp
@@ -46,7 +46,27 @@ void mthread::join() {
if((my_thread) && (my_thread->joinable())) my_thread->join();
}
+//TODO make final
+//looks for work
+void mthread::find_work() {
+}
+
+//makes sure no one is asking for work from us
+void mthread::check_work_request() {
+}
+
+//renders area
+void mthread::render_area() { //TODO rename
+}
+
+//alternates states of finding work work and rendering
+void mthread::run() {
+ for(;;) {
+ }
+}
+
+//TODO move syncronization to another function for extensibility
void mthread::render() {
uint32_t image_width = image.width();
unsigned int iter;
@@ -80,6 +100,7 @@ void mthread::render() {
progress++;
status.status_lock.lock();
status.row_load = y_max - on_y;
+ //check if anyone's asking us to divide
if(status.div_syn) {
status.div_error = status.row_load <= min_lines;
@@ -130,32 +151,45 @@ void mthread::render() {
status.share_finished = true;
status.status_lock.unlock();
+ //first we look over all workers to see which are canidates to ask for work
while(status.searching) {
workers_finished = 0;
+ //TODO do we really need this whole for loop?
for(worker = 0; worker < worker_cnt; worker++) {
+ //lock other worker so we can request from them
peer_status = &workers[worker]->status;
peer_status->status_lock.lock();
+ //if they're done, we remember that to see if we exit
if((peer_status->share_finished) && (worker != id)) {
workers_finished++;
}
+ //if they're us, currently looking for work,
+ //or don't have enough work for us to complete, then skip
+
if((worker == id) ||
(peer_status->searching) || (peer_status->div_syn) || (peer_status->row_load < min_lines)) {
loads[worker] = 0;
peer_status->status_lock.unlock();
continue;
}
+ //finally, if they're valid, write them down
loads[worker] = peer_status->row_load;
peer_status->status_lock.unlock();
}
+ //exit if all workers are finished
if(workers_finished >= worker_cnt - 1) {
return;
}
+ //then we look over and pick our canidates
for(;;) {
+ //find the worker who has the biggest workload
worker = distance(loads, max_element(loads, &loads[worker_cnt]));
- if(!loads[worker]) break;
+ if(!loads[worker]) break; //we have found a worker; distance is 0
peer_status = &workers[worker]->status;
peer_status->status_lock.lock();
+ //check to see if canidate is valid.
+ //TODO do we really need to check the first time?
if((peer_status->searching) || (peer_status->div_syn) || (peer_status->row_load < min_lines)) {
loads[worker] = 0;
peer_status->status_lock.unlock();