--- joko/Uni/BSArch/04/bmp_fractal.c 2006/07/01 11:58:49 1.4 +++ joko/Uni/BSArch/04/bmp_fractal.c 2006/07/02 01:51:26 1.10 @@ -5,7 +5,7 @@ * Uebung 4.4 */ -// $Id: bmp_fractal.c,v 1.4 2006/07/01 11:58:49 joko Exp $ +// $Id: bmp_fractal.c,v 1.10 2006/07/02 01:51:26 joko Exp $ #include #include @@ -15,6 +15,10 @@ #define YSIZE 500 #include "algorithm.h" +#define MASTER -1 + +BOOL VERBOSE = TRUE; + /* BMP Header */ unsigned char header[54]={0x42,0x4d, // signature BM @@ -94,33 +98,126 @@ } +// 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_create_segment (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; + + // calculate pointer to beginning of segment + pDataBitmapSegment = (unsigned char *)((INT_PTR)args->pBitmap + (YSIZE - (args->start_row + args->number_of_rows)) * 3 * XSIZE); + + // debugging + if (VERBOSE) { + 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); + 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]); + + // 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 ??? + } + + if (VERBOSE) + printf("thread finished: %i\n", thread_id); + return 0; + +} + + int main(int argc, char *argv[]) { // MMF support DWORD err; HANDLE hMap, hFile; LPVOID pData; - unsigned char *pDataBitmap, *pDataBitmapCurrent; + unsigned char *pDataBitmap; - // fractal calculation - int x, y; - char bgr[3]; + // workers + int workers = 5; + int worker_index, worker_rows, worker_startrow; + HANDLE *worker_handles; + PWORKERARGS worker_args; + + // threads or processes? + BOOL use_processes = TRUE; + int worker_id = MASTER; + + // information for creating processes + STARTUPINFO si; + PROCESS_INFORMATION pi; + char szCmdline[1024]; + // "parse" command line arguments + if (argc >= 2) { + worker_id = atoi(argv[1]); + } + + if (VERBOSE) { + printf("==============================================================\n"); + printf("worker-id: %i\n", worker_id); + } + // create empty bmp-file (black background) - write_blank_file("test.bmp"); + if (worker_id == MASTER) + write_blank_file("test.bmp"); - /* open file for reading and writing */ - hFile = CreateFile("test.bmp", GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == hFile) { - err = GetLastError(); - printErrorAndExit("Error at CreateFile",err); - } + if (worker_id == MASTER) { + + /* open file for reading and writing */ + hFile = CreateFile("test.bmp", GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (INVALID_HANDLE_VALUE == hFile) { + err = GetLastError(); + printErrorAndExit("Error at CreateFile",err); + } - /* create the file mapping object */ - hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); - if (NULL == hMap) { - printErrorAndExit("Error at CreateFileMapping", GetLastError()); + /* create the file mapping object */ + hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, "bmp_fractal"); + if (NULL == hMap) { + printErrorAndExit("Error at CreateFileMapping", GetLastError()); + } + + } else { + + // open existing mapping object + hMap = OpenFileMapping(FILE_MAP_WRITE, FALSE, "bmp_fractal"); + if (NULL == hMap) + printErrorAndExit("Error at OpenFileMapping", GetLastError()); } /* map the whole file into the process context */ @@ -134,42 +231,142 @@ pDataBitmap = (unsigned char *)((INT_PTR)pData + sizeof(header)); // debugging - printf("pos. of file: %p\n", pData); - printf("pos. of bitmap: %p\n", pDataBitmap); - - // pointer to current pixel - pDataBitmapCurrent = pDataBitmap; + if (VERBOSE) { + printf("pos. of file: %p\n", pData); + printf("pos. of bitmap: %p\n", pDataBitmap); + } + + if (use_processes && worker_id != MASTER) { + + if (VERBOSE) + printf("inside worker-process\n"); + + worker_index = worker_id; + + worker_startrow = atoi(argv[2]); + worker_rows = atoi(argv[3]); + + // allocate memory for one worker's arguments + if ((worker_args = malloc(sizeof(worker_args[0]))) == NULL) + perror("malloc"), exit(1); + + // assign worker's arguments + worker_args[0].start_row = worker_startrow; + worker_args[0].number_of_rows = worker_rows; + worker_args[0].pBitmap = pDataBitmap; + + fractal_create_segment(&worker_args[0]); + + return 0; + } + /* - // turn bitmap into white wand + // turn bitmap into white canvas for (offset = 0; offset < 500 * 500 * 3; offset++) { - //pDataBitmap[offset] = 255; - *pDataBitmapCurrent = 255; - pDataBitmapCurrent++; + *pDataBitmap = 255; + pDataBitmap++; } + exit(0); */ - // calculate fractal - for (y=YSIZE-1; y>=0; y--) { - for (x=0; x