--- a/src/raytracer.cc Fri Mar 28 00:53:20 2008 +0100
+++ b/src/raytracer.cc Fri Mar 28 17:13:21 2008 +0100
@@ -396,39 +396,139 @@
}
#endif
+void *Raytracer::raytrace_worker(void *d)
+{
+ Raytracer *rt = (Raytracer*)d;
+ Sample *sample;
+ Colour col;
+ Ray ray;
+ for (;;)
+ {
+ cout<<"#worker "<<pthread_self()<<" locking queue"<<endl;
+ pthread_mutex_lock(&rt->sample_queue_mutex);
+ pthread_cond_signal(&rt->worker_ready_cond);
+
+ // if queue is empty, wait for samples
+ while (rt->sample_queue.empty()) {
+ if (rt->sample_queue_end)
+ {
+ cout<<"#worker "<<pthread_self()<<" end of queue, unlocking queue and exiting..."<<endl;
+ pthread_mutex_unlock(&rt->sample_queue_mutex);
+ pthread_exit(NULL);
+ }
+ cout<<"#worker "<<pthread_self()<<" waiting for cond"<<endl;
+ pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
+ }
+
+
+ sample = rt->sample_queue.front();
+ rt->sample_queue.pop();
+ cout<<"#worker "<<pthread_self()<<" unlocking queue"<<endl;
+ pthread_mutex_unlock(&rt->sample_queue_mutex);
+
+ // do the work
+ cout<<"#worker "<<pthread_self()<<" locking sampler (camera)"<<endl;
+ pthread_mutex_lock(&rt->sampler_mutex);
+ ray = rt->camera->makeRay(sample);
+ cout<<"#worker "<<pthread_self()<<" unlocking sampler (camera)"<<endl;
+ pthread_mutex_unlock(&rt->sampler_mutex);
+
+ cout<<"#worker "<<pthread_self()<<" ray tracing..."<<endl;
+ col = rt->raytrace(ray, 0, NULL);
+
+ // save the result
+ cout<<"#worker "<<pthread_self()<<" locking sampler"<<endl;
+ pthread_mutex_lock(&rt->sampler_mutex);
+ rt->sampler->saveSample(sample, col);
+ cout<<"#worker "<<pthread_self()<<" unlocking sampler"<<endl;
+ pthread_mutex_unlock(&rt->sampler_mutex);
+
+ delete sample;
+ }
+}
+
void Raytracer::render()
{
if (!sampler || !camera || !top)
return;
+ sample_queue_end = false;
+
// create workers
- // ...
+ dbgmsg(1, "* using %d threads\n", num_threads);
+ pthread_t threads[num_threads];
+ for (int t = 0; t < num_threads; t++)
+ {
+ int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this);
+ if (rc) {
+ dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
+ exit(1);
+ }
+ }
sampler->init();
int sampnum = 0;
+ cout<<"locking sampler"<<endl;
+ pthread_mutex_lock(&sampler_mutex);
while ( (sampnum = sampler->initSampleSet()) > 0 )
{
- Sample *sample, *prev = NULL;
- while ( (sample = sampler->nextSample(prev)) != NULL )
+ Sample *sample;
+ while ( (sample = sampler->nextSample()) != NULL )
{
- Ray ray = camera->makeRay(sample);
- //raystack->push(ray);
+ cout<<"unlocking sampler and locking queue"<<endl;
+ pthread_mutex_unlock(&sampler_mutex);
+ pthread_mutex_lock(&sample_queue_mutex);
+ sample_queue.push(sample);
- // in worker:
- Colour col = raytrace(ray, 0, NULL);
- sampler->saveSample(sample, col);
+ if (sample_queue.size() > 1000)
+ {
+ while (sample_queue.size() > 100)
+ {
+ pthread_cond_signal(&sample_queue_cond);
+ pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
+ }
+ }
- delete prev;
- prev = sample;
+ cout<<"sending signal and unlocking queue"<<endl;
+ pthread_cond_signal(&sample_queue_cond);
+ pthread_mutex_unlock(&sample_queue_mutex);
+
sampnum--;
if ((sampnum % 1000) == 0)
dbgmsg(2, "\b\b\b\b\b\b\b\b%8d", sampnum);
+
+
+ cout<<"locking sampler"<<endl;
+ pthread_mutex_lock(&sampler_mutex);
}
dbgmsg(2, "\n");
}
+ cout<<"unlocking sampler"<<endl;
+ pthread_mutex_unlock(&sampler_mutex);
// wait for workers
- // ...
+ dbgmsg(2, "- waiting for threads to finish\n");
+
+ cout<<"locking queue"<<endl;
+ pthread_mutex_lock(&sample_queue_mutex);
+ sample_queue_end = true;
+ while (!sample_queue.empty())
+ {
+ cout<<"broadcasting signal and unlocking queue"<<endl;
+ pthread_cond_broadcast(&sample_queue_cond);
+ pthread_mutex_unlock(&sample_queue_mutex);
+ cout<<"locking queue"<<endl;
+ pthread_mutex_lock(&sample_queue_mutex);
+ }
+ cout<<"broadcasting signal and unlocking queue"<<endl;
+ pthread_cond_broadcast(&sample_queue_cond);
+ pthread_mutex_unlock(&sample_queue_mutex);
+
+ cout<<"joining threads"<<endl;
+ for (int t = 0; t < num_threads; t++)
+ pthread_join(threads[t], NULL);
+
+ cout<<"done!"<<endl;
#if 0