[05/10] Android: fix __thread keyword issue in android.

Submitted by Yang, Rong R on May 19, 2016, 8:37 a.m.

Details

Message ID 1463647036-25545-5-git-send-email-rong.r.yang@intel.com
State New
Headers show
Series "Series without cover letter" ( rev: 2 1 ) in Beignet

Not browsing as part of any series.

Commit Message

Yang, Rong R May 19, 2016, 8:37 a.m.
Android doesn't support __thread keyword, so use pthread instead in
cl_thread.c and disable multithread in the utest.

Signed-off-by: Yang Rong <rong.r.yang@intel.com>
---
 src/Android.mk          |   4 +-
 src/cl_thread.c         | 120 +++++++++++++++++++++++++++++++++++++++---------
 utests/utest_helper.hpp |   4 ++
 utests/utest_run.cpp    |   5 ++
 4 files changed, 109 insertions(+), 24 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/Android.mk b/src/Android.mk
index 0b15428..8f00e3e 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -15,8 +15,8 @@  LOCAL_C_INCLUDES := $(TOP_C_INCLUDE) $(BEIGNET_ROOT_PATH)/backend/src/backend/ $
 LOCAL_C_INCLUDES += $(DRM_INCLUDE_PATH)
 LOCAL_C_INCLUDES += $(LLVM_INCLUDE_DIRS)
 LOCAL_C_INCLUDES += hardware/drm_gralloc
-LOCAL_CPPFLAGS := $(TOP_CPPFLAGS) -std=c++11
-LOCAL_CFLAGS := $(TOP_CFLAGS)
+LOCAL_CPPFLAGS := $(TOP_CPPFLAGS) -std=c++11 -DCONFIG_NO_TLS_THREAD
+LOCAL_CFLAGS := $(TOP_CFLAGS) -DCONFIG_NO_TLS_THREAD
 OPTIONAL_EGL_LIBRARY :=
 LOCAL_LDFLAGS := -Wl,-Bsymbolic
 
diff --git a/src/cl_thread.c b/src/cl_thread.c
index 5e5a351..2d5ecad 100644
--- a/src/cl_thread.c
+++ b/src/cl_thread.c
@@ -38,9 +38,6 @@  static int *thread_slot_map = NULL;
 static int thread_magic_num = 1;
 static pthread_mutex_t thread_queue_map_lock = PTHREAD_MUTEX_INITIALIZER;
 
-static __thread int thread_id = -1;
-static __thread int thread_magic = -1;
-
 typedef struct _thread_spec_data {
   cl_gpgpu gpgpu ;
   int valid;
@@ -56,18 +53,52 @@  typedef struct _queue_thread_private {
   pthread_mutex_t thread_data_lock;
 } queue_thread_private;
 
+#ifndef CONFIG_NO_TLS_THREAD
+  static __thread int thread_id = -1;
+  static __thread int thread_magic = -1;
+#else
+  static pthread_once_t key_once = PTHREAD_ONCE_INIT;
+  static pthread_key_t thread_id_key;
+  static pthread_key_t thread_magic_key;
+
+  static void create_thread_key()
+  {
+    pthread_key_create(&thread_id_key, NULL);
+    pthread_key_create(&thread_magic_key, NULL);
+  }
+#endif
+
 static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int create)
 {
   queue_thread_private *thread_private = ((queue_thread_private *)(queue->thread_data));
   thread_spec_data* spec = NULL;
   int i = 0;
-
-  if (thread_id == -1) {
+  int *id = NULL, *magic = NULL;
+
+#ifdef CONFIG_NO_TLS_THREAD
+  pthread_once(&key_once, create_thread_key);
+  id = pthread_getspecific(thread_id_key);
+  if(id == NULL) {
+    id = (int *)malloc(sizeof(int));
+    *id = -1;
+    pthread_setspecific(thread_id_key, id);
+  }
+  magic = pthread_getspecific(thread_magic_key);
+  if(magic == NULL) {
+    magic = (int *)malloc(sizeof(int));
+    *magic = -1;
+    pthread_setspecific(thread_magic_key, magic);
+  }
+#else
+  id = &thread_id;
+  magic = &thread_magic;
+#endif
+  if (*id == -1) {
 
     pthread_mutex_lock(&thread_queue_map_lock);
     for (i = 0; i < thread_array_num; i++) {
       if (thread_slot_map[i] == 0) {
-        thread_id = i;
+        *id = i;
         break;
       }
     }
@@ -76,12 +107,12 @@  static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
       thread_array_num *= 2;
       thread_slot_map = realloc(thread_slot_map, sizeof(int) * thread_array_num);
       memset(thread_slot_map + thread_array_num/2, 0, sizeof(int) * (thread_array_num/2));
-      thread_id = thread_array_num/2;
+      *id = thread_array_num/2;
     }
 
-    thread_slot_map[thread_id] = 1;
+    thread_slot_map[*id] = 1;
 
-    thread_magic = thread_magic_num++;
+    *magic = thread_magic_num++;
     pthread_mutex_unlock(&thread_queue_map_lock);
   }
 
@@ -95,12 +126,12 @@  static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
            sizeof(void*) * (thread_private->threads_data_num - old_num));
   }
 
