int main(void) { int nthr = 4; //get_nprocs_conf(); int ndx; int delta = HEIGHT / nthr; int ofs = 0; struct mandelthr *args; pthread_t *thrtab = calloc(nthr, sizeof(pthread_t)); pthread_t **thrptrtab = calloc(nthr, sizeof(pthread_t *)); fprintf(stderr, "mandel launching %d threads\n", nthr); /* Make a window! */ init_x11(WIDTH); init_colours(); g_mandel.nthr = nthr; for (ndx = 0 ; ndx < nthr ; ndx++) { args = calloc(1, sizeof(struct mandelthr)); args->yofs = ofs; args->ylim = ofs + delta; pthread_create(&thrtab[ndx], NULL, mandel_start, args); ofs += delta; } for (ndx = 0 ; ndx < nthr ; ndx++) { pthread_join(thrtab[ndx], (void **)&thrptrtab[ndx]); } do { // pthread_yield(); // m_waitspin(); usleep(50000); pthread_yield(); } while (g_mandel.nthr); XPutImage(g_x11.dpy, g_x11.win, g_x11.gc, g_x11.bitmap, 0, 0, 0, 0, WIDTH, HEIGHT); XFlush(g_x11.dpy); // display_double(ASIZE, xmin, xmax, ymin, ymax); #ifdef WAIT_EXIT while(1) { XEvent event; KeySym key; char text[255]; XNextEvent(g_x11.dpy, &event); /* Just redraw everything on expose */ if ((event.type == Expose) && !event.xexpose.count) { XPutImage(g_x11.dpy, g_x11.win, g_x11.gc, g_x11.bitmap, 0, 0, 0, 0, WIDTH, HEIGHT); } /* Press 'q' to quit */ if ((event.type == KeyPress) && XLookupString(&event.xkey, text, 255, &key, 0) == 1) { if (text[0] == 'q') break; } /* Or simply close the window */ if ((event.type == ClientMessage) && ((Atom) event.xclient.data.l[0] == g_x11.wmdelmsg)) { break; } } #endif sleep(5); /* Done! */ exit_x11(); return 0; }
static void init_x11(int size) { char name[128] = "Mandelbrot"; int bytes_per_pixel; unsigned long white; unsigned long black; XTextProperty tp; char *n = name; Status st; unsigned int ii, jj; unsigned int depth; Visual *visual; int total; XInitThreads(); /* Attempt to open the display */ g_x11.dpy = XOpenDisplay(NULL); white = WhitePixel(g_x11.dpy,DefaultScreen(g_x11.dpy)); black = BlackPixel(g_x11.dpy,DefaultScreen(g_x11.dpy)); depth = DefaultDepth(g_x11.dpy, DefaultScreen(g_x11.dpy)); visual = DefaultVisual(g_x11.dpy, DefaultScreen(g_x11.dpy)); /* Failure */ if (!g_x11.dpy) exit(0); g_x11.win = XCreateSimpleWindow(g_x11.dpy, DefaultRootWindow(g_x11.dpy), 0, 0, size, size, 0, black, white); /* We want to be notified when the window appears */ XSelectInput(g_x11.dpy, g_x11.win, ExposureMask); /* Make it appear */ XMapWindow(g_x11.dpy, g_x11.win); #if 0 while (1) { XEvent e; XNextEvent(g_x11.dpy, &e); if (e.type == MapNotify) break; } #endif /* we need to wait for the Expose event instead of MapNotify */ while (1) { XEvent e; XNextEvent(g_x11.dpy, &e); if (e.type == Expose) break; } st = XStringListToTextProperty(&n, 1, &tp); if (st) XSetWMName(g_x11.dpy, g_x11.win, &tp); /* Wait for the MapNotify event */ XFlush(g_x11.dpy); /* Determine total bytes needed for image */ ii = 1; jj = (depth - 1) >> 2; while (jj >>= 1) ii <<= 1; /* Pad the scanline to a multiple of 4 bytes */ total = size * ii; total = (total + 3) & ~3; total *= size; bytes_per_pixel = ii; if (bytes_per_pixel != 4) { printf("Need 32bit colour screen!"); } /* Make bitmap */ g_x11.bitmap = XCreateImage(g_x11.dpy, visual, depth, ZPixmap, 0, malloc(total), size, size, 32, 0); /* Init GC */ g_x11.gc = XCreateGC(g_x11.dpy, g_x11.win, 0, NULL); XSetForeground(g_x11.dpy, g_x11.gc, black); if (bytes_per_pixel != 4) { printf("Need 32bit colour screen!\n"); exit_x11(); exit(0); } XSelectInput(g_x11.dpy, g_x11.win, ExposureMask | KeyPressMask | StructureNotifyMask); g_x11.wmdelmsg = XInternAtom(g_x11.dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(g_x11.dpy, g_x11.win, &g_x11.wmdelmsg, 1); }
int main(void) { int nthr = get_nprocs_conf(); int ndx; int delta = ASIZE / nthr; int ofs = 0; struct mandelthr *args; pthread_t *thrtab = calloc(nthr, sizeof(pthread_t)); pthread_t **thrptrtab = calloc(nthr, sizeof(pthread_t *)); /* Make a window! */ init_x11(ASIZE); init_colours(); g_nthr = nthr; for (ndx = 0 ; ndx < nthr ; ndx++) { args = calloc(1, sizeof(struct mandelthr)); args->yofs = ofs; args->ylim = ofs + delta; pthread_create(&thrtab[ndx], NULL, mandel_start, args); ofs += delta; } for (ndx = 0 ; ndx < nthr ; ndx++) { pthread_join(thrtab[ndx], (void **)&thrptrtab[ndx]); } do { pthread_yield(); } while (g_nthr); XPutImage(dpy, win, gc, bitmap, 0, 0, 0, 0, ASIZE, ASIZE); XFlush(dpy); // display_double(ASIZE, xmin, xmax, ymin, ymax); #ifdef WAIT_EXIT while(1) { XEvent event; KeySym key; char text[255]; XNextEvent(dpy, &event); /* Just redraw everything on expose */ if ((event.type == Expose) && !event.xexpose.count) { XPutImage(dpy, win, gc, bitmap, 0, 0, 0, 0, ASIZE, ASIZE); } /* Press 'q' to quit */ if ((event.type == KeyPress) && XLookupString(&event.xkey, text, 255, &key, 0) == 1) { if (text[0] == 'q') break; } /* Or simply close the window */ if ((event.type == ClientMessage) && ((Atom) event.xclient.data.l[0] == wmDeleteMessage)) { break; } } #endif /* Done! */ exit_x11(); return 0; }