In my post about OpenMP on Android, I mentioned that your app will crash if you try to use OpenMP directives or functions on a non-main thread. That can be traced back to the gomp_thread function in libgomp/libgomp.h, and the fact that it returns NULL for threads you create.

To see why that happens requires stepping back a bit. GOMP uses a slightly different implementation depending on whether or not thread-local storage (TLS) is available. If it is available, the HAVE_TLS flag will be set, and a global variable will be used to track the state of each thread. Otherwise, thread-local data will be managed via pthread_setspecific.

On Android, thread-local storage defined through the __thread keyword isn't supported (see this thread as well as docs/system/libc/OVERVIEW.html in the NDK distribution). In that case, HAVE_TLS won't be defined, and pthread_setspecific will be used.

When GOMP creates a worker thread, it sets up the thread specific data in gomp_thread_start (see libgomp/team.c):

But, when the application creates a thread independently, the thread specific data isn't set, and so the gomp_thread function returns NULL, which causes the crash. This isn't a problem when TLS is supported, since the global variable that's used will always be available.

To correct the issue, gomp_thread has to be modified to initialize the thread specific data if it hasn't already been set. You can download my proposed patches below. They're based on the code submitted in this ticket.

To update GOMP, you'll have to apply the patches, then rebuild one or more of the GCC toolchains that comes with the NDK. Keep in mind you don't actually need the entire toolchain. It's enough to simply copy the libgomp.a files out of the output directory and into your existing NDK installation.

References: