Skip to content

Commit

Permalink
Retain the event that will be used for waiting.
Browse files Browse the repository at this point in the history
When a non-blocking operation with native source memory
is enqueued, the event will be used to determine when
the source object can be released for garbage collection.
But when the associated event was released manually,
before the wait operation could start, this caused a
painful crash in clWaitForEvents. Increasing the reference
count of the event with clRetainEvent will prevent this.
  • Loading branch information
gpu committed Oct 11, 2016
1 parent e2895ab commit 5c6e44f
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions src/main/java/org/jocl/CL.java
Original file line number Diff line number Diff line change
Expand Up @@ -2023,11 +2023,14 @@ public static void setLogLevel(LogLevel logLevel)
*
* @param event The event to wait for
* @param object The object to which a reference should be kept
* @param doReleaseEvent Whether the event was solely created
* for this method and should be released here
* @param doRetainEvent Whether the event was given to the calling method
* from outside. If this is <code>true</code>, then the event has to be
* retained (in order to increase its reference count), so that it will
* not become invalid when the user calls <code>clReleaseEvent</code>
* on it before the waiting operation started.
*/
private static void scheduleReferenceRelease(
final cl_event event, final Object object, final boolean doReleaseEvent)
final cl_event event, final Object object, final boolean doRetainEvent)
{
Runnable runnable = new Runnable()
{
Expand All @@ -2041,12 +2044,13 @@ private static void scheduleReferenceRelease(
public void run()
{
clWaitForEvents(1, new cl_event[]{event});
if (doReleaseEvent)
{
clReleaseEvent(event);
}
clReleaseEvent(event);
}
};
if (doRetainEvent)
{
clRetainEvent(event);
}
referenceReleaseExecutor.execute(runnable);

}
Expand Down Expand Up @@ -16365,10 +16369,10 @@ public static int clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem buf
}
else
{
boolean doReleaseEvent = false;
boolean doRetainEvent = true;
if (event == null)
{
doReleaseEvent = true;
doRetainEvent = false;
event = new cl_event();
}
int result = clEnqueueReadBufferNative(command_queue, buffer, blocking_read, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
Expand Down Expand Up @@ -16917,17 +16921,17 @@ public static int clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem bu
}
else
{
boolean doReleaseEvent = false;
boolean doRetainEvent = true;
if (event == null)
{
doReleaseEvent = true;
doRetainEvent = false;
event = new cl_event();
}
int result = clEnqueueWriteBufferNative(command_queue, buffer, blocking_write, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
// Only schedule the reference release if the enqueue succeeds.
if (result == CL_SUCCESS)
{
scheduleReferenceRelease(event, ptr, doReleaseEvent);
scheduleReferenceRelease(event, ptr, doRetainEvent);
}
return checkResult(result);
}
Expand Down Expand Up @@ -18528,17 +18532,17 @@ public static int clEnqueueWriteImage(cl_command_queue command_queue, cl_mem ima
}
else
{
boolean doReleaseEvent = false;
boolean doRetainEvent = true;
if (event == null)
{
doReleaseEvent = true;
doRetainEvent = false;
event = new cl_event();
}
int result = clEnqueueWriteImageNative(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
// Only schedule the reference release if the enqueue succeeds.
if (result == CL_SUCCESS)
{
scheduleReferenceRelease(event, ptr, doReleaseEvent);
scheduleReferenceRelease(event, ptr, doRetainEvent);
}
return checkResult(result);
}
Expand Down Expand Up @@ -20231,17 +20235,17 @@ public static ByteBuffer clEnqueueMapImage(cl_command_queue command_queue, cl_me
*/
public static int clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_mem memobj, ByteBuffer mapped_ptr, int num_events_in_wait_list, cl_event event_wait_list[], cl_event event)
{
boolean doReleaseEvent = false;
boolean doRetainEvent = true;
if (event == null)
{
doReleaseEvent = true;
doRetainEvent = false;
event = new cl_event();
}
int result = clEnqueueUnmapMemObjectNative(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
// Only schedule the reference release if the enqueue succeeds.
if (result == CL_SUCCESS)
{
scheduleReferenceRelease(event, mapped_ptr, doReleaseEvent);
scheduleReferenceRelease(event, mapped_ptr, doRetainEvent);
}
return checkResult(result);
}
Expand Down

0 comments on commit 5c6e44f

Please sign in to comment.