Skip to content

Commit 6d38e48

Browse files
committed
Fix existing tsan detected errors
1 parent 4ccf131 commit 6d38e48

File tree

2 files changed

+72
-71
lines changed

2 files changed

+72
-71
lines changed

.github/workflows/tsan.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
- name: test runtime
8686
run: |
8787
cd build
88-
ctest -v
88+
ctest -R acl_test -v
8989
9090
- name: tsan result
9191
uses: actions/upload-artifact@v2

test/acl_command_queue_test.cpp

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,73 @@ static void CL_CALLBACK notify_me(const char *errinfo, const void *private_info,
8080
private_info = private_info; // avoid warning on windows
8181
}
8282

83+
MT_TEST(acl_command_queue, after_context_release) {
84+
acl_set_allow_invalid_type<cl_command_queue>(1);
85+
// OpenCL 1.0 conformance_test_multiples will release the command queues
86+
// after the underlying contexts are gone.
87+
88+
cl_int status;
89+
cl_context context = clCreateContext(0, 1, &m_device[0], 0, 0, &status);
90+
CHECK_EQUAL(CL_SUCCESS, status);
91+
ACL_LOCKED(CHECK(acl_context_is_valid(context)));
92+
93+
status = 42;
94+
cl_command_queue cq0 = clCreateCommandQueue(context, m_device[0], 0, &status);
95+
CHECK(cq0);
96+
CHECK_EQUAL(CL_SUCCESS, status);
97+
98+
status = 95;
99+
cl_command_queue cq1 = clCreateCommandQueue(context, m_device[0], 0, &status);
100+
CHECK(cq1);
101+
CHECK_EQUAL(CL_SUCCESS, status);
102+
103+
// wait until all threads have their context and command queues before
104+
// continuing so that releasing them below won't cause them to be
105+
// immediately reused for another thread
106+
syncThreads();
107+
108+
// Early release of the context!
109+
CHECK_EQUAL(CL_SUCCESS, clReleaseContext(context));
110+
111+
CHECK(cq0);
112+
CHECK_EQUAL(1, acl_ref_count(cq0));
113+
CHECK(cq1);
114+
CHECK_EQUAL(1, acl_ref_count(cq1));
115+
116+
// Should be able to clFinish if there are no commands enqueued.
117+
CHECK_EQUAL(CL_SUCCESS, clFinish(cq0));
118+
CHECK_EQUAL(CL_SUCCESS, clFinish(cq1));
119+
// Should be able to clFlush if there are no commands enqueued.
120+
CHECK_EQUAL(CL_SUCCESS, clFlush(cq0));
121+
CHECK_EQUAL(CL_SUCCESS, clFlush(cq1));
122+
123+
// Should be able to retain....
124+
CHECK_EQUAL(CL_SUCCESS, clRetainCommandQueue(cq0));
125+
CHECK_EQUAL(CL_SUCCESS, clRetainCommandQueue(cq1));
126+
CHECK_EQUAL(2, acl_ref_count(cq0));
127+
CHECK_EQUAL(2, acl_ref_count(cq1));
128+
129+
// Should be able to release...
130+
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq0));
131+
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq1));
132+
CHECK_EQUAL(1, acl_ref_count(cq0));
133+
CHECK_EQUAL(1, acl_ref_count(cq1));
134+
135+
// Should be able to release all the way.
136+
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq0));
137+
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq1));
138+
// Should not access an object after it is freed
139+
// CHECK_EQUAL(0, acl_ref_count(cq0));
140+
// CHECK_EQUAL(0, acl_ref_count(cq1));
141+
142+
// ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq0)));
143+
// ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq1)));
144+
145+
// And once it's gone, it's gone.
146+
// CHECK_EQUAL(CL_INVALID_COMMAND_QUEUE, clReleaseCommandQueue(cq0));
147+
// CHECK_EQUAL(CL_INVALID_COMMAND_QUEUE, clReleaseCommandQueue(cq1));
148+
}
149+
83150
MT_TEST(acl_command_queue, create) {
84151
acl_set_allow_invalid_type<cl_command_queue>(1);
85152
cl_int status;
@@ -387,8 +454,8 @@ MT_TEST(acl_command_queue, create_with_properties) {
387454
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq));
388455
CHECK_EQUAL(1, acl_ref_count(cq));
389456
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq));
390-
CHECK_EQUAL(0, acl_ref_count(cq));
391-
ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq)));
457+
// CHECK_EQUAL(0, acl_ref_count(cq));
458+
// ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq)));
392459

