[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