[Beignet] [PATCH] Fix the bug of multi-thread crash

junyan.he at inbox.com junyan.he at inbox.com
Wed Nov 12 23:19:29 PST 2014


From: Junyan He <junyan.he at linux.intel.com>

The cl_thread has a potential problem.
If the threads are created and destroyed very fast,
while the queue remain avaible, the resource of
destroyed thread will not be free correctly.

Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
 src/cl_thread.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/cl_thread.c b/src/cl_thread.c
index d4de1b3..ce3eab9 100644
--- a/src/cl_thread.c
+++ b/src/cl_thread.c
@@ -4,7 +4,7 @@
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
+ * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -55,11 +55,28 @@ typedef struct _queue_thread_private {
   pthread_mutex_t thread_data_lock;
 } queue_thread_private;
 
-static void thread_data_destructor(void *dummy) {
+static void thread_data_destructor(void *queue_thread) {
+  thread_spec_data* spec = NULL;
+  queue_thread_private *thread_private = (queue_thread_private *)queue_thread;
+
   pthread_mutex_lock(&thread_queue_map_lock);
   thread_slot_map[thread_id] = 0;
   pthread_mutex_unlock(&thread_queue_map_lock);
-  free(dummy);
+
+  pthread_mutex_lock(&thread_private->thread_data_lock);
+  spec = thread_private->threads_data[thread_id];
+  thread_private->threads_data[thread_id] = NULL;
+  pthread_mutex_unlock(&thread_private->thread_data_lock);
+
+  if (!spec || !spec->valid) {
+    return;
+  }
+
+  assert(spec->gpgpu);
+  cl_gpgpu_delete(spec->gpgpu);
+  spec->gpgpu = NULL;
+  spec->valid = 0;
+  free(spec);
 }
 
 static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int create)
@@ -69,8 +86,6 @@ static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
   int i = 0;
 
   if (thread_id == -1) {
-    void * dummy = malloc(sizeof(int));
-
     pthread_mutex_lock(&thread_queue_map_lock);
     for (i = 0; i < thread_array_num; i++) {
       if (thread_slot_map[i] == 0) {
@@ -91,9 +106,10 @@ static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
     thread_magic = thread_magic_num++;
     pthread_mutex_unlock(&thread_queue_map_lock);
 
-    pthread_setspecific(destroy_key, dummy);
+    pthread_setspecific(destroy_key, thread_private);
   }
 
+
   pthread_mutex_lock(&thread_private->thread_data_lock);
   if (thread_array_num > thread_private->threads_data_num) {// just enlarge
     int old_num = thread_private->threads_data_num;
@@ -113,7 +129,6 @@ static thread_spec_data * __create_thread_spec_data(cl_command_queue queue, int
   }
 
   pthread_mutex_unlock(&thread_private->thread_data_lock);
-
   return spec;
 }
 
-- 
1.9.1



More information about the Beignet mailing list