Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > Vthread > Vthread__Best_Effort_Msg__Bench
comparison c-ray-mt.c @ 1:3840d91821c4
VPThread version is working
| author | Merten Sach <msach@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 16 Aug 2011 20:31:31 +0200 |
| parents | 4ae1d7ffb1ae |
| children | 75c818c6cad1 |
comparison
equal
deleted
inserted
replaced
| 0:3390c1245541 | 1:c09da66b67c8 |
|---|---|
| 83 struct vec3 pos, targ; | 83 struct vec3 pos, targ; |
| 84 double fov; | 84 double fov; |
| 85 }; | 85 }; |
| 86 | 86 |
| 87 struct thread_data { | 87 struct thread_data { |
| 88 pthread_t tid; | 88 VirtProcr *VP; |
| 89 int sl_start, sl_count; | 89 int sl_start, sl_count; |
| 90 | |
| 91 uint32_t *pixels; | 90 uint32_t *pixels; |
| 92 }; | 91 }; |
| 92 typedef struct thread_data thread_data; | |
| 93 | 93 |
| 94 void render_scanline(int xsz, int ysz, int sl, uint32_t *fb, int samples); | 94 void render_scanline(int xsz, int ysz, int sl, uint32_t *fb, int samples); |
| 95 struct vec3 trace(struct ray ray, int depth); | 95 struct vec3 trace(struct ray ray, int depth); |
| 96 struct vec3 shade(struct sphere *obj, struct spoint *sp, int depth); | 96 struct vec3 shade(struct sphere *obj, struct spoint *sp, int depth); |
| 97 struct vec3 reflect(struct vec3 v, struct vec3 n); | 97 struct vec3 reflect(struct vec3 v, struct vec3 n); |
| 101 struct vec3 jitter(int x, int y, int s); | 101 struct vec3 jitter(int x, int y, int s); |
| 102 int ray_sphere(const struct sphere *sph, struct ray ray, struct spoint *sp); | 102 int ray_sphere(const struct sphere *sph, struct ray ray, struct spoint *sp); |
| 103 void load_scene(FILE *fp); | 103 void load_scene(FILE *fp); |
| 104 unsigned long get_msec(void); | 104 unsigned long get_msec(void); |
| 105 | 105 |
| 106 void *thread_func(void *tdata); | 106 void thread_func(void *tdata, VirtProcr *VProc); |
| 107 | 107 |
| 108 #define MAX_LIGHTS 16 /* maximum number of lights */ | 108 #define MAX_LIGHTS 16 /* maximum number of lights */ |
| 109 #define RAY_MAG 1000.0 /* trace rays of this magnitude */ | 109 #define RAY_MAG 1000.0 /* trace rays of this magnitude */ |
| 110 #define MAX_RAY_DEPTH 5 /* raytrace recursion limit */ | 110 #define MAX_RAY_DEPTH 5 /* raytrace recursion limit */ |
| 111 #define FOV 0.78539816 /* field of view in rads (pi/4) */ | 111 #define FOV 0.78539816 /* field of view in rads (pi/4) */ |
| 143 struct camera cam; | 143 struct camera cam; |
| 144 | 144 |
| 145 int thread_num = 1; | 145 int thread_num = 1; |
| 146 struct thread_data *threads; | 146 struct thread_data *threads; |
| 147 | 147 |
| 148 int start = 0; | 148 volatile int end = 0; |
| 149 pthread_mutex_t start_mutex = PTHREAD_MUTEX_INITIALIZER; | 149 volatile int start = 0; |
| 150 pthread_cond_t start_cond = PTHREAD_COND_INITIALIZER; | 150 int32 end_mutex, end_cond; |
| 151 int32 start_cond, start_mutex; | |
| 151 | 152 |
| 152 #define NRAN 1024 | 153 #define NRAN 1024 |
| 153 #define MASK (NRAN - 1) | 154 #define MASK (NRAN - 1) |
| 154 struct vec3 urand[NRAN]; | 155 struct vec3 urand[NRAN]; |
| 155 int irand[NRAN]; | 156 int irand[NRAN]; |
| 166 " -i <file> read from <file> instead of stdin\n" | 167 " -i <file> read from <file> instead of stdin\n" |
| 167 " -o <file> write to <file> instead of stdout\n" | 168 " -o <file> write to <file> instead of stdout\n" |
| 168 " -h this help screen\n\n" | 169 " -h this help screen\n\n" |
| 169 }; | 170 }; |
| 170 | 171 |
| 171 void raytrace(uint32_t *pixels); | 172 char __ProgrammName[] = "c-ray"; |
| 173 char __DataSet[255]; | |
| 174 | |
| 175 | |
| 176 void raytrace(void *pixels, VirtProcr *Vprocr); | |
| 172 | 177 |
| 173 int main(int argc, char **argv) { | 178 int main(int argc, char **argv) { |
| 174 int i; | 179 int i; |
| 175 uint32_t *pixels; | 180 uint32_t *pixels; |
| 176 double sl, sl_per_thread; | |
| 177 FILE *infile = stdin, *outfile = stdout; | 181 FILE *infile = stdin, *outfile = stdout; |
| 178 | 182 |
| 179 for(i=1; i<argc; i++) { | 183 for(i=1; i<argc; i++) { |
| 180 if(argv[i][0] == '-' && argv[i][2] == 0) { | 184 if(argv[i][0] == '-' && argv[i][2] == 0) { |
| 181 char *sep; | 185 char *sep; |
| 245 perror("pixel buffer allocation failed"); | 249 perror("pixel buffer allocation failed"); |
| 246 return EXIT_FAILURE; | 250 return EXIT_FAILURE; |
| 247 } | 251 } |
| 248 load_scene(infile); | 252 load_scene(infile); |
| 249 | 253 |
| 250 raytrace(pixels); | 254 //This is the transition to the VMS runtime |
| 255 VPThread__create_seed_procr_and_do_work(raytrace, (void*)pixels); | |
| 251 | 256 |
| 252 /* output statistics to stderr */ | 257 /* output statistics to stderr */ |
| 253 fprintf(stderr, "Rendering took: %lu seconds (%lu milliseconds)\n", rend_time / 1000, rend_time); | 258 fprintf(stderr, "Rendering took: %lu seconds (%lu milliseconds)\n", rend_time / 1000, rend_time); |
| 254 | 259 |
| 255 /* output the image */ | 260 /* output the image */ |
| 269 struct sphere *tmp = walker; | 274 struct sphere *tmp = walker; |
| 270 walker = walker->next; | 275 walker = walker->next; |
| 271 free(tmp); | 276 free(tmp); |
| 272 } | 277 } |
| 273 free(pixels); | 278 free(pixels); |
| 274 free(threads); | |
| 275 return 0; | 279 return 0; |
| 276 } | 280 } |
| 277 | 281 |
| 278 /* this is run after the VMS is set up*/ | 282 /* this is run after the VMS is set up*/ |
| 279 void raytrace(uint32_t *pixels) | 283 void raytrace(void *pixels, VirtProcr *VProc) |
| 280 { | 284 { |
| 281 int i; | 285 int i; |
| 282 double sl, sl_per_thread; | 286 double sl, sl_per_thread; |
| 283 | 287 |
| 284 /* initialize the random number tables for the jitter */ | 288 /* initialize the random number tables for the jitter */ |
| 289 if(thread_num > yres) { | 293 if(thread_num > yres) { |
| 290 fprintf(stderr, "more threads than scanlines specified, reducing number of threads to %d\n", yres); | 294 fprintf(stderr, "more threads than scanlines specified, reducing number of threads to %d\n", yres); |
| 291 thread_num = yres; | 295 thread_num = yres; |
| 292 } | 296 } |
| 293 | 297 |
| 294 if(!(threads = malloc(thread_num * sizeof *threads))) { | 298 |
| 299 if(!(threads = VPThread__malloc(thread_num * sizeof(thread_data), VProc))) { | |
| 295 perror("failed to allocate thread table"); | 300 perror("failed to allocate thread table"); |
| 296 exit(EXIT_FAILURE); | 301 exit(EXIT_FAILURE); |
| 297 } | 302 } |
| 298 | 303 |
| 304 end_mutex = VPThread__make_mutex(VProc); | |
| 305 end_cond = VPThread__make_cond(end_mutex, VProc); | |
| 306 start_mutex = VPThread__make_mutex(VProc); | |
| 307 start_cond = VPThread__make_cond(start_mutex, VProc); | |
| 308 | |
| 299 sl = 0.0; | 309 sl = 0.0; |
| 300 sl_per_thread = (double)yres / (double)thread_num; | 310 sl_per_thread = (double)yres / (double)thread_num; |
| 301 for(i=0; i<thread_num; i++) { | 311 for(i=0; i<thread_num; i++) { |
| 302 threads[i].sl_start = (int)sl; | 312 threads[i].sl_start = (int)sl; |
| 303 sl += sl_per_thread; | 313 sl += sl_per_thread; |
| 304 threads[i].sl_count = (int)sl - threads[i].sl_start; | 314 threads[i].sl_count = (int)sl - threads[i].sl_start; |
| 305 threads[i].pixels = pixels; | 315 threads[i].pixels = (uint32_t*)pixels; |
| 306 | 316 |
| 307 if(pthread_create(&threads[i].tid, 0, thread_func, &threads[i]) != 0) { | 317 threads[i].VP = |
| 308 perror("failed to spawn thread"); | 318 VPThread__create_thread((VirtProcrFnPtr)thread_func, |
| 309 exit(EXIT_FAILURE); | 319 (void*)(&threads[i]), VProc); |
| 310 } | |
| 311 } | 320 } |
| 321 | |
| 312 threads[thread_num - 1].sl_count = yres - threads[thread_num - 1].sl_start; | 322 threads[thread_num - 1].sl_count = yres - threads[thread_num - 1].sl_start; |
| 313 | 323 |
| 314 fprintf(stderr, VER_STR, VER_MAJOR, VER_MINOR); | 324 fprintf(stderr, VER_STR, VER_MAJOR, VER_MINOR); |
| 315 | 325 |
| 316 pthread_mutex_lock(&start_mutex); | 326 // start worker threads |
| 327 //printf("start of worker thread (%d)\n", VProc->procrID); | |
| 328 VPThread__mutex_lock(start_mutex, VProc); | |
| 317 start_time = get_msec(); | 329 start_time = get_msec(); |
| 318 start = 1; | 330 start = 1; |
| 319 pthread_cond_broadcast(&start_cond); | 331 for(i=0; i<thread_num; i++) |
| 320 pthread_mutex_unlock(&start_mutex); | 332 VPThread__cond_signal(start_cond, VProc); |
| 321 | 333 VPThread__mutex_unlock(start_mutex, VProc); |
| 322 for(i=0; i<thread_num; i++) { | 334 |
| 323 pthread_join(threads[i].tid, 0); | 335 //printf("wait for worker (%d)\n", VProc->procrID); |
| 324 } | 336 VPThread__mutex_lock(end_mutex, VProc); |
| 337 while(end < thread_num) | |
| 338 VPThread__cond_wait(end_cond, VProc); | |
| 339 VPThread__mutex_unlock(end_mutex, VProc); | |
| 340 | |
| 325 rend_time = get_msec() - start_time; | 341 rend_time = get_msec() - start_time; |
| 342 | |
| 343 VPThread__free(threads,VProc); | |
| 344 VPThread__dissipate_thread(VProc); | |
| 326 } | 345 } |
| 327 | 346 |
| 328 /* render a frame of xsz/ysz dimensions into the provided framebuffer */ | 347 /* render a frame of xsz/ysz dimensions into the provided framebuffer */ |
| 329 void render_scanline(int xsz, int ysz, int sl, uint32_t *fb, int samples) { | 348 void render_scanline(int xsz, int ysz, int sl, uint32_t *fb, int samples) { |
| 330 int i, s; | 349 int i, s; |
| 672 } | 691 } |
| 673 #else | 692 #else |
| 674 #error "I don't know how to measure time on your platform" | 693 #error "I don't know how to measure time on your platform" |
| 675 #endif | 694 #endif |
| 676 | 695 |
| 677 void *thread_func(void *tdata) { | 696 void thread_func(void *tdata, VirtProcr *VProc) { |
| 678 int i; | 697 int i; |
| 679 struct thread_data *td = (struct thread_data*)tdata; | 698 struct thread_data *td = (struct thread_data*)tdata; |
| 680 | 699 |
| 681 pthread_mutex_lock(&start_mutex); | 700 VPThread__mutex_lock(start_mutex, VProc); |
| 682 while(!start) { | 701 while(!start) |
| 683 pthread_cond_wait(&start_cond, &start_mutex); | 702 VPThread__cond_wait(start_cond, VProc); |
| 684 } | 703 VPThread__mutex_unlock(start_mutex, VProc); |
| 685 pthread_mutex_unlock(&start_mutex); | 704 |
| 686 | |
| 687 for(i=0; i<td->sl_count; i++) { | 705 for(i=0; i<td->sl_count; i++) { |
| 688 render_scanline(xres, yres, i + td->sl_start, td->pixels, rays_per_pixel); | 706 render_scanline(xres, yres, i + td->sl_start, td->pixels, rays_per_pixel); |
| 689 } | 707 } |
| 690 | 708 |
| 691 return 0; | 709 VPThread__mutex_lock(end_mutex, VProc); |
| 692 } | 710 end++; |
| 711 VPThread__cond_signal(end_cond, VProc); | |
| 712 VPThread__mutex_unlock(end_mutex, VProc); | |
| 713 | |
| 714 VPThread__dissipate_thread(VProc); | |
| 715 } |
