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 }