-  assert(thread_id != -1 && thread_id < thread_array_num);
-  spec = thread_private->threads_data[thread_id];
+  assert(*id != -1 && *id < thread_array_num);
+  spec = thread_private->threads_data[*id];
   if (!spec && create) {
        spec = CALLOC(thread_spec_data);
-       spec->thread_magic = thread_magic;
-       thread_private->threads_data[thread_id] = spec;
+       spec->thread_magic = *magic;
+       thread_private->threads_data[*id] = spec;
   }
 
   pthread_mutex_unlock(&thread_private->thread_data_lock);
@@ -111,28 +142,48 @@  static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
 cl_event get_current_event(cl_command_queue queue)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
-  assert(spec && spec->thread_magic == thread_magic);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
+  assert(spec && spec->thread_magic == *magic);
   return spec->current_event;
 }
 
 cl_event get_last_event(cl_command_queue queue)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
-  assert(spec && spec->thread_magic == thread_magic);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
+  assert(spec && spec->thread_magic == *magic);
   return spec->last_event;
 }
 
 void set_current_event(cl_command_queue queue, cl_event e)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
-  assert(spec && spec->thread_magic == thread_magic);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
+  assert(spec && spec->thread_magic == *magic);
   spec->current_event = e;
 }
 
 void set_last_event(cl_command_queue queue, cl_event e)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
-  assert(spec && spec->thread_magic == thread_magic);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
+  assert(spec && spec->thread_magic == *magic);
   spec->last_event = e;
 }
 
@@ -164,8 +215,13 @@  void* cl_thread_data_create(void)
 cl_gpgpu cl_get_thread_gpgpu(cl_command_queue queue)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
 
-  if (!spec->thread_magic && spec->thread_magic != thread_magic) {
+  if (!spec->thread_magic && spec->thread_magic != *magic) {
     //We may get the slot from last thread. So free the resource.
     spec->valid = 0;
   }
@@ -190,8 +246,13 @@  cl_gpgpu cl_get_thread_gpgpu(cl_command_queue queue)
 void cl_set_thread_batch_buf(cl_command_queue queue, void* buf)
 {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
 
-  assert(spec && spec->thread_magic == thread_magic);
+  assert(spec && spec->thread_magic == *magic);
 
   if (spec->thread_batch_buf) {
     cl_gpgpu_unref_batch_buf(spec->thread_batch_buf);
@@ -201,19 +262,29 @@  void cl_set_thread_batch_buf(cl_command_queue queue, void* buf)
 
 void* cl_get_thread_batch_buf(cl_command_queue queue) {
   thread_spec_data* spec = __create_thread_spec_data(queue, 1);
+#ifdef CONFIG_NO_TLS_THREAD
+  int *magic = pthread_getspecific(thread_magic_key);
+#else
+  int *magic = &thread_magic;
+#endif
 
-  assert(spec && spec->thread_magic == thread_magic);
+  assert(spec && spec->thread_magic == *magic);
 
   return spec->thread_batch_buf;
 }
 
 void cl_invalid_thread_gpgpu(cl_command_queue queue)
 {
+#ifdef CONFIG_NO_TLS_THREAD
+  int *id = pthread_getspecific(thread_id_key);
+#else
+  int *id = &thread_id;
+#endif
   queue_thread_private *thread_private = ((queue_thread_private *)(queue->thread_data));
   thread_spec_data* spec = NULL;
 
   pthread_mutex_lock(&thread_private->thread_data_lock);
-  spec = thread_private->threads_data[thread_id];
+  spec = thread_private->threads_data[*id];
   assert(spec);
   pthread_mutex_unlock(&thread_private->thread_data_lock);
 
@@ -229,11 +300,16 @@  void cl_invalid_thread_gpgpu(cl_command_queue queue)
 
 cl_gpgpu cl_thread_gpgpu_take(cl_command_queue queue)
 {
+#ifdef CONFIG_NO_TLS_THREAD
+  int *id = pthread_getspecific(thread_id_key);
+#else
+  int *id = &thread_id;
+#endif
   queue_thread_private *thread_private = ((queue_thread_private *)(queue->thread_data));
   thread_spec_data* spec = NULL;
 
   pthread_mutex_lock(&thread_private->thread_data_lock);
-  spec = thread_private->threads_data[thread_id];
+  spec = thread_private->threads_data[*id];
   assert(spec);
   pthread_mutex_unlock(&thread_private->thread_data_lock);
 
diff --git a/utests/utest_helper.hpp b/utests/utest_helper.hpp
index 95c32d1..a89f197 100644
--- a/utests/utest_helper.hpp
+++ b/utests/utest_helper.hpp
@@ -35,6 +35,10 @@ 
 #include <cstdio>
 #include <cstdlib>
 
+#if defined(__ANDROID__)
+#define __thread
+#endif
+
 #ifdef HAS_EGL
 #define EGL_WINDOW_WIDTH 256
 #define EGL_WINDOW_HEIGHT 256
diff --git a/utests/utest_run.cpp b/utests/utest_run.cpp
index 576d381..28fe4e5 100644
--- a/utests/utest_run.cpp
+++ b/utests/utest_run.cpp
@@ -89,7 +89,12 @@  int main(int argc, char *argv[])
 
       case 'j':
         try {
+#if defined(__ANDROID__)
+          std::cout << "Do not support multithread in android, use single thread instead." << std::endl;
+          UTest::run(optarg);
+#else
           UTest::runMultiThread(optarg);
+#endif
         }
         catch (Exception e){
           std::cout << "  " << e.what() << "    [SUCCESS]" << std::endl;