]> granicus.if.org Git - imagemagick/commitdiff
Changed the OpenCL relinquish code to make sure all events are completed.
authorDirk Lemstra <dirk@git.imagemagick.org>
Sun, 15 Oct 2017 07:29:32 +0000 (09:29 +0200)
committerDirk Lemstra <dirk@git.imagemagick.org>
Sun, 15 Oct 2017 07:30:30 +0000 (09:30 +0200)
MagickCore/opencl.c

index 5ff8443318b13bf57ce09e7f8d836fe722275dce..019f93f74d9dfd25d52300ef04adb1d7c121581f 100644 (file)
@@ -442,6 +442,21 @@ static size_t StringSignature(const char* string)
   return(signature);
 }
 
+static void DestroyMagickCLCacheInfo(MagickCLCacheInfo info)
+{
+  ssize_t
+    i;
+
+  for (i=0; i < (ssize_t) info->event_count; i++)
+    openCL_library->clReleaseEvent(info->events[i]);
+  info->events=(cl_event *) RelinquishMagickMemory(info->events);
+  if (info->buffer != (cl_mem) NULL)
+    openCL_library->clReleaseMemObject(info->buffer);
+  RelinquishSemaphoreInfo(&info->events_semaphore);
+  ReleaseOpenCLDevice(info->device);
+  RelinquishMagickMemory(info);
+}
+
 /*
   Provide call to OpenCL library methods
 */
@@ -507,9 +522,7 @@ MagickPrivate MagickCLCacheInfo AcquireMagickCLCacheInfo(MagickCLDevice device,
   MagickCLCacheInfo
     info;
 
-  info=(MagickCLCacheInfo) AcquireMagickMemory(sizeof(*info));
-  if (info == (MagickCLCacheInfo) NULL)
-    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
+  info=(MagickCLCacheInfo) AcquireCriticalMemory(sizeof(*info));
   (void) ResetMagickMemory(info,0,sizeof(*info));
   LockSemaphoreInfo(openCL_lock);
   device->requested++;
@@ -523,10 +536,8 @@ MagickPrivate MagickCLCacheInfo AcquireMagickCLCacheInfo(MagickCLDevice device,
     &status);
   if (status == CL_SUCCESS)
     return(info);
-  LockSemaphoreInfo(openCL_lock);
-  device->requested--;
-  UnlockSemaphoreInfo(openCL_lock);
-  return((MagickCLCacheInfo) RelinquishMagickMemory(info));
+  DestroyMagickCLCacheInfo(info);
+  return((MagickCLCacheInfo) NULL);
 }
 
 /*
@@ -2838,20 +2849,6 @@ MagickPrivate void ReleaseOpenCLDevice(MagickCLDevice device)
 %    o relinquish_pixels: the pixels will be relinquish when set to true.
 %
 */
-static void DestroyMagickCLCacheInfo(MagickCLCacheInfo info)
-{
-  ssize_t
-    i;
-
-  for (i=0; i < (ssize_t) info->event_count; i++)
-    openCL_library->clReleaseEvent(info->events[i]);
-  info->events=(cl_event *) RelinquishMagickMemory(info->events);
-  if (info->buffer != (cl_mem) NULL)
-    openCL_library->clReleaseMemObject(info->buffer);
-  RelinquishSemaphoreInfo(&info->events_semaphore);
-  ReleaseOpenCLDevice(info->device);
-  RelinquishMagickMemory(info);
-}
 
 static void CL_API_CALL DestroyMagickCLCacheInfoAndPixels(
   cl_event magick_unused(event),
@@ -2863,9 +2860,30 @@ static void CL_API_CALL DestroyMagickCLCacheInfoAndPixels(
   Quantum
     *pixels;
 
+  ssize_t
+    i;
+
   magick_unreferenced(event);
   magick_unreferenced(event_command_exec_status);
   info=(MagickCLCacheInfo) user_data;
+  for (i=(ssize_t)info->event_count-1; i >= 0; i--)
+  {
+    cl_int
+      event_status;
+  
+    cl_uint
+      status;
+
+    status=openCL_library->clGetEventInfo(info->events[i],
+      CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof(event_status),&event_status, 
+      NULL);
+    if ((status == CL_SUCCESS) && (event_status != CL_COMPLETE))
+      {
+        openCL_library->clSetEventCallback(info->events[i],CL_COMPLETE,
+          &DestroyMagickCLCacheInfoAndPixels,info);
+        return;
+      }
+  }
   pixels=info->pixels;
   RelinquishMagickResource(MemoryResource,info->length);
   DestroyMagickCLCacheInfo(info);
@@ -2878,36 +2896,7 @@ MagickPrivate MagickCLCacheInfo RelinquishMagickCLCacheInfo(
   if (info == (MagickCLCacheInfo) NULL)
     return((MagickCLCacheInfo) NULL);
   if (relinquish_pixels != MagickFalse)
-    {
-      MagickBooleanType
-        events_completed;
-
-      ssize_t
-        i;
-
-      events_completed=MagickTrue;
-      for (i=0; i < (ssize_t)info->event_count; i++)
-      {
-        cl_int
-          event_status;
-
-        cl_uint
-          status;
-
-        status=openCL_library->clGetEventInfo(info->events[i],
-          CL_EVENT_COMMAND_EXECUTION_STATUS,sizeof(cl_int),&event_status,NULL);
-        if ((status == CL_SUCCESS) && (event_status != CL_COMPLETE))
-          {
-            events_completed=MagickFalse;
-            break;
-          }
-      }
-      if (events_completed == MagickFalse)
-        openCL_library->clSetEventCallback(info->events[info->event_count-1],
-          CL_COMPLETE,&DestroyMagickCLCacheInfoAndPixels,info);
-      else
-        DestroyMagickCLCacheInfoAndPixels((cl_event) NULL,0,info);
-    }
+    DestroyMagickCLCacheInfoAndPixels((cl_event) NULL,0,info);
   else
     DestroyMagickCLCacheInfo(info);
   return((MagickCLCacheInfo) NULL);