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  }