--- joko/Uni/BSArch/04/bmp_fractal.c 2006/07/01 13:56:54 1.6 +++ joko/Uni/BSArch/04/bmp_fractal.c 2006/07/01 22:10:42 1.8 @@ -5,7 +5,7 @@ * Uebung 4.4 */ -// $Id: bmp_fractal.c,v 1.6 2006/07/01 13:56:54 joko Exp $ +// $Id: bmp_fractal.c,v 1.8 2006/07/01 22:10:42 joko Exp $ #include #include @@ -96,8 +96,8 @@ // arguments for each thread typedef struct _WorkerArguments { - unsigned int start_row; - unsigned int number_of_rows; + int start_row; + int number_of_rows; unsigned char * pBitmap; } WORKERARGS, *PWORKERARGS; @@ -107,6 +107,7 @@ // thread stuff int thread_id; PWORKERARGS args; + unsigned char *pDataBitmapSegment; // fractal calculation int x, y; @@ -117,12 +118,18 @@ // get worker arguments args = (PWORKERARGS)lpParam; + printf("----------------------------------------------\n"); printf("thread_id: %i\n", thread_id); printf("arg.start_row: %i\n", args->start_row); printf("arg.number_of_rows: %i\n", args->number_of_rows); + + // calculate pointer to beginning of segment + pDataBitmapSegment = (unsigned char *)((INT_PTR)args->pBitmap + (YSIZE - (args->start_row + args->number_of_rows)) * 3 * XSIZE); + printf("segment_start: %p\n", pDataBitmapSegment); // calculate fractal for (y = (args->start_row + args->number_of_rows) - 1; y >= args->start_row; y--) { + //printf("calc: thread=%i; y=%i limits: %i,%i p: %p\n", thread_id, y, args->start_row, args->number_of_rows, pDataBitmapSegment); for (x = 0; x < XSIZE; x++) { getColorValuesAt(x * (2.0 / XSIZE) - 1.5, y * (2.0 / YSIZE) - 1.0, &bgr[2], &bgr[1], &bgr[0]); @@ -130,17 +137,18 @@ //printf("pointer: %p\n", pDataBitmapCurrent); // transfer color values to current pixel - args->pBitmap[0] = bgr[0]; - args->pBitmap[1] = bgr[1]; - args->pBitmap[2] = bgr[2]; + pDataBitmapSegment[0] = bgr[0]; + pDataBitmapSegment[1] = bgr[1]; + pDataBitmapSegment[2] = bgr[2]; // move pointer to next pixel - args->pBitmap += 3; + pDataBitmapSegment += 3; } //no padding required because 1500%4 =0 } + printf("thread finished: %i\n", thread_id); return 0; } @@ -155,8 +163,8 @@ unsigned char *pDataBitmap, *pDataBitmapCurrent; // workers - unsigned int workers = 3; - unsigned int worker_index, worker_rows, worker_startrow; + int workers = 5; + int worker_index, worker_rows, worker_startrow; HANDLE *worker_handles; //struct WorkerArguments *worker_args; PWORKERARGS worker_args; @@ -209,19 +217,28 @@ if ((worker_handles = malloc(workers * sizeof worker_handles[0])) == NULL) perror("malloc"), exit(1); - /* // allocate memory for table of all worker arguments if ((worker_args = malloc(workers * sizeof worker_args[0])) == NULL) perror("malloc"), exit(1); - */ + // allocate memory for table of all worker arguments - worker_args = (PWORKERARGS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, workers * sizeof(WORKERARGS)); + /* + worker_args = (PWORKERARGS) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, workers * sizeof(WORKERARGS)); + + if (worker_args == NULL) { + printErrorAndExit("Failed to allocate on heap", GetLastError()); + } + */ // calculate segments of bitmap for worker threads/processes and start them worker_rows = YSIZE / workers; printf("rows for each worker: %i\n", worker_rows); for (worker_index = 0; worker_index < workers; worker_index++) { + // debugging: just run with single thread + //if (worker_index == 1) + // continue; + // number of row to start for each worker worker_startrow = worker_index * worker_rows; @@ -249,7 +266,15 @@ // wait for all threads if (WaitForMultipleObjects(workers, worker_handles, TRUE, INFINITE) == WAIT_FAILED) perror("WaitForMultipleObjects"); - + + // debugging: just run with single thread + //if (WaitForSingleObject(worker_handles[0], INFINITE) == WAIT_FAILED) + // perror("WaitForSingleObject"); + + // close all worker handles + for (worker_index = 0; worker_index < workers; worker_index++) + CloseHandle(worker_handles[worker_index]); + /* write the result into the file */ if (!FlushViewOfFile(pData, 0)) { err = GetLastError(); @@ -269,4 +294,13 @@ printErrorAndExit("Error at CloseHandle", err); } + /* + if (HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, worker_args) != TRUE) { + printErrorAndExit("Call to HeapFree has failed", GetLastError()); + } + */ + + + return 0; + }