--- joko/Uni/BSArch/04/bmp_fractal.c 2006/07/01 12:19:46 1.5 +++ 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.5 2006/07/01 12:19:46 joko Exp $ +// $Id: bmp_fractal.c,v 1.8 2006/07/01 22:10:42 joko Exp $ #include #include @@ -94,6 +94,66 @@ } +// arguments for each thread +typedef struct _WorkerArguments { + int start_row; + int number_of_rows; + unsigned char * pBitmap; +} WORKERARGS, *PWORKERARGS; + +// worker thread - main entry function +DWORD WINAPI fractal_thread (LPVOID lpParam) { + + // thread stuff + int thread_id; + PWORKERARGS args; + unsigned char *pDataBitmapSegment; + + // fractal calculation + int x, y; + char bgr[3]; + + thread_id = GetCurrentThreadId(); + + // 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]); + + // debugging + //printf("pointer: %p\n", pDataBitmapCurrent); + + // transfer color values to current pixel + pDataBitmapSegment[0] = bgr[0]; + pDataBitmapSegment[1] = bgr[1]; + pDataBitmapSegment[2] = bgr[2]; + + // move pointer to next pixel + pDataBitmapSegment += 3; + + } + //no padding required because 1500%4 =0 + } + + printf("thread finished: %i\n", thread_id); + return 0; + +} + + int main(int argc, char *argv[]) { // MMF support @@ -103,13 +163,12 @@ unsigned char *pDataBitmap, *pDataBitmapCurrent; // workers - unsigned int workers = 3; - unsigned int worker_index, worker_rows, worker_startrow; - - // fractal calculation - int x, y; - char bgr[3]; - + int workers = 5; + int worker_index, worker_rows, worker_startrow; + HANDLE *worker_handles; + //struct WorkerArguments *worker_args; + PWORKERARGS worker_args; + // create empty bmp-file (black background) write_blank_file("test.bmp"); @@ -153,11 +212,33 @@ } */ - // calculate segments of bitmap for worker threads/processes + + // allocate memory for table of all worker handles + 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 | 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; @@ -166,29 +247,34 @@ worker_rows = YSIZE - worker_startrow; printf("rows for last worker: %i\n", worker_rows); } + + worker_args[worker_index].start_row = worker_startrow; + worker_args[worker_index].number_of_rows = worker_rows; + worker_args[worker_index].pBitmap = pDataBitmap; + + worker_handles[worker_index] = CreateThread( + NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, + 0, // SIZE_T dwStackSize, + fractal_thread, // LPTHREAD_START_ROUTINE lpStartAddress, + &worker_args[worker_index], // LPVOID lpParameter, + 0, // DWORD dwCreationFlags, + NULL // LPDWORD lpThreadId + ); + } - // calculate fractal - for (y=YSIZE-1; y>=0; y--) { - for (x=0; x