Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > Vthread > Vthread__C-Ray__Bench
diff 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 |
line diff
1.1 --- a/c-ray-mt.c Wed Aug 03 14:26:31 2011 +0200 1.2 +++ b/c-ray-mt.c Tue Aug 16 20:31:31 2011 +0200 1.3 @@ -85,11 +85,11 @@ 1.4 }; 1.5 1.6 struct thread_data { 1.7 - pthread_t tid; 1.8 + VirtProcr *VP; 1.9 int sl_start, sl_count; 1.10 - 1.11 uint32_t *pixels; 1.12 }; 1.13 +typedef struct thread_data thread_data; 1.14 1.15 void render_scanline(int xsz, int ysz, int sl, uint32_t *fb, int samples); 1.16 struct vec3 trace(struct ray ray, int depth); 1.17 @@ -103,7 +103,7 @@ 1.18 void load_scene(FILE *fp); 1.19 unsigned long get_msec(void); 1.20 1.21 -void *thread_func(void *tdata); 1.22 +void thread_func(void *tdata, VirtProcr *VProc); 1.23 1.24 #define MAX_LIGHTS 16 /* maximum number of lights */ 1.25 #define RAY_MAG 1000.0 /* trace rays of this magnitude */ 1.26 @@ -145,9 +145,10 @@ 1.27 int thread_num = 1; 1.28 struct thread_data *threads; 1.29 1.30 -int start = 0; 1.31 -pthread_mutex_t start_mutex = PTHREAD_MUTEX_INITIALIZER; 1.32 -pthread_cond_t start_cond = PTHREAD_COND_INITIALIZER; 1.33 +volatile int end = 0; 1.34 +volatile int start = 0; 1.35 +int32 end_mutex, end_cond; 1.36 +int32 start_cond, start_mutex; 1.37 1.38 #define NRAN 1024 1.39 #define MASK (NRAN - 1) 1.40 @@ -168,12 +169,15 @@ 1.41 " -h this help screen\n\n" 1.42 }; 1.43 1.44 -void raytrace(uint32_t *pixels); 1.45 +char __ProgrammName[] = "c-ray"; 1.46 +char __DataSet[255]; 1.47 + 1.48 + 1.49 +void raytrace(void *pixels, VirtProcr *Vprocr); 1.50 1.51 int main(int argc, char **argv) { 1.52 int i; 1.53 uint32_t *pixels; 1.54 - double sl, sl_per_thread; 1.55 FILE *infile = stdin, *outfile = stdout; 1.56 1.57 for(i=1; i<argc; i++) { 1.58 @@ -247,7 +251,8 @@ 1.59 } 1.60 load_scene(infile); 1.61 1.62 - raytrace(pixels); 1.63 + //This is the transition to the VMS runtime 1.64 + VPThread__create_seed_procr_and_do_work(raytrace, (void*)pixels); 1.65 1.66 /* output statistics to stderr */ 1.67 fprintf(stderr, "Rendering took: %lu seconds (%lu milliseconds)\n", rend_time / 1000, rend_time); 1.68 @@ -271,12 +276,11 @@ 1.69 free(tmp); 1.70 } 1.71 free(pixels); 1.72 - free(threads); 1.73 return 0; 1.74 } 1.75 1.76 /* this is run after the VMS is set up*/ 1.77 -void raytrace(uint32_t *pixels) 1.78 +void raytrace(void *pixels, VirtProcr *VProc) 1.79 { 1.80 int i; 1.81 double sl, sl_per_thread; 1.82 @@ -291,38 +295,53 @@ 1.83 thread_num = yres; 1.84 } 1.85 1.86 - if(!(threads = malloc(thread_num * sizeof *threads))) { 1.87 + 1.88 + if(!(threads = VPThread__malloc(thread_num * sizeof(thread_data), VProc))) { 1.89 perror("failed to allocate thread table"); 1.90 exit(EXIT_FAILURE); 1.91 } 1.92 - 1.93 + 1.94 + end_mutex = VPThread__make_mutex(VProc); 1.95 + end_cond = VPThread__make_cond(end_mutex, VProc); 1.96 + start_mutex = VPThread__make_mutex(VProc); 1.97 + start_cond = VPThread__make_cond(start_mutex, VProc); 1.98 + 1.99 sl = 0.0; 1.100 sl_per_thread = (double)yres / (double)thread_num; 1.101 for(i=0; i<thread_num; i++) { 1.102 threads[i].sl_start = (int)sl; 1.103 sl += sl_per_thread; 1.104 threads[i].sl_count = (int)sl - threads[i].sl_start; 1.105 - threads[i].pixels = pixels; 1.106 + threads[i].pixels = (uint32_t*)pixels; 1.107 1.108 - if(pthread_create(&threads[i].tid, 0, thread_func, &threads[i]) != 0) { 1.109 - perror("failed to spawn thread"); 1.110 - exit(EXIT_FAILURE); 1.111 - } 1.112 + threads[i].VP = 1.113 + VPThread__create_thread((VirtProcrFnPtr)thread_func, 1.114 + (void*)(&threads[i]), VProc); 1.115 } 1.116 + 1.117 threads[thread_num - 1].sl_count = yres - threads[thread_num - 1].sl_start; 1.118 - 1.119 + 1.120 fprintf(stderr, VER_STR, VER_MAJOR, VER_MINOR); 1.121 - 1.122 - pthread_mutex_lock(&start_mutex); 1.123 + 1.124 + // start worker threads 1.125 + //printf("start of worker thread (%d)\n", VProc->procrID); 1.126 + VPThread__mutex_lock(start_mutex, VProc); 1.127 start_time = get_msec(); 1.128 start = 1; 1.129 - pthread_cond_broadcast(&start_cond); 1.130 - pthread_mutex_unlock(&start_mutex); 1.131 - 1.132 - for(i=0; i<thread_num; i++) { 1.133 - pthread_join(threads[i].tid, 0); 1.134 - } 1.135 + for(i=0; i<thread_num; i++) 1.136 + VPThread__cond_signal(start_cond, VProc); 1.137 + VPThread__mutex_unlock(start_mutex, VProc); 1.138 + 1.139 + //printf("wait for worker (%d)\n", VProc->procrID); 1.140 + VPThread__mutex_lock(end_mutex, VProc); 1.141 + while(end < thread_num) 1.142 + VPThread__cond_wait(end_cond, VProc); 1.143 + VPThread__mutex_unlock(end_mutex, VProc); 1.144 + 1.145 rend_time = get_msec() - start_time; 1.146 + 1.147 + VPThread__free(threads,VProc); 1.148 + VPThread__dissipate_thread(VProc); 1.149 } 1.150 1.151 /* render a frame of xsz/ysz dimensions into the provided framebuffer */ 1.152 @@ -674,19 +693,23 @@ 1.153 #error "I don't know how to measure time on your platform" 1.154 #endif 1.155 1.156 -void *thread_func(void *tdata) { 1.157 +void thread_func(void *tdata, VirtProcr *VProc) { 1.158 int i; 1.159 struct thread_data *td = (struct thread_data*)tdata; 1.160 1.161 - pthread_mutex_lock(&start_mutex); 1.162 - while(!start) { 1.163 - pthread_cond_wait(&start_cond, &start_mutex); 1.164 - } 1.165 - pthread_mutex_unlock(&start_mutex); 1.166 - 1.167 + VPThread__mutex_lock(start_mutex, VProc); 1.168 + while(!start) 1.169 + VPThread__cond_wait(start_cond, VProc); 1.170 + VPThread__mutex_unlock(start_mutex, VProc); 1.171 + 1.172 for(i=0; i<td->sl_count; i++) { 1.173 render_scanline(xres, yres, i + td->sl_start, td->pixels, rays_per_pixel); 1.174 } 1.175 + 1.176 + VPThread__mutex_lock(end_mutex, VProc); 1.177 + end++; 1.178 + VPThread__cond_signal(end_cond, VProc); 1.179 + VPThread__mutex_unlock(end_mutex, VProc); 1.180 1.181 - return 0; 1.182 + VPThread__dissipate_thread(VProc); 1.183 }
