Skip to content

Instantly share code, notes, and snippets.

@amurzeau
Created August 15, 2018 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amurzeau/dda0d50b76f3752758a12274a4c7ffe5 to your computer and use it in GitHub Desktop.
Save amurzeau/dda0d50b76f3752758a12274a4c7ffe5 to your computer and use it in GitHub Desktop.
Test openblas use of compiler's TLS to not deadlock on dl_close
/* Build with gcc test_compiler_tls.c -o test_compiler_tls -ldl -g -pthread */
#include <dlfcn.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <stdint.h>
pthread_cond_t cond;
void* test_thread(void* arg) {
const char* filename = (const char*) arg;
int i;
intptr_t ret = 0;
for(i = 0; i < 10; i++) {
printf("Try %d\n", i);
void* handle = dlopen(filename, RTLD_NOW);
if(handle == 0) {
printf("Can't open openblas: %s\n", dlerror());
ret = 1;
break;
}
dlclose(handle);
}
pthread_cond_signal(&cond);
return (void*) ret;
}
int main(int argc, char* argv[]) {
pthread_t thread;
pthread_mutex_t mutex;
struct timespec timeToWait;
struct timeval now;
int ret;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
if(argc < 2) {
printf("Usage: %s libopenblas.so\n", argv[0]);
return 1;
}
pthread_create(&thread, NULL, &test_thread, argv[1]);
gettimeofday(&now, NULL);
/* 10s timeout */
timeToWait.tv_sec = now.tv_sec + 10;
timeToWait.tv_nsec = now.tv_usec * 1000UL;
pthread_mutex_lock(&mutex);
ret = pthread_cond_timedwait(&cond, &mutex, &timeToWait);
if(ret != 0) {
printf("Failed to wait end of test thread, deadlocked ?: %d\n", ret);
return 2;
} else {
void* threadRet;
pthread_join(thread, &threadRet);
if((intptr_t)threadRet != 0) {
printf("test_thread failed\n");
return 3;
}
return 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment