Skip to content

Commit 169815f

Browse files
jtb20shiltian
andauthored
[OpenMP] Fixed an issue that taskwait doesn't work on detachable task (llvm#3005)
It appears that this patch (fixing SWDEV-510164) got lost during (many) merges from mainline. This PR reapplies it. Original log (by Shilei Tian) follows: D77609 mistakenly changed the bebavior of task waiting on detachable task that a detachable task is not waited, based on https://lists.llvm.org/pipermail/openmp-dev/2021-February/003836.html. This patch fixed it. Thank Raúl for the report. Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D95798 Co-authored-by: Shilei Tian <[email protected]>
1 parent c491482 commit 169815f

File tree

2 files changed

+116
-1
lines changed

2 files changed

+116
-1
lines changed

openmp/runtime/src/kmp_tasking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1517,7 +1517,7 @@ kmp_task_t *__kmp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
15171517
}
15181518
}
15191519

1520-
if (flags->proxy == TASK_PROXY &&
1520+
if ((flags->proxy == TASK_PROXY || flags->detachable == TASK_DETACHABLE) &&
15211521
task_team->tt.tt_found_proxy_tasks == FALSE)
15221522
TCW_4(task_team->tt.tt_found_proxy_tasks, TRUE);
15231523
if (flags->hidden_helper &&
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// RUN: %libomp-cxx-compile-and-run
2+
3+
#include <omp.h>
4+
5+
#include <chrono>
6+
#include <iostream>
7+
#include <thread>
8+
9+
// detached
10+
#define PTASK_FLAG_DETACHABLE 0x40
11+
12+
// OpenMP RTL interfaces
13+
typedef long long kmp_int64;
14+
15+
typedef struct ID {
16+
int reserved_1;
17+
int flags;
18+
int reserved_2;
19+
int reserved_3;
20+
char *psource;
21+
} id;
22+
23+
// Compiler-generated code (emulation)
24+
typedef struct ident {
25+
void *dummy; // not used in the library
26+
} ident_t;
27+
28+
typedef enum kmp_event_type_t {
29+
KMP_EVENT_UNINITIALIZED = 0,
30+
KMP_EVENT_ALLOW_COMPLETION = 1
31+
} kmp_event_type_t;
32+
33+
typedef struct {
34+
kmp_event_type_t type;
35+
union {
36+
void *task;
37+
} ed;
38+
} kmp_event_t;
39+
40+
typedef struct shar { // shareds used in the task
41+
} * pshareds;
42+
43+
typedef struct task {
44+
pshareds shareds;
45+
int (*routine)(int, struct task *);
46+
int part_id;
47+
// void *destructor_thunk; // optional, needs flag setting if provided
48+
// int priority; // optional, needs flag setting if provided
49+
// ------------------------------
50+
// privates used in the task:
51+
omp_event_handle_t evt;
52+
} * ptask, kmp_task_t;
53+
54+
typedef int (*task_entry_t)(int, ptask);
55+
56+
#ifdef __cplusplus
57+
extern "C" {
58+
#endif
59+
extern int __kmpc_global_thread_num(void *id_ref);
60+
extern int **__kmpc_omp_task_alloc(id *loc, int gtid, int flags, size_t sz,
61+
size_t shar, task_entry_t rtn);
62+
extern int __kmpc_omp_task(id *loc, kmp_int64 gtid, kmp_task_t *task);
63+
extern omp_event_handle_t __kmpc_task_allow_completion_event(ident_t *loc_ref,
64+
int gtid,
65+
kmp_task_t *task);
66+
#ifdef __cplusplus
67+
}
68+
#endif
69+
70+
int volatile checker;
71+
72+
void target(ptask task) {
73+
std::this_thread::sleep_for(std::chrono::seconds(3));
74+
checker = 1;
75+
omp_fulfill_event(task->evt);
76+
}
77+
78+
// User's code
79+
int task_entry(int gtid, ptask task) {
80+
std::thread t(target, task);
81+
t.detach();
82+
return 0;
83+
}
84+
85+
int main(int argc, char *argv[]) {
86+
int gtid = __kmpc_global_thread_num(nullptr);
87+
checker = 0;
88+
89+
/*
90+
#pragma omp task detach(evt)
91+
{}
92+
*/
93+
std::cout << "detaching...\n";
94+
ptask task = (ptask)__kmpc_omp_task_alloc(
95+
nullptr, gtid, PTASK_FLAG_DETACHABLE, sizeof(struct task),
96+
sizeof(struct shar), &task_entry);
97+
omp_event_handle_t evt =
98+
(omp_event_handle_t)__kmpc_task_allow_completion_event(nullptr, gtid,
99+
task);
100+
task->evt = evt;
101+
102+
__kmpc_omp_task(nullptr, gtid, task);
103+
104+
#pragma omp taskwait
105+
106+
// check results
107+
if (checker == 1) {
108+
std::cout << "PASS\n";
109+
return 0;
110+
}
111+
112+
return 1;
113+
}
114+
115+
// CHECK: PASS

0 commit comments

Comments
 (0)