]> git.pld-linux.org Git - packages/beignet.git/blame - beignet-eventchain-memory-leak.patch
- merged some Debian patches
[packages/beignet.git] / beignet-eventchain-memory-leak.patch
CommitLineData
7d3d7cb5
JB
1Description: Don't leak memory on long chains of events
2
3Delete event->depend_events when no longer needed to avoid keeping
4the whole dependency tree in memory as long as the final event exists
5
6Author: Rebecca N. Palmer <rebecca_palmer@zoho.com>
7Bug-Ubuntu: https://launchpad.net/bugs/1354086
8Forwarded: https://lists.freedesktop.org/archives/beignet/2018-July/009209.html
9
10--- a/src/cl_event.c
11+++ b/src/cl_event.c
12@@ -184,6 +184,25 @@ cl_event_new(cl_context ctx, cl_command_
13 return e;
14 }
15
16+/* This exists to prevent long chains of events from filling up memory (https://bugs.launchpad.net/ubuntu/+source/beignet/+bug/1354086). Call only after the dependencies are complete, or failed and marked as such in this event's status, or when this event is being destroyed */
17+LOCAL void
18+cl_event_delete_depslist(cl_event event)
19+{
20+ CL_OBJECT_LOCK(event);
21+ cl_event *old_depend_events = event->depend_events;
22+ int depend_count = event->depend_event_num;
23+ event->depend_event_num = 0;
24+ event->depend_events = NULL;
25+ CL_OBJECT_UNLOCK(event);
26+ if (old_depend_events) {
27+ assert(depend_count);
28+ for (int i = 0; i < depend_count; i++) {
29+ cl_event_delete(old_depend_events[i]);
30+ }
31+ cl_free(old_depend_events);
32+ }
33+}
34+
35 LOCAL void
36 cl_event_delete(cl_event event)
37 {
38@@ -200,13 +219,7 @@ cl_event_delete(cl_event event)
39
40 assert(list_node_out_of_list(&event->enqueue_node));
41
42- if (event->depend_events) {
43- assert(event->depend_event_num);
44- for (i = 0; i < event->depend_event_num; i++) {
45- cl_event_delete(event->depend_events[i]);
46- }
47- cl_free(event->depend_events);
48- }
49+ cl_event_delete_depslist(event);
50
51 /* Free all the callbacks. Last ref, no need to lock. */
52 while (!list_empty(&event->callbacks)) {
53@@ -566,8 +579,12 @@ cl_event_exec(cl_event event, cl_int exe
54 assert(depend_status <= CL_COMPLETE || ignore_depends || exec_to_status == CL_QUEUED);
55 if (depend_status < CL_COMPLETE) { // Error happend, cancel exec.
56 ret = cl_event_set_status(event, depend_status);
57+ cl_event_delete_depslist(event);
58 return depend_status;
59 }
60+ if (depend_status == CL_COMPLETE) { // Avoid memory leak
61+ cl_event_delete_depslist(event);
62+ }
63
64 if (cur_status <= exec_to_status) {
65 return ret;
66--- a/src/cl_event.h
67+++ b/src/cl_event.h
68@@ -44,7 +44,7 @@ typedef struct _cl_event {
69 cl_command_type event_type; /* Event type. */
70 cl_bool is_barrier; /* Is this event a barrier */
71 cl_int status; /* The execution status */
72- cl_event *depend_events; /* The events must complete before this. */
73+ cl_event *depend_events; /* The events must complete before this. May disappear after they have completed - see cl_event_delete_depslist*/
74 cl_uint depend_event_num; /* The depend events number. */
75 list_head callbacks; /* The events The event callback functions */
76 list_node enqueue_node; /* The node in the enqueue list. */
This page took 0.087554 seconds and 4 git commands to generate.