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