mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-30 03:38:05 +00:00
New implementation of OpenMP 5.0 detached tasks.
Patch by Alex Duran Differential Revision: https://reviews.llvm.org/D62485 llvm-svn: 363799
This commit is contained in:
parent
982a1cf028
commit
405037c4e6
@ -408,7 +408,7 @@ kmpc_set_disp_num_buffers 267
|
||||
__kmpc_pause_resource 273
|
||||
__kmpc_task_reduction_modifier_init 274
|
||||
__kmpc_task_reduction_modifier_fini 275
|
||||
# __kmpc_task_allow_completion_event 276
|
||||
__kmpc_task_allow_completion_event 276
|
||||
__kmpc_taskred_init 277
|
||||
__kmpc_taskred_modifier_init 278
|
||||
%endif
|
||||
@ -572,6 +572,7 @@ kmp_set_disp_num_buffers 890
|
||||
omp_pause_resource 756
|
||||
omp_pause_resource_all 757
|
||||
omp_get_supported_active_levels 758
|
||||
omp_fulfill_event 759
|
||||
|
||||
omp_null_allocator DATA
|
||||
omp_default_mem_alloc DATA
|
||||
|
@ -334,6 +334,15 @@
|
||||
extern void __KAI_KMPC_CONVENTION omp_display_affinity(char const *);
|
||||
extern size_t __KAI_KMPC_CONVENTION omp_capture_affinity(char *, size_t, char const *);
|
||||
|
||||
/* OpenMP 5.0 events */
|
||||
# if defined(_WIN32)
|
||||
// On Windows cl and icl do not support 64-bit enum, let's use integer then.
|
||||
typedef omp_uintptr_t omp_event_handle_t;
|
||||
# else
|
||||
typedef enum omp_event_handle_t { KMP_EVENT_MAX_HANDLE = UINTPTR_MAX } omp_event_handle_t;
|
||||
# endif
|
||||
extern void __KAI_KMPC_CONVENTION omp_fulfill_event ( omp_event_handle_t event );
|
||||
|
||||
/* OpenMP 5.0 Pause Resources */
|
||||
typedef enum omp_pause_resource_t {
|
||||
omp_pause_resume = 0,
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
integer, parameter :: omp_pause_resource_kind = omp_integer_kind
|
||||
integer, parameter :: omp_depend_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_event_handle_kind = int_ptr_kind()
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
@ -351,6 +352,11 @@
|
||||
integer (kind=omp_integer_kind) omp_get_supported_active_levels
|
||||
end function omp_get_supported_active_levels
|
||||
|
||||
subroutine omp_fulfill_event(event)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_event_handle_kind) event
|
||||
end subroutine omp_fulfill_event
|
||||
|
||||
subroutine omp_init_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
@ -705,6 +711,7 @@
|
||||
!dec$ attributes alias:'OMP_PAUSE_RESOURCE' :: omp_pause_resource
|
||||
!dec$ attributes alias:'OMP_PAUSE_RESOURCE_ALL' :: omp_pause_resource_all
|
||||
!dec$ attributes alias:'OMP_GET_SUPPORTED_ACTIVE_LEVELS' :: omp_get_supported_active_levels
|
||||
!dec$ attributes alias:'OMP_FULFILL_EVENT' :: omp_fulfill_event
|
||||
|
||||
!dec$ attributes alias:'OMP_CONTROL_TOOL' :: omp_control_tool
|
||||
!dec$ attributes alias:'OMP_SET_AFFINITY_FORMAT' :: omp_set_affinity_format
|
||||
@ -796,6 +803,7 @@
|
||||
!dec$ attributes alias:'_OMP_PAUSE_RESOURCE' :: omp_pause_resource
|
||||
!dec$ attributes alias:'_OMP_PAUSE_RESOURCE_ALL' :: omp_pause_resource_all
|
||||
!dec$ attributes alias:'_OMP_GET_SUPPORTED_ACTIVE_LEVELS' :: omp_get_supported_active_levels
|
||||
!dec$ attributes alias:'_OMP_FULFILL_EVENT' :: omp_fulfill_event
|
||||
|
||||
!dec$ attributes alias:'_OMP_CONTROL_TOOL' :: omp_control_tool
|
||||
!dec$ attributes alias:'_OMP_SET_AFFINITY_FORMAT' :: omp_set_affinity_format
|
||||
@ -890,6 +898,7 @@
|
||||
!dec$ attributes alias:'omp_pause_resource_' :: omp_pause_resource
|
||||
!dec$ attributes alias:'omp_pause_resource_all_' :: omp_pause_resource_all
|
||||
!dec$ attributes alias:'omp_get_supported_active_levels_' :: omp_get_supported_active_levels
|
||||
!dec$ attributes alias:'omp_fulfill_event_' :: omp_fulfill_event
|
||||
|
||||
!dec$ attributes alias:'omp_set_affinity_format_' :: omp_set_affinity_format
|
||||
!dec$ attributes alias:'omp_get_affinity_format_' :: omp_get_affinity_format
|
||||
@ -983,6 +992,7 @@
|
||||
!dec$ attributes alias:'_omp_pause_resource_' :: omp_pause_resource
|
||||
!dec$ attributes alias:'_omp_pause_resource_all_' :: omp_pause_resource_all
|
||||
!dec$ attributes alias:'_omp_get_supported_active_levels_' :: omp_get_supported_active_levels
|
||||
!dec$ attributes alias:'_omp_fulfill_event_' :: omp_fulfill_event
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock_'::omp_init_lock
|
||||
!dec$ attributes alias:'_omp_init_lock_with_hint_'::omp_init_lock_with_hint
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
integer, parameter :: omp_pause_resource_kind = omp_integer_kind
|
||||
integer, parameter :: omp_depend_kind = c_intptr_t
|
||||
integer, parameter :: omp_event_handle_kind = c_intptr_t
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
@ -366,6 +367,11 @@
|
||||
integer (kind=omp_integer_kind) omp_get_supported_active_levels
|
||||
end function omp_get_supported_active_levels
|
||||
|
||||
subroutine omp_fulfill_event(event) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_event_handle_kind), value :: event
|
||||
end subroutine omp_fulfill_event
|
||||
|
||||
subroutine omp_init_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
|
@ -50,6 +50,8 @@
|
||||
parameter(omp_pause_resource_kind=omp_integer_kind)
|
||||
integer omp_depend_kind
|
||||
parameter(omp_depend_kind=int_ptr_kind())
|
||||
integer omp_event_handle_kind
|
||||
parameter(omp_event_handle_kind=int_ptr_kind())
|
||||
|
||||
integer(kind=omp_integer_kind)openmp_version
|
||||
parameter(openmp_version=@LIBOMP_OMP_YEAR_MONTH@)
|
||||
@ -442,6 +444,11 @@
|
||||
integer (kind=omp_integer_kind) omp_get_supported_active_levels
|
||||
end function omp_get_supported_active_levels
|
||||
|
||||
subroutine omp_fulfill_event(event) bind(c)
|
||||
import
|
||||
integer (kind=omp_event_handle_kind), value :: event
|
||||
end subroutine omp_fulfill_event
|
||||
|
||||
subroutine omp_init_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
@ -778,6 +785,7 @@
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource_all
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_supported_active_levels
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_fulfill_event
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_teams
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_team_num
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_lock
|
||||
@ -860,6 +868,7 @@
|
||||
!$omp declare target(omp_pause_resource )
|
||||
!$omp declare target(omp_pause_resource_all )
|
||||
!$omp declare target(omp_get_supported_active_levels )
|
||||
!$omp declare target(omp_fulfill_event)
|
||||
!$omp declare target(omp_get_num_teams )
|
||||
!$omp declare target(omp_get_team_num )
|
||||
!$omp declare target(omp_init_lock )
|
||||
|
@ -48,6 +48,8 @@
|
||||
#define TASK_IMPLICIT 0
|
||||
#define TASK_PROXY 1
|
||||
#define TASK_FULL 0
|
||||
#define TASK_DETACHABLE 1
|
||||
#define TASK_UNDETACHABLE 0
|
||||
|
||||
#define KMP_CANCEL_THREADS
|
||||
#define KMP_THREAD_ATTR
|
||||
@ -2269,6 +2271,19 @@ typedef struct kmp_task_affinity_info {
|
||||
kmp_int32 reserved : 30;
|
||||
} flags;
|
||||
} kmp_task_affinity_info_t;
|
||||
|
||||
typedef enum kmp_event_type_t {
|
||||
KMP_EVENT_UNINITIALIZED = 0,
|
||||
KMP_EVENT_ALLOW_COMPLETION = 1
|
||||
} kmp_event_type_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_event_type_t type;
|
||||
kmp_tas_lock_t lock;
|
||||
union {
|
||||
kmp_task_t *task;
|
||||
} ed;
|
||||
} kmp_event_t;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -2304,7 +2319,8 @@ typedef struct kmp_tasking_flags { /* Total struct must be exactly 32 bits */
|
||||
context of the RTL) */
|
||||
unsigned priority_specified : 1; /* set if the compiler provides priority
|
||||
setting for the task */
|
||||
unsigned reserved : 10; /* reserved for compiler use */
|
||||
unsigned detachable : 1; /* 1 == can detach */
|
||||
unsigned reserved : 9; /* reserved for compiler use */
|
||||
#else
|
||||
unsigned reserved : 12; /* reserved for compiler use */
|
||||
#endif
|
||||
@ -2372,6 +2388,9 @@ struct kmp_taskdata { /* aligned during dynamic allocation */
|
||||
// GOMP sends in a copy function for copy constructors
|
||||
void (*td_copy_func)(void *, void *);
|
||||
#endif
|
||||
#if OMP_50_ENABLED
|
||||
kmp_event_t td_allow_completion_event;
|
||||
#endif
|
||||
#if OMPT_SUPPORT
|
||||
ompt_task_info_t ompt_task_info;
|
||||
#endif
|
||||
@ -3642,6 +3661,14 @@ extern void __kmp_init_implicit_task(ident_t *loc_ref, kmp_info_t *this_thr,
|
||||
int set_curr_task);
|
||||
extern void __kmp_finish_implicit_task(kmp_info_t *this_thr);
|
||||
extern void __kmp_free_implicit_task(kmp_info_t *this_thr);
|
||||
|
||||
#ifdef OMP_50_ENABLED
|
||||
extern kmp_event_t *__kmpc_task_allow_completion_event(ident_t *loc_ref,
|
||||
int gtid,
|
||||
kmp_task_t *task);
|
||||
extern void __kmp_fulfill_event(kmp_event_t *event);
|
||||
#endif
|
||||
|
||||
int __kmp_execute_tasks_32(kmp_info_t *thread, kmp_int32 gtid,
|
||||
kmp_flag_32 *flag, int final_spin,
|
||||
int *thread_finished,
|
||||
|
@ -1387,6 +1387,12 @@ int FTN_STDCALL FTN_GET_SUPPORTED_ACTIVE_LEVELS(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void FTN_STDCALL FTN_FULFILL_EVENT(kmp_event_t *event) {
|
||||
#ifndef KMP_STUB
|
||||
__kmp_fulfill_event(event);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // OMP_50_ENABLED
|
||||
|
||||
// GCC compatibility (versioned symbols)
|
||||
@ -1493,6 +1499,7 @@ KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLACE_NUMS, 45, "OMP_4.5");
|
||||
// KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE, 50, "OMP_5.0");
|
||||
// KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE_ALL, 50, "OMP_5.0");
|
||||
// KMP_VERSION_SYMBOL(FTN_GET_SUPPORTED_ACTIVE_LEVELS, 50, "OMP_5.0");
|
||||
// KMP_VERSION_SYMBOL(FTN_FULFILL_EVENT, 50, "OMP_5.0");
|
||||
#endif
|
||||
|
||||
#endif // KMP_USE_VERSION_SYMBOLS
|
||||
|
@ -144,6 +144,7 @@
|
||||
#define FTN_PAUSE_RESOURCE omp_pause_resource
|
||||
#define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels
|
||||
#define FTN_FULFILL_EVENT omp_fulfill_event
|
||||
#endif
|
||||
|
||||
#endif /* KMP_FTN_PLAIN */
|
||||
@ -278,6 +279,7 @@
|
||||
#define FTN_PAUSE_RESOURCE omp_pause_resource_
|
||||
#define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all_
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels_
|
||||
#define FTN_FULFILL_EVENT omp_fulfill_event_
|
||||
#endif
|
||||
|
||||
#endif /* KMP_FTN_APPEND */
|
||||
@ -410,6 +412,7 @@
|
||||
#define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE
|
||||
#define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS
|
||||
#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT
|
||||
#endif
|
||||
|
||||
#endif /* KMP_FTN_UPPER */
|
||||
@ -544,6 +547,7 @@
|
||||
#define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE_
|
||||
#define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL_
|
||||
#define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS_
|
||||
#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT_
|
||||
#endif
|
||||
|
||||
#endif /* KMP_FTN_UAPPEND */
|
||||
|
@ -874,28 +874,47 @@ static void __kmp_task_finish(kmp_int32 gtid, kmp_task_t *task,
|
||||
}
|
||||
|
||||
KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
|
||||
taskdata->td_flags.complete = 1; // mark the task as completed
|
||||
bool detach = false;
|
||||
#if OMP_50_ENABLED
|
||||
if (taskdata->td_flags.detachable == TASK_DETACHABLE) {
|
||||
if (taskdata->td_allow_completion_event.type ==
|
||||
KMP_EVENT_ALLOW_COMPLETION) {
|
||||
// event hasn't been fulfilled yet. Try to detach task.
|
||||
__kmp_acquire_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
|
||||
if (taskdata->td_allow_completion_event.type ==
|
||||
KMP_EVENT_ALLOW_COMPLETION) {
|
||||
taskdata->td_flags.proxy = TASK_PROXY; // proxify!
|
||||
detach = true;
|
||||
}
|
||||
__kmp_release_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
KMP_DEBUG_ASSERT(taskdata->td_flags.started == 1);
|
||||
KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
|
||||
|
||||
// Only need to keep track of count if team parallel and tasking not
|
||||
// serialized
|
||||
if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
|
||||
// Predecrement simulated by "- 1" calculation
|
||||
children =
|
||||
KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks) - 1;
|
||||
KMP_DEBUG_ASSERT(children >= 0);
|
||||
if (!detach) {
|
||||
taskdata->td_flags.complete = 1; // mark the task as completed
|
||||
|
||||
// Only need to keep track of count if team parallel and tasking not
|
||||
// serialized
|
||||
if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
|
||||
// Predecrement simulated by "- 1" calculation
|
||||
children =
|
||||
KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks) - 1;
|
||||
KMP_DEBUG_ASSERT(children >= 0);
|
||||
#if OMP_40_ENABLED
|
||||
if (taskdata->td_taskgroup)
|
||||
KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
|
||||
__kmp_release_deps(gtid, taskdata);
|
||||
if (taskdata->td_taskgroup)
|
||||
KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
|
||||
__kmp_release_deps(gtid, taskdata);
|
||||
#if OMP_45_ENABLED
|
||||
} else if (task_team && task_team->tt.tt_found_proxy_tasks) {
|
||||
// if we found proxy tasks there could exist a dependency chain
|
||||
// with the proxy task as origin
|
||||
__kmp_release_deps(gtid, taskdata);
|
||||
} else if (task_team && task_team->tt.tt_found_proxy_tasks) {
|
||||
// if we found proxy tasks there could exist a dependency chain
|
||||
// with the proxy task as origin
|
||||
__kmp_release_deps(gtid, taskdata);
|
||||
#endif // OMP_45_ENABLED
|
||||
#endif // OMP_40_ENABLED
|
||||
}
|
||||
}
|
||||
|
||||
// td_flags.executing must be marked as 0 after __kmp_release_deps has been
|
||||
@ -942,7 +961,8 @@ static void __kmp_task_finish(kmp_int32 gtid, kmp_task_t *task,
|
||||
// johnmc: if an asynchronous inquiry peers into the runtime system
|
||||
// it doesn't see the freed task as the current task.
|
||||
thread->th.th_current_task = resumed_task;
|
||||
__kmp_free_task_and_ancestors(gtid, taskdata, thread);
|
||||
if (!detach)
|
||||
__kmp_free_task_and_ancestors(gtid, taskdata, thread);
|
||||
|
||||
// TODO: GEH - make sure root team implicit task is initialized properly.
|
||||
// KMP_DEBUG_ASSERT( resumed_task->td_flags.executing == 0 );
|
||||
@ -1069,6 +1089,9 @@ void __kmp_init_implicit_task(ident_t *loc_ref, kmp_info_t *this_thr,
|
||||
task->td_depnode = NULL;
|
||||
#endif
|
||||
task->td_last_tied = task;
|
||||
#if OMP_50_ENABLED
|
||||
task->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
|
||||
#endif
|
||||
|
||||
if (set_curr_task) { // only do this init first time thread is created
|
||||
KMP_ATOMIC_ST_REL(&task->td_incomplete_child_tasks, 0);
|
||||
@ -1187,11 +1210,19 @@ kmp_task_t *__kmp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
|
||||
KMP_CHECK_UPDATE(thread->th.th_task_team->tt.tt_untied_task_encountered, 1);
|
||||
}
|
||||
|
||||
#if OMP_50_ENABLED
|
||||
// Detachable tasks are not proxy tasks yet but could be in the future. Doing
|
||||
// the tasking setup
|
||||
// when that happens is too late.
|
||||
if (flags->proxy == TASK_PROXY || flags->detachable == TASK_DETACHABLE) {
|
||||
#endif
|
||||
#if OMP_45_ENABLED
|
||||
if (flags->proxy == TASK_PROXY) {
|
||||
flags->tiedness = TASK_UNTIED;
|
||||
flags->merged_if0 = 1;
|
||||
|
||||
if (flags->proxy == TASK_PROXY) {
|
||||
flags->tiedness = TASK_UNTIED;
|
||||
flags->merged_if0 = 1;
|
||||
#if OMP_50_ENABLED
|
||||
}
|
||||
#endif
|
||||
/* are we running in a sequential parallel or tskm_immediate_exec... we need
|
||||
tasking support enabled */
|
||||
if ((thread->th.th_task_team) == NULL) {
|
||||
@ -1295,6 +1326,9 @@ kmp_task_t *__kmp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
|
||||
#endif // OMP_40_ENABLED
|
||||
#if OMP_45_ENABLED
|
||||
taskdata->td_flags.proxy = flags->proxy;
|
||||
#if OMP_50_ENABLED
|
||||
taskdata->td_flags.detachable = flags->detachable;
|
||||
#endif
|
||||
taskdata->td_task_team = thread->th.th_task_team;
|
||||
taskdata->td_size_alloc = shareds_offset + sizeof_shareds;
|
||||
#endif
|
||||
@ -1334,15 +1368,20 @@ kmp_task_t *__kmp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
|
||||
taskdata->td_last_tied = NULL; // will be set when the task is scheduled
|
||||
else
|
||||
taskdata->td_last_tied = taskdata;
|
||||
|
||||
#if OMP_50_ENABLED
|
||||
taskdata->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
|
||||
#endif
|
||||
#if OMPT_SUPPORT
|
||||
if (UNLIKELY(ompt_enabled.enabled))
|
||||
__ompt_task_init(taskdata, gtid);
|
||||
#endif
|
||||
// Only need to keep track of child task counts if team parallel and tasking not
|
||||
// serialized or if it is a proxy task
|
||||
// serialized or if it is a proxy or detachable task
|
||||
#if OMP_45_ENABLED
|
||||
if (flags->proxy == TASK_PROXY ||
|
||||
#if OMP_50_ENABLED
|
||||
flags->detachable == TASK_DETACHABLE ||
|
||||
#endif
|
||||
!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
|
||||
#else
|
||||
if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
|
||||
@ -1378,11 +1417,20 @@ kmp_task_t *__kmpc_omp_task_alloc(ident_t *loc_ref, kmp_int32 gtid,
|
||||
// __kmp_task_alloc() sets up all other runtime flags
|
||||
|
||||
#if OMP_45_ENABLED
|
||||
#if OMP_50_ENABLED
|
||||
KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s %s) "
|
||||
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
|
||||
gtid, loc_ref, input_flags->tiedness ? "tied " : "untied",
|
||||
input_flags->proxy ? "proxy" : "",
|
||||
input_flags->detachable ? "detachable" : "", sizeof_kmp_task_t,
|
||||
sizeof_shareds, task_entry));
|
||||
#else
|
||||
KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
|
||||
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
|
||||
gtid, loc_ref, input_flags->tiedness ? "tied " : "untied",
|
||||
input_flags->proxy ? "proxy" : "", sizeof_kmp_task_t,
|
||||
sizeof_shareds, task_entry));
|
||||
#endif
|
||||
#else
|
||||
KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
|
||||
"sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
|
||||
@ -3914,6 +3962,58 @@ void __kmpc_proxy_task_completed_ooo(kmp_task_t *ptask) {
|
||||
taskdata));
|
||||
}
|
||||
|
||||
#if OMP_50_ENABLED
|
||||
kmp_event_t *__kmpc_task_allow_completion_event(ident_t *loc_ref, int gtid,
|
||||
kmp_task_t *task) {
|
||||
kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
|
||||
if (td->td_allow_completion_event.type == KMP_EVENT_UNINITIALIZED) {
|
||||
td->td_allow_completion_event.type = KMP_EVENT_ALLOW_COMPLETION;
|
||||
td->td_allow_completion_event.ed.task = task;
|
||||
__kmp_init_tas_lock(&td->td_allow_completion_event.lock);
|
||||
}
|
||||
return &td->td_allow_completion_event;
|
||||
}
|
||||
|
||||
void __kmp_fulfill_event(kmp_event_t *event) {
|
||||
if (event->type == KMP_EVENT_ALLOW_COMPLETION) {
|
||||
kmp_task_t *ptask = event->ed.task;
|
||||
kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
|
||||
bool detached = false;
|
||||
int gtid = __kmp_get_gtid();
|
||||
|
||||
if (taskdata->td_flags.proxy == TASK_PROXY) {
|
||||
// The associated task code completed before this call and detached.
|
||||
detached = true;
|
||||
event->type = KMP_EVENT_UNINITIALIZED;
|
||||
} else {
|
||||
// The associated task has not completed but could be completing at this
|
||||
// point.
|
||||
// We need to take the lock to avoid races
|
||||
__kmp_acquire_tas_lock(&event->lock, gtid);
|
||||
if (taskdata->td_flags.proxy == TASK_PROXY)
|
||||
detached = true;
|
||||
event->type = KMP_EVENT_UNINITIALIZED;
|
||||
__kmp_release_tas_lock(&event->lock, gtid);
|
||||
}
|
||||
|
||||
if (detached) {
|
||||
// If the task detached complete the proxy task
|
||||
if (gtid >= 0) {
|
||||
kmp_team_t *team = taskdata->td_team;
|
||||
kmp_info_t *thread = __kmp_get_thread();
|
||||
if (thread->th.th_team == team) {
|
||||
__kmpc_proxy_task_completed(gtid, ptask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// fallback
|
||||
__kmpc_proxy_task_completed_ooo(ptask);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// __kmp_task_dup_alloc: Allocate the taskdata and make a copy of source task
|
||||
// for taskloop
|
||||
//
|
||||
|
113
openmp/runtime/test/tasking/kmp_detach_tasks_t1.c
Normal file
113
openmp/runtime/test/tasking/kmp_detach_tasks_t1.c
Normal file
@ -0,0 +1,113 @@
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
#include "omp_my_sleep.h"
|
||||
|
||||
// detached untied
|
||||
#define PTASK_FLAG_DETACHABLE 0x40
|
||||
|
||||
// OpenMP RTL interfaces
|
||||
typedef unsigned long long kmp_uint64;
|
||||
typedef long long kmp_int64;
|
||||
|
||||
typedef struct ID {
|
||||
int reserved_1;
|
||||
int flags;
|
||||
int reserved_2;
|
||||
int reserved_3;
|
||||
char *psource;
|
||||
} id;
|
||||
|
||||
// Compiler-generated code (emulation)
|
||||
typedef struct ident {
|
||||
void* dummy; // not used in the library
|
||||
} ident_t;
|
||||
|
||||
typedef enum kmp_event_type_t {
|
||||
KMP_EVENT_UNINITIALIZED = 0,
|
||||
KMP_EVENT_ALLOW_COMPLETION = 1
|
||||
} kmp_event_type_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_event_type_t type;
|
||||
union {
|
||||
void *task;
|
||||
} ed;
|
||||
} kmp_event_t;
|
||||
|
||||
typedef struct shar { // shareds used in the task
|
||||
} *pshareds;
|
||||
|
||||
typedef struct task {
|
||||
pshareds shareds;
|
||||
int(*routine)(int,struct task*);
|
||||
int part_id;
|
||||
// void *destructor_thunk; // optional, needs flag setting if provided
|
||||
// int priority; // optional, needs flag setting if provided
|
||||
// ------------------------------
|
||||
// privates used in the task:
|
||||
omp_event_handle_t evt;
|
||||
} *ptask, kmp_task_t;
|
||||
|
||||
typedef int(*task_entry_t)(int, ptask);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int __kmpc_global_thread_num(void *id_ref);
|
||||
extern ptask __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
|
||||
size_t sz, size_t shar, task_entry_t rtn);
|
||||
extern int __kmpc_omp_task(id *loc, int gtid, ptask task);
|
||||
extern omp_event_handle_t __kmpc_task_allow_completion_event(
|
||||
ident_t *loc_ref, int gtid, ptask task);
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int volatile checker;
|
||||
|
||||
// User's code, outlined into task entry
|
||||
int task_entry(int gtid, ptask task) {
|
||||
checker = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i, j, gtid = __kmpc_global_thread_num(NULL);
|
||||
int nt = omp_get_max_threads();
|
||||
ptask task;
|
||||
pshareds psh;
|
||||
checker = 0;
|
||||
omp_set_dynamic(0);
|
||||
#pragma omp parallel //num_threads(N)
|
||||
{
|
||||
#pragma omp master
|
||||
{
|
||||
int gtid = __kmpc_global_thread_num(NULL);
|
||||
omp_event_handle_t evt;
|
||||
/*
|
||||
#pragma omp task detach(evt)
|
||||
{}
|
||||
*/
|
||||
task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,sizeof(struct task),sizeof(struct shar),&task_entry);
|
||||
psh = task->shareds;
|
||||
evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
|
||||
task->evt = evt;
|
||||
|
||||
__kmpc_omp_task(NULL, gtid, task);
|
||||
my_sleep(2.0);
|
||||
omp_fulfill_event(evt);
|
||||
|
||||
} // end master
|
||||
} // end parallel
|
||||
|
||||
// check results
|
||||
if (checker == 1) {
|
||||
printf("passed\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("failed\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
116
openmp/runtime/test/tasking/kmp_detach_tasks_t2.c
Normal file
116
openmp/runtime/test/tasking/kmp_detach_tasks_t2.c
Normal file
@ -0,0 +1,116 @@
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
#include "omp_my_sleep.h"
|
||||
|
||||
// detached tied
|
||||
#define PTASK_FLAG_DETACHABLE 0x41
|
||||
|
||||
// OpenMP RTL interfaces
|
||||
typedef unsigned long long kmp_uint64;
|
||||
typedef long long kmp_int64;
|
||||
|
||||
typedef struct ID {
|
||||
int reserved_1;
|
||||
int flags;
|
||||
int reserved_2;
|
||||
int reserved_3;
|
||||
char *psource;
|
||||
} id;
|
||||
|
||||
// Compiler-generated code (emulation)
|
||||
typedef struct ident {
|
||||
void* dummy; // not used in the library
|
||||
} ident_t;
|
||||
|
||||
typedef enum kmp_event_type_t {
|
||||
KMP_EVENT_UNINITIALIZED = 0,
|
||||
KMP_EVENT_ALLOW_COMPLETION = 1
|
||||
} kmp_event_type_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_event_type_t type;
|
||||
union {
|
||||
void *task;
|
||||
} ed;
|
||||
} kmp_event_t;
|
||||
|
||||
typedef struct shar { // shareds used in the task
|
||||
} *pshareds;
|
||||
|
||||
typedef struct task {
|
||||
pshareds shareds;
|
||||
int(*routine)(int,struct task*);
|
||||
int part_id;
|
||||
// void *destructor_thunk; // optional, needs flag setting if provided
|
||||
// int priority; // optional, needs flag setting if provided
|
||||
// ------------------------------
|
||||
// privates used in the task:
|
||||
omp_event_handle_t evt;
|
||||
} *ptask, kmp_task_t;
|
||||
|
||||
typedef int(* task_entry_t)( int, ptask );
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int __kmpc_global_thread_num(void *id_ref);
|
||||
extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
|
||||
size_t sz, size_t shar, task_entry_t rtn);
|
||||
extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
|
||||
extern omp_event_handle_t __kmpc_task_allow_completion_event(
|
||||
ident_t *loc_ref, int gtid, kmp_task_t *task);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int volatile checker;
|
||||
|
||||
// User's code, outlined into task entry
|
||||
int task_entry(int gtid, ptask task) {
|
||||
my_sleep(2.0);
|
||||
checker = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i, j, gtid = __kmpc_global_thread_num(NULL);
|
||||
int nt = omp_get_max_threads();
|
||||
ptask task;
|
||||
pshareds psh;
|
||||
checker = 0;
|
||||
omp_set_dynamic(0);
|
||||
#pragma omp parallel //num_threads(N)
|
||||
{
|
||||
#pragma omp master
|
||||
{
|
||||
int gtid = __kmpc_global_thread_num(NULL);
|
||||
omp_event_handle_t evt;
|
||||
/*
|
||||
#pragma omp task detach(evt)
|
||||
{}
|
||||
*/
|
||||
task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
|
||||
sizeof(struct task),sizeof(struct shar),&task_entry);
|
||||
psh = task->shareds;
|
||||
evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
|
||||
task->evt = evt;
|
||||
__kmpc_omp_task(NULL, gtid, task);
|
||||
omp_fulfill_event(evt);
|
||||
#pragma omp taskwait
|
||||
;
|
||||
// printf("after tw %d\n", omp_get_thread_num());
|
||||
} // end master
|
||||
} // end parallel
|
||||
|
||||
// check results
|
||||
if (checker == 1) {
|
||||
printf("passed\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("failed\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
138
openmp/runtime/test/tasking/kmp_detach_tasks_t3.c
Normal file
138
openmp/runtime/test/tasking/kmp_detach_tasks_t3.c
Normal file
@ -0,0 +1,138 @@
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
|
||||
// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
|
||||
// The runtime currently does not get dependency information from GCC.
|
||||
// UNSUPPORTED: gcc
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
#include "omp_my_sleep.h"
|
||||
|
||||
// detached untied
|
||||
#define PTASK_FLAG_DETACHABLE 0x40
|
||||
|
||||
// OpenMP RTL interfaces
|
||||
typedef unsigned long long kmp_uint64;
|
||||
typedef long long kmp_int64;
|
||||
|
||||
typedef struct ID {
|
||||
int reserved_1;
|
||||
int flags;
|
||||
int reserved_2;
|
||||
int reserved_3;
|
||||
char *psource;
|
||||
} id;
|
||||
|
||||
// Compiler-generated code (emulation)
|
||||
typedef struct ident {
|
||||
void* dummy; // not used in the library
|
||||
} ident_t;
|
||||
|
||||
typedef enum kmp_event_type_t {
|
||||
KMP_EVENT_UNINITIALIZED = 0,
|
||||
KMP_EVENT_ALLOW_COMPLETION = 1
|
||||
} kmp_event_type_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_event_type_t type;
|
||||
union {
|
||||
void *task;
|
||||
} ed;
|
||||
} kmp_event_t;
|
||||
|
||||
typedef struct shar { // shareds used in the task
|
||||
} *pshareds;
|
||||
|
||||
typedef struct task {
|
||||
pshareds shareds;
|
||||
int(*routine)(int,struct task*);
|
||||
int part_id;
|
||||
// void *destructor_thunk; // optional, needs flag setting if provided
|
||||
// int priority; // optional, needs flag setting if provided
|
||||
// ------------------------------
|
||||
// privates used in the task:
|
||||
omp_event_handle_t evt;
|
||||
} *ptask, kmp_task_t;
|
||||
|
||||
typedef struct DEP {
|
||||
size_t addr;
|
||||
size_t len;
|
||||
int flags;
|
||||
} dep;
|
||||
|
||||
typedef int(* task_entry_t)( int, ptask );
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern int __kmpc_global_thread_num(void *id_ref);
|
||||
extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
|
||||
size_t sz, size_t shar, task_entry_t rtn);
|
||||
extern int __kmpc_omp_task_with_deps(id *loc, int gtid, ptask task, int nd,
|
||||
dep *dep_lst, int nd_noalias, dep *noalias_dep_lst);
|
||||
extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
|
||||
extern omp_event_handle_t __kmpc_task_allow_completion_event(
|
||||
ident_t *loc_ref, int gtid, kmp_task_t *task);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int volatile checker;
|
||||
|
||||
// User's code, outlined into task entry
|
||||
int task_entry(int gtid, ptask task) {
|
||||
checker = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i, j, gtid = __kmpc_global_thread_num(NULL);
|
||||
int nt = omp_get_max_threads();
|
||||
ptask task;
|
||||
pshareds psh;
|
||||
checker = 0;
|
||||
omp_set_dynamic(0);
|
||||
#pragma omp parallel //num_threads(N)
|
||||
{
|
||||
#pragma omp master
|
||||
{
|
||||
#pragma omp task depend(inout:nt)
|
||||
{
|
||||
my_sleep(2.0);
|
||||
}
|
||||
int gtid = __kmpc_global_thread_num(NULL);
|
||||
omp_event_handle_t evt;
|
||||
/*
|
||||
#pragma omp task detach(evt)
|
||||
{}
|
||||
*/
|
||||
task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
|
||||
sizeof(struct task),sizeof(struct shar),&task_entry);
|
||||
psh = task->shareds;
|
||||
evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
|
||||
task->evt = evt;
|
||||
|
||||
dep sdep;
|
||||
sdep.addr = (size_t)&nt;
|
||||
sdep.len = 0L;
|
||||
sdep.flags = 3;
|
||||
|
||||
__kmpc_omp_task_with_deps(NULL,gtid,task,1,&sdep,0,0);
|
||||
//__kmpc_omp_task(NULL, gtid, task);
|
||||
|
||||
omp_fulfill_event(evt);
|
||||
|
||||
#pragma omp taskwait
|
||||
;
|
||||
// printf("after tw %d\n", omp_get_thread_num());
|
||||
} // end master
|
||||
} // end parallel
|
||||
|
||||
// check results
|
||||
if (checker == 1) {
|
||||
printf("passed\n");
|
||||
return 0;
|
||||
} else {
|
||||
printf("failed\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user