394 #endif |
394 #endif |
395 return (void *)d; |
395 return (void *)d; |
396 } |
396 } |
397 #endif |
397 #endif |
398 |
398 |
|
399 void *Raytracer::raytrace_worker(void *d) |
|
400 { |
|
401 Raytracer *rt = (Raytracer*)d; |
|
402 Sample *sample; |
|
403 Colour col; |
|
404 Ray ray; |
|
405 for (;;) |
|
406 { |
|
407 cout<<"#worker "<<pthread_self()<<" locking queue"<<endl; |
|
408 pthread_mutex_lock(&rt->sample_queue_mutex); |
|
409 pthread_cond_signal(&rt->worker_ready_cond); |
|
410 |
|
411 // if queue is empty, wait for samples |
|
412 while (rt->sample_queue.empty()) { |
|
413 if (rt->sample_queue_end) |
|
414 { |
|
415 cout<<"#worker "<<pthread_self()<<" end of queue, unlocking queue and exiting..."<<endl; |
|
416 pthread_mutex_unlock(&rt->sample_queue_mutex); |
|
417 pthread_exit(NULL); |
|
418 } |
|
419 cout<<"#worker "<<pthread_self()<<" waiting for cond"<<endl; |
|
420 pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex); |
|
421 } |
|
422 |
|
423 |
|
424 sample = rt->sample_queue.front(); |
|
425 rt->sample_queue.pop(); |
|
426 cout<<"#worker "<<pthread_self()<<" unlocking queue"<<endl; |
|
427 pthread_mutex_unlock(&rt->sample_queue_mutex); |
|
428 |
|
429 // do the work |
|
430 cout<<"#worker "<<pthread_self()<<" locking sampler (camera)"<<endl; |
|
431 pthread_mutex_lock(&rt->sampler_mutex); |
|
432 ray = rt->camera->makeRay(sample); |
|
433 cout<<"#worker "<<pthread_self()<<" unlocking sampler (camera)"<<endl; |
|
434 pthread_mutex_unlock(&rt->sampler_mutex); |
|
435 |
|
436 cout<<"#worker "<<pthread_self()<<" ray tracing..."<<endl; |
|
437 col = rt->raytrace(ray, 0, NULL); |
|
438 |
|
439 // save the result |
|
440 cout<<"#worker "<<pthread_self()<<" locking sampler"<<endl; |
|
441 pthread_mutex_lock(&rt->sampler_mutex); |
|
442 rt->sampler->saveSample(sample, col); |
|
443 cout<<"#worker "<<pthread_self()<<" unlocking sampler"<<endl; |
|
444 pthread_mutex_unlock(&rt->sampler_mutex); |
|
445 |
|
446 delete sample; |
|
447 } |
|
448 } |
|
449 |
399 void Raytracer::render() |
450 void Raytracer::render() |
400 { |
451 { |
401 if (!sampler || !camera || !top) |
452 if (!sampler || !camera || !top) |
402 return; |
453 return; |
403 |
454 |
|
455 sample_queue_end = false; |
|
456 |
404 // create workers |
457 // create workers |
405 // ... |
458 dbgmsg(1, "* using %d threads\n", num_threads); |
|
459 pthread_t threads[num_threads]; |
|
460 for (int t = 0; t < num_threads; t++) |
|
461 { |
|
462 int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this); |
|
463 if (rc) { |
|
464 dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc); |
|
465 exit(1); |
|
466 } |
|
467 } |
406 |
468 |
407 sampler->init(); |
469 sampler->init(); |
408 int sampnum = 0; |
470 int sampnum = 0; |
|
471 cout<<"locking sampler"<<endl; |
|
472 pthread_mutex_lock(&sampler_mutex); |
409 while ( (sampnum = sampler->initSampleSet()) > 0 ) |
473 while ( (sampnum = sampler->initSampleSet()) > 0 ) |
410 { |
474 { |
411 Sample *sample, *prev = NULL; |
475 Sample *sample; |
412 while ( (sample = sampler->nextSample(prev)) != NULL ) |
476 while ( (sample = sampler->nextSample()) != NULL ) |
413 { |
477 { |
414 Ray ray = camera->makeRay(sample); |
478 cout<<"unlocking sampler and locking queue"<<endl; |
415 //raystack->push(ray); |
479 pthread_mutex_unlock(&sampler_mutex); |
416 |
480 pthread_mutex_lock(&sample_queue_mutex); |
417 // in worker: |
481 sample_queue.push(sample); |
418 Colour col = raytrace(ray, 0, NULL); |
482 |
419 sampler->saveSample(sample, col); |
483 if (sample_queue.size() > 1000) |
420 |
484 { |
421 delete prev; |
485 while (sample_queue.size() > 100) |
422 prev = sample; |
486 { |
|
487 pthread_cond_signal(&sample_queue_cond); |
|
488 pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex); |
|
489 } |
|
490 } |
|
491 |
|
492 cout<<"sending signal and unlocking queue"<<endl; |
|
493 pthread_cond_signal(&sample_queue_cond); |
|
494 pthread_mutex_unlock(&sample_queue_mutex); |
|
495 |
423 sampnum--; |
496 sampnum--; |
424 if ((sampnum % 1000) == 0) |
497 if ((sampnum % 1000) == 0) |
425 dbgmsg(2, "\b\b\b\b\b\b\b\b%8d", sampnum); |
498 dbgmsg(2, "\b\b\b\b\b\b\b\b%8d", sampnum); |
|
499 |
|
500 |
|
501 cout<<"locking sampler"<<endl; |
|
502 pthread_mutex_lock(&sampler_mutex); |
426 } |
503 } |
427 dbgmsg(2, "\n"); |
504 dbgmsg(2, "\n"); |
428 } |
505 } |
|
506 cout<<"unlocking sampler"<<endl; |
|
507 pthread_mutex_unlock(&sampler_mutex); |
429 |
508 |
430 // wait for workers |
509 // wait for workers |
431 // ... |
510 dbgmsg(2, "- waiting for threads to finish\n"); |
|
511 |
|
512 cout<<"locking queue"<<endl; |
|
513 pthread_mutex_lock(&sample_queue_mutex); |
|
514 sample_queue_end = true; |
|
515 while (!sample_queue.empty()) |
|
516 { |
|
517 cout<<"broadcasting signal and unlocking queue"<<endl; |
|
518 pthread_cond_broadcast(&sample_queue_cond); |
|
519 pthread_mutex_unlock(&sample_queue_mutex); |
|
520 cout<<"locking queue"<<endl; |
|
521 pthread_mutex_lock(&sample_queue_mutex); |
|
522 } |
|
523 cout<<"broadcasting signal and unlocking queue"<<endl; |
|
524 pthread_cond_broadcast(&sample_queue_cond); |
|
525 pthread_mutex_unlock(&sample_queue_mutex); |
|
526 |
|
527 cout<<"joining threads"<<endl; |
|
528 for (int t = 0; t < num_threads; t++) |
|
529 pthread_join(threads[t], NULL); |
|
530 |
|
531 cout<<"done!"<<endl; |
432 |
532 |
433 #if 0 |
533 #if 0 |
434 |
534 |
435 RenderrowData *d; |
535 RenderrowData *d; |
436 |
536 |