int main(int argc, char *argv[]) { mandelPars pars; int i,k,x,y,level,*res,check; int xoff,yoff, thrCheck; long double reStep,imStep; Toolbox **Tool; pthread_t *thrP; printf("\n"); printf("This program starts by drawing the default Mandelbrot region\n"); printf("When done, you can click with the mouse on an area of interest\n"); printf("and the program will zoom at this point\n"); printf("\n"); printf("Press enter to continue\n"); getchar(); pars.rePixels = WinW; /* never changes */ pars.imPixels = WinH; /* never changes */ /* default mandelbrot region */ pars.reBeg = (long double) -2.0; pars.reEnd = (long double) 1.0; pars.imBeg = (long double) -1.5; pars.imEnd = (long double) 1.5; reStep = (pars.reEnd - pars.reBeg) / pars.rePixels; imStep = (pars.imEnd - pars.imBeg) / pars.imPixels; printf("enter max iterations (50): "); scanf("%d",&pars.maxIterations); printf("enter no of slices: "); scanf("%d",&pars.slices); /* adjust slices to divide win height */ while (WinH % pars.slices != 0) { pars.slices++;} /* allocate result and ready arrays */ res = (int *) malloc(sizeof(int)*pars.rePixels*pars.imPixels); /* open window for drawing results */ openDisplay(); openWin(argv[0], WinW, WinH); level = 1; if (NULL== (Tool=(Toolbox**)malloc(sizeof(Toolbox)*pars.slices))){ perror ("Memory Error"); } for (i=0; i<pars.slices; i++){ if (NULL== (Tool[i]=(Toolbox*)malloc(sizeof(Toolbox)*pars.slices))){ perror ("Memory Error"); } if (NULL==(Tool[i]->mand=(mandelPars*)malloc(sizeof(mandelPars)))){ perror ("Memory error"); } Tool[i]->mand=&pars; if (NULL==(Tool[i]->res=(int*)malloc(sizeof(int)))){ perror ("Memory error"); } Tool[i]->res= res; Tool[i]->count=i; Tool[i]->rd=-1; if (NULL== (thrP=(pthread_t*)malloc(sizeof(pthread_t)*pars.slices))){ perror ("Memory Error"); } thrCheck = pthread_create( &thrP[i], NULL,calcMandel , (void *)Tool[i]); if(thrCheck) { fprintf(stderr,"Error - pthread_create() return code: %d\n",thrCheck); exit(EXIT_FAILURE); } } while (1) { clearWin(); printf("computing for level %d:\n",level); printf("reBeg=%Lf reEnd=%Lf reStep=%Lf\n",pars.reBeg,pars.reEnd,reStep); printf("imBeg=%Lf imEnd=%Lf imStep=%Lf\n",pars.imBeg,pars.imEnd,imStep); printf("maxIterations=%d\n",pars.maxIterations); for (i=0; i<pars.slices; i++) { Tool[i]->level=&level; Tool[i]->rd=0; } /* busywait (and draw results) until all slices done */ k=0; while (k!=pars.slices) { for (i=0; i<pars.slices; i++) { while (Tool[i]->rd!=1){ if (0!=(check= sched_yield())){ perror ("Thread"); } } for (y=i*(pars.imPixels/pars.slices); y<(i+1)*(pars.imPixels/pars.slices); y++) { for (x=0; x<pars.rePixels; x++) { setColor(pickColor(res[y*pars.rePixels+x],pars.maxIterations)); drawPoint(x,y); } } k++; Tool[i]->rd=2; } } /* get next focus/zoom point */ getMouseCoords(&x,&y); xoff = WinW/2 - x; yoff = WinH/2 - (WinH-y); /* adjust focus */ pars.reBeg = pars.reBeg - xoff*reStep; pars.reEnd = pars.reBeg + reStep*pars.rePixels; pars.imBeg = pars.imBeg - yoff*reStep; pars.imEnd = pars.imBeg + reStep*pars.imPixels; /* zoom in */ reStep = reStep*ZoomStepFactor; imStep = imStep*ZoomStepFactor; pars.reBeg = pars.reBeg + (pars.reEnd-pars.reBeg)/2 - reStep*pars.rePixels/2; pars.reEnd = pars.reBeg+reStep*pars.rePixels; pars.imBeg = pars.imBeg + (pars.imEnd-pars.imBeg)/2 - imStep*pars.imPixels/2; pars.imEnd = pars.imBeg+imStep*pars.imPixels; pars.maxIterations = pars.maxIterations*ZoomIterationFactor; level++; } /* never reach this point; for cosmetic reasons */ free(res); closeWin(); closeDisplay(); }
int main(int argc, char *argv[]) { mandel_Pars pars; int i, j, x, y, k, nofslices, level, thread_status; int xoff,yoff; long double reEnd,imEnd,reCenter,imCenter; pthread_t *thread_workers; printf("\n"); printf("This program starts by drawing the default Mandelbrot region\n"); printf("When done, you can click with the mouse on an area of interest\n"); printf("and the program will automatically zoom around this point\n"); printf("\n"); printf("Press enter to continue\n"); getchar(); pars.reSteps = WinW; /* never changes */ pars.imSteps = WinH; /* never changes */ /* default mandelbrot region */ pars.reBeg = (long double) -2.0; reEnd = (long double) 1.0; pars.imBeg = (long double) -1.5; imEnd = (long double) 1.5; pars.reInc = (reEnd - pars.reBeg) / pars.reSteps; pars.imInc = (imEnd - pars.imBeg) / pars.imSteps; printf("enter max iterations (50): "); scanf("%d",&maxIterations); printf("enter no of slices: "); scanf("%d",&nofslices); /* adjust slices to divide win height */ while (WinH % nofslices != 0) { nofslices++;} /* allocate slice parameter and result arrays */ slices = (mandel_Pars *) malloc(sizeof(mandel_Pars)*nofslices); res = (int *) malloc(sizeof(int)*pars.reSteps*pars.imSteps); //workers init thread_workers = (pthread_t*)malloc(sizeof(pthread_t)*nofslices); work_status=(int *)malloc(sizeof(int)*nofslices); for(i=0;i<nofslices;i++)work_status[i]=-1; for(i=0;i<nofslices;i++){ thread_status=pthread_create(&thread_workers[i], NULL, workers, (void*)(intptr_t)i); if(thread_status){ perror("Fail create thread\n"); exit(1); } } /* open window for drawing results */ openDisplay(); openWin(argv[0], WinW, WinH); level = 1; while (1) { clearWin(); mandel_Slice(&pars,nofslices,slices); for(i=0;i<nofslices;i++)work_status[i]=0; i=0; y=0; while(i<nofslices){ for(k=0;work_status[k]!=1;k++)if((k+1)==nofslices)k=-1; for(i++, work_status[k]=2, j=0;j<slices[k].imSteps;j++,y++){ for(x=0;x<slices[k].reSteps;x++){ setColor(pickColor(res[y*slices[k].reSteps+x],maxIterations)); drawPoint(x, y); } } printf("thread no. %d finish draw\n", k); } /* get next focus/zoom point */ getMouseCoords(&x,&y); xoff = x; yoff = WinH-y; /* adjust region and zoom factor */ reCenter = pars.reBeg + xoff*pars.reInc; imCenter = pars.imBeg + yoff*pars.imInc; pars.reInc = pars.reInc*ZoomStepFactor; pars.imInc = pars.imInc*ZoomStepFactor; pars.reBeg = reCenter - (WinW/2)*pars.reInc; pars.imBeg = imCenter - (WinH/2)*pars.imInc; maxIterations = maxIterations*ZoomIterationFactor; level++; } /* never reach this point; for cosmetic reasons */ free(work_status); free(thread_workers); free(slices); free(res); closeWin(); closeDisplay(); }