[Mesa-dev] Threading issues with LLVM pipeline

Juraj Švec ageorgo at gmail.com
Thu Mar 29 19:52:11 PDT 2012


Hi,

last time I was wondering about thread safety in Mesa 8.0 build with
llvm=no - this configuration seems to be working with the lock patch.

Now I am testing 8.0 branch with LLVM 3.0 (with scons script fix
a1482b21cb438c271cf20e7d52cb9e4e0537344c - stop me if it is not
supposed to work)

I have very simple GL code:

  HGLRC glContext = wglCreateContext(hDC);
  wglMakeCurrent(hDC, glContext);

  glViewport(0, 0, 1024, 600);

  void *buffer = malloc(1024*600*3);
  for (int i=0; i < 100; i++) {
    glClearColor(0.0, 0.0, 1.0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glReadPixels(0, 0, 1024, 600, GL_RGB, GL_UNSIGNED_BYTE, buffer);
    SwapBuffers(hDC);
    Sleep(20);
  }
  free (buffer);


which I run in 2 or more threads. The first problem occurs during
wglMakeCurrent:

thread 1:

opengl32.dll!pipe_semaphore_wait(pipe_semaphore * sema)  Line 432 + 0x17 bytes
opengl32.dll!lp_rast_finish(lp_rasterizer * rast)  Line 782 + 0x16 bytes
opengl32.dll!lp_setup_rasterize_scene(lp_setup_context * setup)  Line
160 + 0xc bytes
opengl32.dll!set_scene_state(lp_setup_context * setup, setup_state
new_state, const char * reason)  Line 313 + 0x9 bytes
opengl32.dll!lp_setup_flush(lp_setup_context * setup,
pipe_fence_handle * * fence, const char * reason)  Line 342 + 0xf
bytes
opengl32.dll!llvmpipe_flush(pipe_context * pipe, pipe_fence_handle * *
fence, const char * reason)  Line 55 + 0x17 bytes
opengl32.dll!llvmpipe_finish(pipe_context * pipe, const char * reason)
 Line 89 + 0x11 bytes
opengl32.dll!llvmpipe_flush_resource(pipe_context * pipe,
pipe_resource * resource, unsigned int level, int layer, unsigned char
read_only, unsigned char cpu_access, unsigned char do_not_block, const
char * reason)  Line 128 + 0xd bytes
opengl32.dll!llvmpipe_get_transfer(pipe_context * pipe, pipe_resource
* resource, unsigned int level, unsigned int usage, const pipe_box *
box)  Line 607 + 0x41 bytes
opengl32.dll!pipe_get_transfer(pipe_context * context, pipe_resource *
resource, unsigned int level, unsigned int layer, pipe_transfer_usage
usage, unsigned int x, unsigned int y, unsigned int w, unsigned int h)
 Line 393 + 0x1f bytes
opengl32.dll!st_MapRenderbuffer(gl_context * ctx, gl_renderbuffer *
rb, unsigned int x, unsigned int y, unsigned int w, unsigned int h,
unsigned int mode, unsigned char * * mapOut, int * rowStrideOut)  Line
683 + 0x38 bytes
opengl32.dll!slow_read_rgba_pixels(gl_context * ctx, int x, int y, int
width, int height, unsigned int format, unsigned int type, void *
pixels, const gl_pixelstore_attrib * packing, unsigned int
transferOps)  Line 274 + 0x2d bytes
opengl32.dll!read_rgba_pixels(gl_context * ctx, int x, int y, int
width, int height, unsigned int format, unsigned int type, void *
pixels, const gl_pixelstore_attrib * packing)  Line 338 + 0x2d bytes
opengl32.dll!_mesa_readpixels(gl_context * ctx, int x, int y, int
width, int height, unsigned int format, unsigned int type, const
gl_pixelstore_attrib * packing, void * pixels)  Line 586 + 0x29 bytes
opengl32.dll!st_readpixels(gl_context * ctx, int x, int y, int width,
int height, unsigned int format, unsigned int type, const
gl_pixelstore_attrib * pack, void * dest)  Line 54 + 0x29 bytes
opengl32.dll!_mesa_ReadnPixelsARB(int x, int y, int width, int height,
unsigned int format, unsigned int type, int bufSize, void * pixels)
Line 831 + 0x35 bytes
opengl32.dll!_mesa_ReadPixels(int x, int y, int width, int height,
unsigned int format, unsigned int type, void * pixels)  Line 839
opengl32.dll!glReadPixels(int x, int y, int width, int height,
unsigned int format, unsigned int type, void * pixels)  Line 1618
multithreads.exe!display_gl_window(int id)  Line 103 + 0x24 bytes
multithreads.exe!thread_1_main(void * lpParameter)  Line 126 + 0x9 bytes

thread 2:

opengl32.dll!_debug_assert_fail(const char * expr, const char * file,
unsigned int line, const char * function)  Line 278
opengl32.dll!begin_binning(lp_setup_context * setup)  Line 180 + 0x24 bytes
opengl32.dll!execute_clears(lp_setup_context * setup)  Line 262 + 0x9 bytes
opengl32.dll!set_scene_state(lp_setup_context * setup, setup_state
new_state, const char * reason)  Line 310 + 0x9 bytes
opengl32.dll!lp_setup_flush(lp_setup_context * setup,
pipe_fence_handle * * fence, const char * reason)  Line 342 + 0xf
bytes
opengl32.dll!llvmpipe_flush(pipe_context * pipe, pipe_fence_handle * *
fence, const char * reason)  Line 55 + 0x17 bytes
opengl32.dll!do_flush(pipe_context * pipe, pipe_fence_handle * *
fence)  Line 141 + 0x12 bytes
opengl32.dll!st_flush(st_context * st, pipe_fence_handle * * fence)
Line 92 + 0x19 bytes
opengl32.dll!st_context_flush(st_context_iface * stctxi, unsigned int
flags, pipe_fence_handle * * fence)  Line 462 + 0xd bytes
opengl32.dll!stw_make_current(HDC__ * hdc, unsigned long dhglrc)  Line
327 + 0x14 bytes
opengl32.dll!DrvSetContext(HDC__ * hdc, unsigned long dhglrc, void
(_GLCLTPROCTABLE *)* pfnSetProcTable)  Line 768 + 0xd bytes
opengl32.dll!wglMakeCurrent(HDC__ * hdc, HGLRC__ * hglrc)  Line 88 + 0xf bytes
multithreads.exe!display_gl_window(int id)  Line 94 + 0x10 bytes
multithreads.exe!thread_1_main(void * lpParameter)  Line 126 + 0x9 bytes

I tested that this is probably because of late init of ThreadSafe flag
in u_current.c - if I set it to 1 the call does not fail. Basically
the call to stw_current_context in stw_make_current returns the other
thread context and not null.
After hard coding ThreadSafe to 1 I am getting crashes in LLVM code.
The suspicious code is gallivm_create() which returns singleton but
the creation is not guarded by any lock.
The code is randomly failing somewhere within LLVMCreateJITCompiler.

Thanks,
Juraj


More information about the mesa-dev mailing list