From c4f2710f9d474049bfbbebdb9dad2466e6a3ac94 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 23 Mar 2006 17:17:23 +0000 Subject: [PATCH] Added -l option for explicit locking around Xlib and GLX calls in threaded code. Seems to improve reliability quite a bit. --- progs/xdemos/glthreads.c | 69 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/progs/xdemos/glthreads.c b/progs/xdemos/glthreads.c index 333f4bb281a..83413383dd4 100644 --- a/progs/xdemos/glthreads.c +++ b/progs/xdemos/glthreads.c @@ -64,6 +64,9 @@ static int NumWinThreads = 0; static volatile GLboolean ExitFlag = GL_FALSE; static GLboolean MultiDisplays = 0; +static GLboolean Locking = 0; + +static pthread_mutex_t Mutex; static void @@ -148,9 +151,22 @@ resize(struct winthread *wt, int w, int h) static void draw_loop(struct winthread *wt) { + GLboolean firstIter = GL_TRUE; + while (!ExitFlag) { + if (Locking) + pthread_mutex_lock(&Mutex); + glXMakeCurrent(wt->Dpy, wt->Win, wt->Context); + if (firstIter) { + printf("glthreads: %d: GL_RENDERER = %s\n", wt->Index, + (char *) glGetString(GL_RENDERER)); + firstIter = GL_FALSE; + } + + if (Locking) + pthread_mutex_unlock(&Mutex); glEnable(GL_DEPTH_TEST); @@ -175,8 +191,14 @@ draw_loop(struct winthread *wt) draw_object(); glPopMatrix(); + if (Locking) + pthread_mutex_lock(&Mutex); + glXSwapBuffers(wt->Dpy, wt->Win); + if (Locking) + pthread_mutex_unlock(&Mutex); + usleep(5000); wt->Angle += 1.0; } @@ -196,7 +218,25 @@ event_loop(Display *dpy) assert(!MultiDisplays); while (!ExitFlag) { - XNextEvent(dpy, &event); + + if (Locking) { + while (1) { + int k; + pthread_mutex_lock(&Mutex); + k = XPending(dpy); + if (k) { + XNextEvent(dpy, &event); + pthread_mutex_unlock(&Mutex); + break; + } + pthread_mutex_unlock(&Mutex); + usleep(5000); + } + } + else { + XNextEvent(dpy, &event); + } + switch (event.type) { case ConfigureNotify: /* Find winthread for this event's window */ @@ -376,9 +416,9 @@ main(int argc, char *argv[]) Status threadStat; if (argc == 1) { - printf("threadgl: test of GL thread safety (any key = exit)\n"); + printf("glthreads: test of GL thread safety (any key = exit)\n"); printf("Usage:\n"); - printf(" threadgl [-display dpyName] [-n numthreads]\n"); + printf(" glthreads [-display dpyName] [-n numthreads]\n"); } else { int i; @@ -390,6 +430,9 @@ main(int argc, char *argv[]) else if (strcmp(argv[i], "-p") == 0) { MultiDisplays = 1; } + else if (strcmp(argv[i], "-l") == 0) { + Locking = 1; + } else if (strcmp(argv[i], "-n") == 0 && i + 1 < argc) { numThreads = atoi(argv[i + 1]); if (numThreads < 1) @@ -404,17 +447,29 @@ main(int argc, char *argv[]) } } + if (Locking) + printf("glthreads: Using explict locks around Xlib calls.\n"); + else + printf("glthreads: No explict locking.\n"); + + if (MultiDisplays) + printf("glthreads: Per-thread display connections.\n"); + else + printf("glthreads: Single display connection.\n"); + /* * VERY IMPORTANT: call XInitThreads() before any other Xlib functions. */ if (!MultiDisplays) { - threadStat = XInitThreads(); + if (!Locking) { + threadStat = XInitThreads(); if (threadStat) { printf("XInitThreads() returned %d (success)\n", (int) threadStat); } else { printf("XInitThreads() returned 0 (failure- this program may fail)\n"); } + } dpy = XOpenDisplay(displayName); if (!dpy) { @@ -423,6 +478,10 @@ main(int argc, char *argv[]) } } + if (Locking) { + pthread_mutex_init(&Mutex, NULL); + } + printf("glthreads: creating windows\n"); NumWinThreads = numThreads; @@ -446,7 +505,7 @@ main(int argc, char *argv[]) for (i = 0; i < numThreads; i++) { pthread_create(&WinThreads[i].Thread, NULL, thread_function, (void*) &WinThreads[i]); - printf("Created Thread %d\n", (int) WinThreads[i].Thread); + printf("glthreads: Created thread %u\n", (unsigned int) WinThreads[i].Thread); } if (MultiDisplays) -- 2.30.2