393460
// wait until all threads do their checks on the 0-ref-count command
394461
// queue before starting the next iteration of the loop and creating new
@@ -421,8 +488,8 @@ MT_TEST(acl_command_queue, create_with_properties) {
421488
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq));
422489
CHECK_EQUAL(1, acl_ref_count(cq));
423490
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq));
424-
CHECK_EQUAL(0, acl_ref_count(cq));
425-
ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq)));
491+
// CHECK_EQUAL(0, acl_ref_count(cq));
492+
// ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq)));
426493

427494
// wait until all threads do their checks on the 0-ref-count command
428495
// queue before starting the next iteration of the loop and creating new
@@ -619,72 +686,6 @@ MT_TEST(acl_command_queue, set_prop) {
619686
}
620687
#endif
621688

622-
MT_TEST(acl_command_queue, after_context_release) {
623-
acl_set_allow_invalid_type<cl_command_queue>(1);
624-
// OpenCL 1.0 conformance_test_multiples will release the command queues
625-
// after the underlying contexts are gone.
626-
627-
cl_int status;
628-
cl_context context = clCreateContext(0, 1, &m_device[0], 0, 0, &status);
629-
CHECK_EQUAL(CL_SUCCESS, status);
630-
ACL_LOCKED(CHECK(acl_context_is_valid(context)));
631-
632-
status = 42;
633-
cl_command_queue cq0 = clCreateCommandQueue(context, m_device[0], 0, &status);
634-
CHECK(cq0);
635-
CHECK_EQUAL(CL_SUCCESS, status);
636-
637-
status = 95;
638-
cl_command_queue cq1 = clCreateCommandQueue(context, m_device[0], 0, &status);
639-
CHECK(cq1);
640-
CHECK_EQUAL(CL_SUCCESS, status);
641-
642-
// wait until all threads have their context and command queues before
643-
// continuing so that releasing them below won't cause them to be
644-
// immediately reused for another thread
645-
syncThreads();
646-
647-
// Early release of the context!
648-
CHECK_EQUAL(CL_SUCCESS, clReleaseContext(context));
649-
650-
CHECK(cq0);
651-
CHECK_EQUAL(1, acl_ref_count(cq0));
652-
CHECK(cq1);
653-
CHECK_EQUAL(1, acl_ref_count(cq1));
654-
655-
// Should be able to clFinish if there are no commands enqueued.
656-
CHECK_EQUAL(CL_SUCCESS, clFinish(cq0));
657-
CHECK_EQUAL(CL_SUCCESS, clFinish(cq1));
658-
// Should be able to clFlush if there are no commands enqueued.
659-
CHECK_EQUAL(CL_SUCCESS, clFlush(cq0));
660-
CHECK_EQUAL(CL_SUCCESS, clFlush(cq1));
661-
662-
// Should be able to retain....
663-
CHECK_EQUAL(CL_SUCCESS, clRetainCommandQueue(cq0));
664-
CHECK_EQUAL(CL_SUCCESS, clRetainCommandQueue(cq1));
665-
CHECK_EQUAL(2, acl_ref_count(cq0));
666-
CHECK_EQUAL(2, acl_ref_count(cq1));
667-
668-
// Should be able to release...
669-
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq0));
670-
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq1));
671-
CHECK_EQUAL(1, acl_ref_count(cq0));
672-
CHECK_EQUAL(1, acl_ref_count(cq1));
673-
674-
// Should be able to release all the way.
675-
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq0));
676-
CHECK_EQUAL(CL_SUCCESS, clReleaseCommandQueue(cq1));
677-
CHECK_EQUAL(0, acl_ref_count(cq0));
678-
CHECK_EQUAL(0, acl_ref_count(cq1));
679-
680-
ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq0)));
681-
ACL_LOCKED(CHECK(!acl_command_queue_is_valid(cq1)));
682-
683-
// And once it's gone, it's gone.
684-
CHECK_EQUAL(CL_INVALID_COMMAND_QUEUE, clReleaseCommandQueue(cq0));
685-
CHECK_EQUAL(CL_INVALID_COMMAND_QUEUE, clReleaseCommandQueue(cq1));
686-
}
687-
688689
// Main Event is in an OOO queue. It has a dependent event in an in-order queue.
689690
// Test that completing the main event, will unblock the dependent event.
690691
MT_TEST(acl_command_queue, mixed_queue_dependencies_1) {

0 commit comments

Comments
 (0)