gallivm: Allow drivers and state trackers to initialize gallivm LLVM targets v2
authorTom Stellard <thomas.stellard@amd.com>
Thu, 24 Sep 2015 15:57:02 +0000 (15:57 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Fri, 2 Oct 2015 23:41:26 +0000 (23:41 +0000)
commit76cfd6f1da3748effb480e4f1151910af59fb88a
tree7f84f221f6f8e4946c8c84a4c14b5e4d952fc0b3
parent3219b48ae5a5b1288bf1fc1325ebbc7ac9e236df
gallivm: Allow drivers and state trackers to initialize gallivm LLVM targets v2

Drivers and state trackers that use LLVM for generating code, must
register the targets they use with LLVM's global TargetRegistry.
The TargetRegistry is not thread-safe, so all targets must be added
to the registry before it can be queried for target information.

When drivers and state trackers initialize their own targets, they need
a way to force gallivm to initialize its targets at the same time.
Otherwise, there can be a race condition in some multi-threaded
applications (e.g. glx-multihreaded-shader-compile in piglit),
when one thread creates a context for a driver that uses LLVM (e.g.
radeonsi) and another thread creates a gallivm context (glxContextCreate
does this).

The race happens when the driver thread initializes its LLVM targets and
then starts using the registry before the gallivm thread has a chance to
register its targets.

This patch allows users to force gallivm to register its targets by
calling the gallivm_init_llvm_targets() function.

v2:
  - Use call_once and remove mutexes and static initializations.
  - Replace gallivm_init_llvm_{begin,end}() with
    gallivm_init_llvm_targets().

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
CC: "10.6 11.0" <mesa-stable@lists.freedesktop.org>
src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
src/gallium/auxiliary/gallivm/lp_bld_misc.h
src/gallium/targets/opencl/Makefile.am