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

Yang Rong rong.r.yang at intel.com
Wed May 25 05:27:21 UTC 2016


Android doesn't support __thread keyword, so use pthread instead in
cl_thread.c and disable multithread in the utest.

V2: remove __thread in the scr/cl_thread.
Signed-off-by: Yang Rong <rong.r.yang at intel.com>
---
 src/cl_thread.c         | 74 ++++++++++++++++++++++++++++++++++---------------
 utests/utest_helper.hpp |  4 +++
 utests/utest_run.cpp    |  5 ++++
 3 files changed, 61 insertions(+), 22 deletions(-)

diff --git a/src/cl_thread.c b/src/cl_thread.c
index 5e5a351..8f1dd3f 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,42 @@ typedef struct _queue_thread_private {
   pthread_mutex_t thread_data_lock;
 } queue_thread_private;
 
+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);
+}
+
 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;
+  int *id = NULL, *magic = NULL;
+
+  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);
+  }
 
-  if (thread_id == -1) {
-
+  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 +97,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 +116,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 +132,32 @@ 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);
+  int *magic = pthread_getspecific(thread_magic_key);
+  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);
+  int *magic = pthread_getspecific(thread_magic_key);
+  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);
+  int *magic = pthread_getspecific(thread_magic_key);
+  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);
+  int *magic = pthread_getspecific(thread_magic_key);
+  assert(spec && spec->thread_magic == *magic);
   spec->last_event = e;
 }
 
@@ -164,8 +189,9 @@ 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);
+  int *magic = pthread_getspecific(thread_magic_key);
 
-  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 +216,9 @@ 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);
+  int *magic = pthread_getspecific(thread_magic_key);
 
-  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 +228,21 @@ 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);
+  int *magic = pthread_getspecific(thread_magic_key);
 
-  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)
 {
+  int *id = pthread_getspecific(thread_id_key);
   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 +258,12 @@ void cl_invalid_thread_gpgpu(cl_command_queue queue)
 
 cl_gpgpu cl_thread_gpgpu_take(cl_command_queue queue)
 {
+  int *id = pthread_getspecific(thread_id_key);
   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;
-- 
2.1.4



More information about the Beignet mailing list