From b226afb63068bf74b2b396472b0f50b86111f5ee Mon Sep 17 00:00:00 2001 From: David Alvarez Date: Fri, 1 Jul 2022 17:54:18 +0200 Subject: [PATCH] Implement Nanos6 emulator model --- CMakeLists.txt | 2 + cfg/active-pid-and-tasks.cfg | 6 +- cfg/active-pid.cfg | 2 +- cfg/active-task-id.cfg | 2 +- cfg/active-task-type-id.cfg | 2 +- cfg/all.cfg | 14 +- cfg/cpu-flushing.cfg | 2 +- cfg/cpu-kernel-context-switch.cfg | 2 +- cfg/cpu-nodes-subsystem.cfg | 2 +- cfg/cpu-nosv-task-rank.cfg | 2 +- cfg/cpu-openmp-mode.cfg | 2 +- cfg/cpu-tampi-mode.cfg | 2 +- cfg/cpu.cfg | 14 +- cfg/thread-flushing.cfg | 2 +- cfg/thread-kernel-context-switch.cfg | 2 +- cfg/thread-nodes-subsystem.cfg | 2 +- cfg/thread-nosv-task-rank.cfg | 2 +- cfg/thread-openmp-mode.cfg | 2 +- cfg/thread-tampi-mode.cfg | 2 +- cfg/thread.cfg | 8 +- chan.c | 4 +- emu.c | 7 +- emu.h | 120 +++++--- emu_nanos6.c | 440 +++++++++++++++++++++++++++ emu_nosv.c | 322 +++----------------- emu_task.c | 263 ++++++++++++++++ emu_task.h | 32 ++ pcf.c | 42 ++- 28 files changed, 944 insertions(+), 360 deletions(-) create mode 100644 emu_nanos6.c create mode 100644 emu_task.c create mode 100644 emu_task.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 64a4c25..e37bdad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,6 +76,8 @@ add_executable(ovniemu emu_tampi.c emu_nodes.c emu_kernel.c + emu_nanos6.c + emu_task.c trace.c ovni.c parson.c diff --git a/cfg/active-pid-and-tasks.cfg b/cfg/active-pid-and-tasks.cfg index a1bc076..d10f56a 100644 --- a/cfg/active-pid-and-tasks.cfg +++ b/cfg/active-pid-and-tasks.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 10 +window_filter_module evt_type 1 1 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -77,7 +77,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 20 +window_filter_module evt_type 1 10 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -116,7 +116,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 21 +window_filter_module evt_type 1 11 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/active-pid.cfg b/cfg/active-pid.cfg index d646acb..bbfcd08 100644 --- a/cfg/active-pid.cfg +++ b/cfg/active-pid.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 400 +window_filter_module evt_type 1 1 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/active-task-id.cfg b/cfg/active-task-id.cfg index 9f6551a..d5ef89f 100644 --- a/cfg/active-task-id.cfg +++ b/cfg/active-task-id.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 200 +window_filter_module evt_type 1 10 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/active-task-type-id.cfg b/cfg/active-task-type-id.cfg index 2564746..f6d94b9 100644 --- a/cfg/active-task-type-id.cfg +++ b/cfg/active-task-type-id.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 300 +window_filter_module evt_type 1 11 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/all.cfg b/cfg/all.cfg index 5961ab7..601a846 100644 --- a/cfg/all.cfg +++ b/cfg/all.cfg @@ -39,7 +39,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 10 +window_filter_module evt_type 1 1 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -79,7 +79,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 20 +window_filter_module evt_type 1 10 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -120,7 +120,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 21 +window_filter_module evt_type 1 11 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -161,7 +161,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 12 +window_filter_module evt_type 1 3 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -199,7 +199,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 60 +window_filter_module evt_type 1 4 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -237,7 +237,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 61 +window_filter_module evt_type 1 2 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 @@ -277,7 +277,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 11 +window_filter_module evt_type 1 2 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/cpu-flushing.cfg b/cfg/cpu-flushing.cfg index a1556f3..2864979 100644 --- a/cfg/cpu-flushing.cfg +++ b/cfg/cpu-flushing.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 66 +window_filter_module evt_type 1 7 window_filter_module evt_type_label 1 "CPU: Flusing state of the RUNNING thread" window_synchronize 1 diff --git a/cfg/cpu-kernel-context-switch.cfg b/cfg/cpu-kernel-context-switch.cfg index caedc9a..ce0f025 100644 --- a/cfg/cpu-kernel-context-switch.cfg +++ b/cfg/cpu-kernel-context-switch.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 105 +window_filter_module evt_type 1 40 window_filter_module evt_type_label 1 "CPU: Context switches of the ACTIVE thread" window_synchronize 1 diff --git a/cfg/cpu-nodes-subsystem.cfg b/cfg/cpu-nodes-subsystem.cfg index e808e0c..4290d42 100644 --- a/cfg/cpu-nodes-subsystem.cfg +++ b/cfg/cpu-nodes-subsystem.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 100 +window_filter_module evt_type 1 30 window_filter_module evt_type_label 1 "CPU: NODES running thread subsystem" window_synchronize 1 diff --git a/cfg/cpu-nosv-task-rank.cfg b/cfg/cpu-nosv-task-rank.cfg index 202751f..6c8b46e 100644 --- a/cfg/cpu-nosv-task-rank.cfg +++ b/cfg/cpu-nosv-task-rank.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 74 +window_filter_module evt_type 1 14 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/cpu-openmp-mode.cfg b/cfg/cpu-openmp-mode.cfg index 984a52d..eb53681 100644 --- a/cfg/cpu-openmp-mode.cfg +++ b/cfg/cpu-openmp-mode.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 90 +window_filter_module evt_type 1 25 window_filter_module evt_type_label 1 "CPU: OpenMP running thread mode" window_synchronize 1 diff --git a/cfg/cpu-tampi-mode.cfg b/cfg/cpu-tampi-mode.cfg index 9d1664e..9f6baf3 100644 --- a/cfg/cpu-tampi-mode.cfg +++ b/cfg/cpu-tampi-mode.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 80 +window_filter_module evt_type 1 20 window_filter_module evt_type_label 1 "CPU: TAMPI running thread mode" window_synchronize 1 diff --git a/cfg/cpu.cfg b/cfg/cpu.cfg index a0c875b..45e6360 100644 --- a/cfg/cpu.cfg +++ b/cfg/cpu.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 60 +window_filter_module evt_type 1 1 window_filter_module evt_type_label 1 "CPU: PID of the RUNNING thread" window_synchronize 1 @@ -75,7 +75,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 70 +window_filter_module evt_type 1 8 window_filter_module evt_type_label 1 "CPU: nOS-V TaskID of the RUNNING thread" window_synchronize 1 @@ -113,7 +113,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 71 +window_filter_module evt_type 1 11 window_filter_module evt_type_label 1 "CPU: nOS-V task type of the RUNNING thread" window_synchronize 1 @@ -152,7 +152,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 62 +window_filter_module evt_type 1 3 window_filter_module evt_type_label 1 "CPU: Number of RUNNING threads" window_synchronize 1 @@ -190,7 +190,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 61 +window_filter_module evt_type 1 2 window_filter_module evt_type_label 1 "CPU: TID of the RUNNING thread" window_synchronize 1 @@ -229,7 +229,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 72 +window_filter_module evt_type 1 12 window_filter_module evt_type_label 1 "CPU: nOS-V task AppID of the RUNNING thread" window_synchronize 1 @@ -267,7 +267,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 73 +window_filter_module evt_type 1 13 window_filter_module evt_type_label 1 "CPU: nOS-V subsystem of the RUNNING thread" window_synchronize 1 diff --git a/cfg/thread-flushing.cfg b/cfg/thread-flushing.cfg index eb01334..6e01d19 100644 --- a/cfg/thread-flushing.cfg +++ b/cfg/thread-flushing.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 16 +window_filter_module evt_type 1 7 window_filter_module evt_type_label 1 "Thread: Flushing state of the CURRENT thread" window_synchronize 1 diff --git a/cfg/thread-kernel-context-switch.cfg b/cfg/thread-kernel-context-switch.cfg index 1705146..6f521c1 100644 --- a/cfg/thread-kernel-context-switch.cfg +++ b/cfg/thread-kernel-context-switch.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 55 +window_filter_module evt_type 1 40 window_filter_module evt_type_label 1 "Thread: Context switches of the CURRENT thread" window_synchronize 1 diff --git a/cfg/thread-nodes-subsystem.cfg b/cfg/thread-nodes-subsystem.cfg index 9a0e091..b263199 100644 --- a/cfg/thread-nodes-subsystem.cfg +++ b/cfg/thread-nodes-subsystem.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 50 +window_filter_module evt_type 1 30 window_filter_module evt_type_label 1 "Thread: NODES subsystem" window_synchronize 1 diff --git a/cfg/thread-nosv-task-rank.cfg b/cfg/thread-nosv-task-rank.cfg index 49fea33..37f66ef 100644 --- a/cfg/thread-nosv-task-rank.cfg +++ b/cfg/thread-nosv-task-rank.cfg @@ -38,7 +38,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 24 +window_filter_module evt_type 1 14 window_filter_module evt_type_label 1 "Unknown" window_synchronize 1 diff --git a/cfg/thread-openmp-mode.cfg b/cfg/thread-openmp-mode.cfg index 44ad8a3..d3ff087 100644 --- a/cfg/thread-openmp-mode.cfg +++ b/cfg/thread-openmp-mode.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 40 +window_filter_module evt_type 1 25 window_filter_module evt_type_label 1 "Thread: OpenMP mode" window_synchronize 1 diff --git a/cfg/thread-tampi-mode.cfg b/cfg/thread-tampi-mode.cfg index 75942a6..62a8fae 100644 --- a/cfg/thread-tampi-mode.cfg +++ b/cfg/thread-tampi-mode.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 30 +window_filter_module evt_type 1 20 window_filter_module evt_type_label 1 "Thread: TAMPI mode" window_synchronize 1 diff --git a/cfg/thread.cfg b/cfg/thread.cfg index 82fafcf..c628733 100644 --- a/cfg/thread.cfg +++ b/cfg/thread.cfg @@ -37,7 +37,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 13 +window_filter_module evt_type 1 4 window_filter_module evt_type_label 1 "Thread: State of the CURRENT thread" window_synchronize 1 @@ -75,7 +75,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 11 +window_filter_module evt_type 1 2 window_filter_module evt_type_label 1 "Thread: TID of the RUNNING thread" window_synchronize 1 @@ -113,7 +113,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 23 +window_filter_module evt_type 1 13 window_filter_module evt_type_label 1 "Thread: nOS-V subsystem of the ACTIVE thread" window_synchronize 1 @@ -151,7 +151,7 @@ window_pixel_size 1 window_labels_to_draw 1 window_selected_functions { 14, { {cpu, Active Thd}, {appl, Adding}, {task, Adding}, {thread, Last Evt Val}, {node, Adding}, {system, Adding}, {workload, Adding}, {from_obj, All}, {to_obj, All}, {tag_msg, All}, {size_msg, All}, {bw_msg, All}, {evt_type, =}, {evt_value, All} } } window_compose_functions { 9, { {compose_cpu, As Is}, {compose_appl, As Is}, {compose_task, As Is}, {compose_thread, As Is}, {compose_node, As Is}, {compose_system, As Is}, {compose_workload, As Is}, {topcompose1, As Is}, {topcompose2, As Is} } } -window_filter_module evt_type 1 15 +window_filter_module evt_type 1 6 window_filter_module evt_type_label 1 "Thread: CPU affinity of the CURRENT thread" window_synchronize 1 diff --git a/chan.c b/chan.c index 3eeb9e1..b7c05d6 100644 --- a/chan.c +++ b/chan.c @@ -68,7 +68,7 @@ chan_th_init(struct ovni_ethread *th, int prvth; chan = &th->chan[id]; - prvth = CHAN_PRV_TH(id); + prvth = chan_to_prvtype[id]; chan_init(chan, track, row, prvth, prv, clock); @@ -97,7 +97,7 @@ chan_cpu_init(struct ovni_cpu *cpu, int prvcpu; chan = &cpu->chan[id]; - prvcpu = CHAN_PRV_CPU(id); + prvcpu = chan_to_prvtype[id]; chan_init(chan, track, row, prvcpu, prv, clock); diff --git a/emu.c b/emu.c index 0868998..2ddee3c 100644 --- a/emu.c +++ b/emu.c @@ -266,12 +266,14 @@ hook_init(struct ovni_emu *emu) hook_init_openmp(emu); hook_init_nodes(emu); hook_init_kernel(emu); + hook_init_nanos6(emu); } static void hook_end(struct ovni_emu *emu) { hook_end_nosv(emu); + hook_end_nanos6(emu); } static void @@ -285,6 +287,7 @@ hook_pre(struct ovni_emu *emu) case 'M': hook_pre_openmp(emu); break; case 'D': hook_pre_nodes(emu); break; case 'K': hook_pre_kernel(emu); break; + case '6': hook_pre_nanos6(emu); break; default: break; } @@ -1095,10 +1098,10 @@ create_pcf_cpus(struct ovni_emu *emu) { /* Only needed for the thread PCF */ struct pcf_file *pcf = &emu->pcf[CHAN_TH]; - int prvtype = CHAN_PRV_TH(CHAN_OVNI_CPU); + int prvtype = chan_to_prvtype[CHAN_OVNI_CPU]; struct pcf_type *type = pcf_find_type(pcf, prvtype); - if (type == NULL) + if(type == NULL) die("cannot find PCF type for CHAN_OVNI_CPU\n"); for(size_t i=0; itotal_ncpus; i++) diff --git a/emu.h b/emu.h index cd15917..296f373 100644 --- a/emu.h +++ b/emu.h @@ -37,7 +37,7 @@ enum ethread_state { TH_ST_WARMING, }; -enum nosv_task_state { +enum task_state { TASK_ST_CREATED, TASK_ST_RUNNING, TASK_ST_PAUSED, @@ -100,6 +100,46 @@ enum nodes_state { ST_NODES_SPAWN = 8, }; +/* The values of nanos6_ss_state are synced to the previous + * CTF implementation. */ +enum nanos6_ss_state { + ST_NANOS6_NULL = 0, /* IDLE */ + /* RUNTIME */ + ST_NANOS6_SCHED_HUNGRY = 2, /* BUSY_WAIT */ + ST_NANOS6_TASK_RUNNING = 3, /* TASK */ + ST_NANOS6_DEP_REG = 4, /* DEPENDENCY_REGISTER */ + ST_NANOS6_DEP_UNREG = 5, /* DEPENDENCY_UNREGISTER */ + ST_NANOS6_SCHED_SUBMITTING = 6, /* SCHEDULER_ADD_TASK */ + /* SCHEDULER_GET_TASK */ + ST_NANOS6_CREATING = 8, /* TASK_CREATE */ + /* TASK_ARGS_INIT */ + ST_NANOS6_SUBMIT = 10, /* TASK_SUBMIT */ + /* TASKFOR_INIT */ + ST_NANOS6_TASKWAIT = 12, /* TASK_WAIT */ + ST_NANOS6_WAITFOR = 13, /* WAIT_FOR */ + /* LOCK */ + /* UNLOCK */ + ST_NANOS6_BLOCKING = 16, /* BLOCKING_API_BLOCK */ + ST_NANOS6_UNBLOCKING = 17, /* BLOCKING_API_UNBLOCK */ + ST_NANOS6_SPAWNING = 18, /* SPAWN_FUNCTION */ + /* SCHEDULER_LOCK_ENTER */ + ST_NANOS6_SCHED_SERVING = 20, /* SCHEDULER_LOCK_SERVING */ + ST_NANOS6_ATTACHED, + + EV_NANOS6_SCHED_RECV, + EV_NANOS6_SCHED_SEND, + EV_NANOS6_SCHED_SELF, +}; + +/* Possible reasons for Nanos6 tasks becoming running or not running */ +enum nanos6_task_run_reason +{ + TB_EXEC_OR_END = -1, + TB_BLOCKING_API = 0, + TB_TASKWAIT = 1, + TB_WAITFOR = 2 +}; + enum kernel_cs_state { ST_KERNEL_CSOUT = 3, }; @@ -107,26 +147,26 @@ enum kernel_cs_state { struct ovni_ethread; struct ovni_eproc; -struct nosv_task_type { - uint32_t id; /* Per-process identifier, same as nOS-V */ +struct task_type { + uint32_t id; /* Per-process task identifier */ uint32_t gid; /* Global identifier computed from the label */ char label[MAX_PCF_LABEL]; UT_hash_handle hh; }; -struct nosv_task { +struct task { uint32_t id; - struct nosv_task_type *type; + struct task_type *type; /* The thread that has began to execute the task. It cannot * change after being set, even if the task ends. */ struct ovni_ethread *thread; - enum nosv_task_state state; + enum task_state state; UT_hash_handle hh; /* List handle for nested task support */ - struct nosv_task *next; - struct nosv_task *prev; + struct task *next; + struct task *prev; }; #define MAX_CHAN_STACK 128 @@ -163,6 +203,11 @@ enum chan { CHAN_OPENMP_MODE, CHAN_NODES_SUBSYSTEM, + CHAN_NANOS6_TASKID, + CHAN_NANOS6_TYPE, + CHAN_NANOS6_SUBSYSTEM, + CHAN_NANOS6_RANK, + CHAN_KERNEL_CS, CHAN_MAX @@ -184,30 +229,29 @@ enum chan_dirty { CHAN_DIRTY_VALUE = 2, }; -static const int chan_to_prvtype[CHAN_MAX][CHAN_MAXTYPE] = { - /* FIXME: Use odd/even identifiers for thread and cpu */ - /* Channel TH CPU */ - [CHAN_OVNI_PID] = { 10, 60 }, - [CHAN_OVNI_TID] = { 11, 61 }, - [CHAN_OVNI_NRTHREADS] = { -1, 62 }, - [CHAN_OVNI_STATE] = { 13, -1 }, - [CHAN_OVNI_APPID] = { 14, 64 }, /* Not used */ - [CHAN_OVNI_CPU] = { 15, -1 }, - [CHAN_OVNI_FLUSH] = { 16, 66 }, - [CHAN_NOSV_TASKID] = { 20, 70 }, - [CHAN_NOSV_TYPE] = { 21, 71 }, - [CHAN_NOSV_APPID] = { 22, 72 }, - [CHAN_NOSV_SUBSYSTEM] = { 23, 73 }, - [CHAN_NOSV_RANK] = { 24, 74 }, - [CHAN_TAMPI_MODE] = { 30, 80 }, - [CHAN_OPENMP_MODE] = { 40, 90 }, - [CHAN_NODES_SUBSYSTEM] = { 50, 100 }, - [CHAN_KERNEL_CS] = { 55, 105 }, +static const int chan_to_prvtype[CHAN_MAX] = { + [CHAN_OVNI_PID] = 1, + [CHAN_OVNI_TID] = 2, + [CHAN_OVNI_NRTHREADS] = 3, + [CHAN_OVNI_STATE] = 4, + [CHAN_OVNI_APPID] = 5, /* Not used */ + [CHAN_OVNI_CPU] = 6, + [CHAN_OVNI_FLUSH] = 7, + [CHAN_NOSV_TASKID] = 10, + [CHAN_NOSV_TYPE] = 11, + [CHAN_NOSV_APPID] = 12, + [CHAN_NOSV_SUBSYSTEM] = 13, + [CHAN_NOSV_RANK] = 14, + [CHAN_TAMPI_MODE] = 20, + [CHAN_OPENMP_MODE] = 25, + [CHAN_NODES_SUBSYSTEM] = 30, + [CHAN_NANOS6_TASKID] = 35, + [CHAN_NANOS6_TYPE] = 36, + [CHAN_NANOS6_SUBSYSTEM] = 37, + [CHAN_NANOS6_RANK] = 38, + [CHAN_KERNEL_CS] = 40, }; -#define CHAN_PRV_TH(id) chan_to_prvtype[id][CHAN_TH] -#define CHAN_PRV_CPU(id) chan_to_prvtype[id][CHAN_CPU] - struct ovni_chan { /* Channel id */ enum chan id; @@ -290,8 +334,9 @@ struct ovni_ethread { /* FIXME: Use a table with registrable pointers to custom data * structures */ - /* nOS-V stack of tasks: points to the runnable task. */ - struct nosv_task *task_stack; + /* Task stacks, top ones are the tasks currently runnable. */ + struct task *nosv_task_stack; + struct task *nanos6_task_stack; /* Channels are used to output the emulator state in PRV */ struct ovni_chan chan[CHAN_MAX]; @@ -331,8 +376,11 @@ struct ovni_eproc { /* ------ Subsystem specific data --------*/ /* TODO: Use dynamic allocation */ - struct nosv_task_type *types; - struct nosv_task *tasks; + struct task_type *nosv_types; + struct task *nosv_tasks; + + struct task_type *nanos6_types; + struct task *nanos6_tasks; }; @@ -512,6 +560,10 @@ void hook_pre_nodes(struct ovni_emu *emu); void hook_init_kernel(struct ovni_emu *emu); void hook_pre_kernel(struct ovni_emu *emu); +void hook_init_nanos6(struct ovni_emu *emu); +void hook_pre_nanos6(struct ovni_emu *emu); +void hook_end_nanos6(struct ovni_emu *emu); + struct ovni_cpu *emu_get_cpu(struct ovni_loom *loom, int cpuid); struct ovni_ethread *emu_get_thread(struct ovni_eproc *proc, int tid); diff --git a/emu_nanos6.c b/emu_nanos6.c new file mode 100644 index 0000000..25b55de --- /dev/null +++ b/emu_nanos6.c @@ -0,0 +1,440 @@ +/* + * Copyright (c) 2022 Barcelona Supercomputing Center (BSC) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "uthash.h" +#include "utlist.h" + +#include "ovni.h" +#include "emu.h" +#include "emu_task.h" +#include "prv.h" +#include "chan.h" + +void +hook_init_nanos6(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_cpu *cpu; + struct ovni_chan **uth, **ucpu; + size_t i; + int row; + FILE *prv_th, *prv_cpu; + int64_t *clock; + + clock = &emu->delta_time; + prv_th = emu->prv_thread; + prv_cpu = emu->prv_cpu; + + /* Init the channels in all threads */ + for(i=0; itotal_nthreads; i++) + { + th = emu->global_thread[i]; + row = th->gindex + 1; + + uth = &emu->th_chan; + + chan_th_init(th, uth, CHAN_NANOS6_TASKID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); + chan_th_init(th, uth, CHAN_NANOS6_TYPE, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); + chan_th_init(th, uth, CHAN_NANOS6_SUBSYSTEM, CHAN_TRACK_TH_ACTIVE, 0, 0, 1, row, prv_th, clock); + chan_th_init(th, uth, CHAN_NANOS6_RANK, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); + } + + /* Init the Nanos6 channels in all cpus */ + for(i=0; itotal_ncpus; i++) + { + cpu = emu->global_cpu[i]; + row = cpu->gindex + 1; + ucpu = &emu->cpu_chan; + + chan_cpu_init(cpu, ucpu, CHAN_NANOS6_TASKID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); + chan_cpu_init(cpu, ucpu, CHAN_NANOS6_TYPE, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); + chan_cpu_init(cpu, ucpu, CHAN_NANOS6_SUBSYSTEM, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); + chan_cpu_init(cpu, ucpu, CHAN_NANOS6_RANK, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); + } +} + +/* --------------------------- pre ------------------------------- */ + +static void +task_not_running(struct ovni_emu *emu, struct task *task, enum nanos6_task_run_reason reason) +{ + struct ovni_ethread *th; + th = emu->cur_thread; + + if(task->state == TASK_ST_RUNNING) + die("task is still running\n"); + + chan_set(&th->chan[CHAN_NANOS6_TASKID], 0); + chan_set(&th->chan[CHAN_NANOS6_TYPE], 0); + + if(emu->cur_loom->rank_enabled) + chan_set(&th->chan[CHAN_NANOS6_RANK], 0); + + // Check the reason + switch (reason) + { + case TB_EXEC_OR_END: + chan_pop(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASK_RUNNING); + break; + case TB_BLOCKING_API: + chan_push(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_BLOCKING); + break; + case TB_TASKWAIT: + chan_push(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASKWAIT); + break; + case TB_WAITFOR: + chan_push(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_WAITFOR); + break; + } +} + +static void +task_running(struct ovni_emu *emu, struct task *task, enum nanos6_task_run_reason reason) +{ + struct ovni_ethread *th; + struct ovni_eproc *proc; + + th = emu->cur_thread; + proc = emu->cur_proc; + + if(task->id == 0) + die("task id cannot be 0\n"); + + if(task->type->gid == 0) + die("task type gid cannot be 0\n"); + + if(proc->appid <= 0) + die("app id must be positive\n"); + + chan_set(&th->chan[CHAN_NANOS6_TASKID], task->id); + chan_set(&th->chan[CHAN_NANOS6_TYPE], task->type->gid); + + if(emu->cur_loom->rank_enabled) + chan_set(&th->chan[CHAN_NANOS6_RANK], proc->rank + 1); + + // Check the reason + switch (reason) + { + case TB_EXEC_OR_END: + chan_push(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASK_RUNNING); + break; + case TB_BLOCKING_API: + chan_pop(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_BLOCKING); + break; + case TB_TASKWAIT: + chan_pop(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_TASKWAIT); + break; + case TB_WAITFOR: + chan_pop(&th->chan[CHAN_NANOS6_SUBSYSTEM], ST_NANOS6_WAITFOR); + break; + } +} + +static void +task_switch(struct ovni_emu *emu, struct task *prev_task, + struct task *next_task, int newtask) +{ + struct ovni_ethread *th; + + th = emu->cur_thread; + + if(!prev_task || !next_task) + die("cannot switch to or from a NULL task\n"); + + if(prev_task == next_task) + die("cannot switch to the same task\n"); + + if(newtask && prev_task->state != TASK_ST_RUNNING) + die("previous task must not be no longer running\n"); + + if(!newtask && prev_task->state != TASK_ST_DEAD) + die("previous task must be dead\n"); + + if(next_task->state != TASK_ST_RUNNING) + die("next task must be running\n"); + + if(next_task->id == 0) + die("next task id cannot be 0\n"); + + if(next_task->type->gid == 0) + die("next task type id cannot be 0\n"); + + if(prev_task->thread != next_task->thread) + die("cannot switch to a task of another thread\n"); + + /* No need to change the rank as we will switch to tasks from same stack */ + chan_set(&th->chan[CHAN_NANOS6_TASKID], next_task->id); + + /* FIXME: We should emit a PRV event even if we are switching to + * the same type event, to mark the end of the current task. For + * now we only emit a new type if we switch to a type with a + * different gid. */ + if(prev_task->type->gid != next_task->type->gid) + chan_set(&th->chan[CHAN_NANOS6_TYPE], next_task->type->gid); +} + +static void +pre_task(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + struct task **task_map = &emu->cur_proc->nanos6_tasks; + struct task_type **type_map = &emu->cur_proc->nanos6_types; + struct task **task_stack = &emu->cur_thread->nanos6_task_stack; + struct task *prev_running = task_get_running(*task_stack); + int was_running_task = (prev_running != NULL); + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + /* Update the emulator state, but don't modify the channels yet */ + switch(emu->cur_ev->header.value) + { + case 'c': task_create(emu->cur_ev->payload.i32[0], emu->cur_ev->payload.i32[1], task_map, type_map); break; + case 'x': task_execute(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'e': task_end(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'b': task_pause(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'u': task_resume(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'C': break; + default: + abort(); + } + + struct task *next_running = task_get_running(*task_stack); + int runs_task_now = (next_running != NULL); + + /* Now that we know if the emulator was running a task before + * or if it's running one now, update the channels accordingly. */ + switch(emu->cur_ev->header.value) + { + case 'x': /* Execute: either a nested task or a new one */ + if(was_running_task) + task_switch(emu, prev_running, next_running, 1); + else + task_running(emu, next_running, TB_EXEC_OR_END); + break; + case 'e': /* End: either a nested task or the last one */ + if(runs_task_now) + task_switch(emu, prev_running, next_running, 0); + else + task_not_running(emu, prev_running, TB_EXEC_OR_END); + break; + case 'b': /* Block */ + task_not_running(emu, prev_running, emu->cur_ev->payload.i32[1]); + break; + case 'u': /* Unblock */ + task_running(emu, next_running, emu->cur_ev->payload.i32[1]); + break; + case 'c': /* Create */ + chan_push(chan_th, ST_NANOS6_CREATING); + break; + case 'C': /* Create end */ + chan_pop(chan_th, ST_NANOS6_CREATING); + break; + default: + break; + } +} + +static void +pre_type(struct ovni_emu *emu) +{ + uint8_t *data; + + switch(emu->cur_ev->header.value) + { + case 'c': + if((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) + { + err("expecting a jumbo event\n"); + abort(); + } + + data = &emu->cur_ev->payload.jumbo.data[0]; + uint32_t *typeid = (uint32_t *) data; + data += sizeof(*typeid); + const char *label = (const char *) data; + task_type_create(*typeid, label, &emu->cur_proc->nanos6_types); + break; + default: + break; + } +} + +static void +pre_deps(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + switch(emu->cur_ev->header.value) + { + case 'r': chan_push(chan_th, ST_NANOS6_DEP_REG); break; + case 'R': chan_pop(chan_th, ST_NANOS6_DEP_REG); break; + case 'u': chan_push(chan_th, ST_NANOS6_DEP_UNREG); break; + case 'U': chan_pop(chan_th, ST_NANOS6_DEP_UNREG); break; + default: break; + } +} + +static void +pre_blocking(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + switch(emu->cur_ev->header.value) + { + case 'u': chan_push(chan_th, ST_NANOS6_UNBLOCKING); break; + case 'U': chan_pop(chan_th, ST_NANOS6_UNBLOCKING); break; + default: break; + } +} + +static void +pre_sched(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + switch(emu->cur_ev->header.value) + { + case 'h': chan_push(chan_th, ST_NANOS6_SCHED_HUNGRY); break; + case 'f': chan_pop(chan_th, ST_NANOS6_SCHED_HUNGRY); break; + case '[': chan_push(chan_th, ST_NANOS6_SCHED_SERVING); break; + case ']': chan_pop(chan_th, ST_NANOS6_SCHED_SERVING); break; + case '@': chan_ev(chan_th, EV_NANOS6_SCHED_SELF); break; + case 'r': chan_ev(chan_th, EV_NANOS6_SCHED_RECV); break; + case 's': chan_ev(chan_th, EV_NANOS6_SCHED_SEND); break; + default: break; + } +} + +static void +pre_thread_type(struct ovni_emu *emu) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + switch(emu->cur_ev->header.value) + { + case 'a': chan_push(chan_th, ST_NANOS6_ATTACHED); break; + case 'A': chan_pop (chan_th, ST_NANOS6_ATTACHED); break; + case 's': chan_push(chan_th, ST_NANOS6_SPAWNING); break; + case 'S': chan_pop (chan_th, ST_NANOS6_SPAWNING); break; + default: break; + } +} + +static void +pre_ss(struct ovni_emu *emu, int st) +{ + struct ovni_ethread *th; + struct ovni_chan *chan_th; + + th = emu->cur_thread; + chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; + + dbg("pre_ss chan id %d st=%d\n", chan_th->id, st); + + switch(emu->cur_ev->header.value) + { + case '[': chan_push(chan_th, st); break; + case ']': chan_pop(chan_th, st); break; + default: + err("unexpected value '%c' (expecting '[' or ']')\n", + emu->cur_ev->header.value); + abort(); + } +} + +static void +check_affinity(struct ovni_emu *emu) +{ + struct ovni_ethread *th = emu->cur_thread; + struct ovni_cpu *cpu = th->cpu; + + if(!cpu || cpu->virtual) + return; + + if(cpu->nrunning_threads > 1) + { + die("cpu %s has more than one thread running\n", + cpu->name); + } +} + +void +hook_pre_nanos6(struct ovni_emu *emu) +{ + if(emu->cur_ev->header.model != '6') + die("hook_pre_nanos6: unexpected event with model %c\n", + emu->cur_ev->header.model); + + if(!emu->cur_thread->is_active) + die("hook_pre_nanos6: current thread %d not active\n", + emu->cur_thread->tid); + + switch(emu->cur_ev->header.category) + { + case 'T': pre_task(emu); break; + case 'Y': pre_type(emu); break; + case 'S': pre_sched(emu); break; + case 'U': pre_ss(emu, ST_NANOS6_SUBMIT); break; + case 'H': pre_thread_type(emu); break; + case 'D': pre_deps(emu); break; + case 'B': pre_blocking(emu); break; + default: + break; + } + + check_affinity(emu); +} + +void +hook_end_nanos6(struct ovni_emu *emu) +{ + /* Emit types for all channel types and processes */ + for(enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) + { + struct pcf_file *pcf = &emu->pcf[ct]; + int typeid = chan_to_prvtype[CHAN_NANOS6_TYPE]; + struct pcf_type *pcftype = pcf_find_type(pcf, typeid); + + for(size_t i = 0; i < emu->trace.nlooms; i++) + { + struct ovni_loom *loom = &emu->trace.loom[i]; + for(size_t j = 0; j < loom->nprocs; j++) + { + struct ovni_eproc *proc = &loom->proc[j]; + task_create_pcf_types(pcftype, proc->nanos6_types); + } + } + } +} diff --git a/emu_nosv.c b/emu_nosv.c index 050d7fd..2c9ae9a 100644 --- a/emu_nosv.c +++ b/emu_nosv.c @@ -20,6 +20,7 @@ #include "ovni.h" #include "emu.h" +#include "emu_task.h" #include "prv.h" #include "chan.h" @@ -78,170 +79,7 @@ hook_init_nosv(struct ovni_emu *emu) /* --------------------------- pre ------------------------------- */ static void -pre_task_create(struct ovni_emu *emu) -{ - uint32_t task_id = emu->cur_ev->payload.u32[0]; - uint32_t type_id = emu->cur_ev->payload.u32[1]; - - /* Ensure the task id is new */ - struct nosv_task *task = NULL; - HASH_FIND_INT(emu->cur_proc->tasks, &task_id, task); - - if(task != NULL) - die("a task with id %u already exists\n", task_id); - - /* Ensure the type exists */ - struct nosv_task_type *type = NULL; - HASH_FIND_INT(emu->cur_proc->types, &type_id, type); - - if(type == NULL) - die("unknown task type id %u\n", type_id); - - task = calloc(1, sizeof(*task)); - - if(task == NULL) - die("calloc failed\n"); - - task->id = task_id; - task->type = type; - task->state = TASK_ST_CREATED; - task->thread = NULL; - - /* Add the new task to the hash table */ - HASH_ADD_INT(emu->cur_proc->tasks, id, task); - - dbg("new task created id=%d\n", task->id); -} - -static void -pre_task_execute(struct ovni_emu *emu) -{ - struct nosv_task *top = emu->cur_thread->task_stack; - uint32_t taskid = emu->cur_ev->payload.u32[0]; - - struct nosv_task *task = NULL; - HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); - - if(task == NULL) - die("cannot find task with id %u\n", taskid); - - if(task->state != TASK_ST_CREATED) - die("task state is not created\n"); - - if(task->thread != NULL) - die("task already has a thread assigned\n"); - - if(emu->cur_thread->state != TH_ST_RUNNING) - die("thread state is not running\n"); - - if(top == task) - die("thread already has assigned task %u\n", taskid); - - if(top && top->state != TASK_ST_RUNNING) - die("cannot execute a nested task from a non-running task\n"); - - task->state = TASK_ST_RUNNING; - task->thread = emu->cur_thread; - - DL_PREPEND(emu->cur_thread->task_stack, task); - - dbg("task id=%u runs now\n", task->id); -} - -static void -pre_task_pause(struct ovni_emu *emu) -{ - struct nosv_task *top = emu->cur_thread->task_stack; - uint32_t taskid = emu->cur_ev->payload.u32[0]; - - struct nosv_task *task = NULL; - HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); - - if(task == NULL) - die("cannot find task with id %u\n", taskid); - - if(task->state != TASK_ST_RUNNING) - die("task state is not running\n"); - - if(emu->cur_thread->state != TH_ST_RUNNING) - die("thread state is not running\n"); - - if(top != task) - die("thread has assigned a different task\n"); - - if(emu->cur_thread != task->thread) - die("task is assigned to a different thread\n"); - - task->state = TASK_ST_PAUSED; - - dbg("task id=%d pauses\n", task->id); -} - -static void -pre_task_resume(struct ovni_emu *emu) -{ - struct nosv_task *top = emu->cur_thread->task_stack; - uint32_t taskid = emu->cur_ev->payload.u32[0]; - - struct nosv_task *task = NULL; - HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); - - if(task == NULL) - die("cannot find task with id %u\n", taskid); - - if(task->state != TASK_ST_PAUSED) - die("task state is not paused\n"); - - if(emu->cur_thread->state != TH_ST_RUNNING) - die("thread is not running\n"); - - if(top != task) - die("thread has assigned a different task\n"); - - if(emu->cur_thread != task->thread) - die("task is assigned to a different thread\n"); - - task->state = TASK_ST_RUNNING; - - dbg("task id=%d resumes\n", task->id); -} - -static void -pre_task_end(struct ovni_emu *emu) -{ - struct nosv_task *top = emu->cur_thread->task_stack; - uint32_t taskid = emu->cur_ev->payload.u32[0]; - - struct nosv_task *task = NULL; - HASH_FIND_INT(emu->cur_proc->tasks, &taskid, task); - - if(task == NULL) - die("cannot find task with id %u\n", taskid); - - if(task->state != TASK_ST_RUNNING) - die("task state is not running\n"); - - if(emu->cur_thread->state != TH_ST_RUNNING) - die("thread is not running\n"); - - if(top != task) - die("thread has assigned a different task\n"); - - if(emu->cur_thread != task->thread) - die("task is assigned to a different thread\n"); - - task->state = TASK_ST_DEAD; - - /* Don't unset the thread from the task, as it will be used - * later to ensure we switch to tasks of the same thread. */ - - DL_DELETE(emu->cur_thread->task_stack, task); - - dbg("task id=%d ends\n", task->id); -} - -static void -pre_task_not_running(struct ovni_emu *emu, struct nosv_task *task) +task_not_running(struct ovni_emu *emu, struct task *task) { struct ovni_ethread *th; th = emu->cur_thread; @@ -260,7 +98,7 @@ pre_task_not_running(struct ovni_emu *emu, struct nosv_task *task) } static void -pre_task_running(struct ovni_emu *emu, struct nosv_task *task) +task_running(struct ovni_emu *emu, struct task *task) { struct ovni_ethread *th; struct ovni_eproc *proc; @@ -288,8 +126,8 @@ pre_task_running(struct ovni_emu *emu, struct nosv_task *task) } static void -pre_task_switch(struct ovni_emu *emu, struct nosv_task *prev_task, - struct nosv_task *next_task, int newtask) +task_switch(struct ovni_emu *emu, struct task *prev_task, + struct task *next_task, int newtask) { struct ovni_ethread *th; @@ -331,35 +169,28 @@ pre_task_switch(struct ovni_emu *emu, struct nosv_task *prev_task, chan_set(&th->chan[CHAN_NOSV_TYPE], next_task->type->gid); } -static struct nosv_task * -get_running_task(struct ovni_emu *emu) -{ - struct nosv_task *task = emu->cur_thread->task_stack; - if(task && task->state == TASK_ST_RUNNING) - return task; - - return NULL; -} - static void pre_task(struct ovni_emu *emu) { - struct nosv_task *prev_running = get_running_task(emu); + struct task **task_map = &emu->cur_proc->nosv_tasks; + struct task_type **type_map = &emu->cur_proc->nosv_types; + struct task **task_stack = &emu->cur_thread->nosv_task_stack; + struct task *prev_running = task_get_running(*task_stack); int was_running_task = (prev_running != NULL); /* Update the emulator state, but don't modify the channels yet */ switch(emu->cur_ev->header.value) { - case 'c': pre_task_create(emu); break; - case 'x': pre_task_execute(emu); break; - case 'e': pre_task_end(emu); break; - case 'p': pre_task_pause(emu); break; - case 'r': pre_task_resume(emu); break; + case 'c': task_create(emu->cur_ev->payload.i32[0], emu->cur_ev->payload.i32[1], task_map, type_map); break; + case 'x': task_execute(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'e': task_end(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'p': task_pause(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; + case 'r': task_resume(emu->cur_ev->payload.i32[0], emu->cur_thread, task_map, task_stack); break; default: abort(); } - struct nosv_task *next_running = get_running_task(emu); + struct task *next_running = task_get_running(*task_stack); int runs_task_now = (next_running != NULL); /* Now that we know if the emulator was running a task before @@ -368,102 +199,47 @@ pre_task(struct ovni_emu *emu) { case 'x': /* Execute: either a nested task or a new one */ if(was_running_task) - pre_task_switch(emu, prev_running, next_running, 1); + task_switch(emu, prev_running, next_running, 1); else - pre_task_running(emu, next_running); + task_running(emu, next_running); break; case 'e': /* End: either a nested task or the last one */ if(runs_task_now) - pre_task_switch(emu, prev_running, next_running, 0); + task_switch(emu, prev_running, next_running, 0); else - pre_task_not_running(emu, prev_running); + task_not_running(emu, prev_running); break; case 'p': /* Pause */ - pre_task_not_running(emu, prev_running); + task_not_running(emu, prev_running); break; case 'r': /* Resume */ - pre_task_running(emu, next_running); + task_running(emu, next_running); break; default: break; } } -static uint32_t -get_task_type_gid(const char *label) -{ - uint32_t gid; - - HASH_VALUE(label, strlen(label), gid); - - /* Use non-negative values */ - gid &= 0x7FFFFFFF; - - if (gid == 0) - gid++; - - return gid; -} - -static void -pre_type_create(struct ovni_emu *emu) -{ - struct nosv_task_type *type; - uint8_t *data; - uint32_t *typeid; - const char *label; - - if((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) - { - err("expecting a jumbo event\n"); - abort(); - } - - data = &emu->cur_ev->payload.jumbo.data[0]; - typeid = (uint32_t *) data; - data += sizeof(*typeid); - label = (const char *) data; - - /* Ensure the type id is new */ - HASH_FIND_INT(emu->cur_proc->types, typeid, type); - - if(type != NULL) - { - err("A task type with id %d already exists\n", *typeid); - abort(); - } - - type = calloc(1, sizeof(*type)); - - if(type == NULL) - { - perror("calloc"); - abort(); - } - - type->id = *typeid; - - if(type->id == 0) - die("invalid task type id %d\n", type->id); - - type->gid = get_task_type_gid(label); - int n = snprintf(type->label, MAX_PCF_LABEL, "%s", label); - if(n >= MAX_PCF_LABEL) - die("task label too long: %s\n", label); - - /* Add the new task type to the hash table */ - HASH_ADD_INT(emu->cur_proc->types, id, type); - - dbg("new task type created id=%d label=%s\n", type->id, - type->label); -} - static void pre_type(struct ovni_emu *emu) { + uint8_t *data; + switch(emu->cur_ev->header.value) { - case 'c': pre_type_create(emu); break; + case 'c': + if((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) + { + err("expecting a jumbo event\n"); + abort(); + } + + data = &emu->cur_ev->payload.jumbo.data[0]; + uint32_t *typeid = (uint32_t *) data; + data += sizeof(*typeid); + const char *label = (const char *) data; + task_type_create(*typeid, label, &emu->cur_proc->nosv_types); + break; default: break; } @@ -645,28 +421,6 @@ hook_pre_nosv(struct ovni_emu *emu) check_affinity(emu); } -static void -create_pcf_task_types(struct ovni_eproc *proc, struct pcf_type *pcftype) -{ - /* Emit types for all task types */ - struct nosv_task_type *tt; - for(tt = proc->types; tt != NULL; tt=tt->hh.next) - { - struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid); - if(pcfvalue != NULL) - { - /* Ensure the label is the same, so we know that - * no collision occurred */ - if(strcmp(pcfvalue->label, tt->label) != 0) - die("collision occurred in task type labels\n"); - else - continue; - } - - pcf_add_value(pcftype, tt->gid, tt->label); - } -} - void hook_end_nosv(struct ovni_emu *emu) { @@ -674,7 +428,7 @@ hook_end_nosv(struct ovni_emu *emu) for(enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) { struct pcf_file *pcf = &emu->pcf[ct]; - int typeid = chan_to_prvtype[CHAN_NOSV_TYPE][ct]; + int typeid = chan_to_prvtype[CHAN_NOSV_TYPE]; struct pcf_type *pcftype = pcf_find_type(pcf, typeid); for(size_t i = 0; i < emu->trace.nlooms; i++) @@ -683,7 +437,7 @@ hook_end_nosv(struct ovni_emu *emu) for(size_t j = 0; j < loom->nprocs; j++) { struct ovni_eproc *proc = &loom->proc[j]; - create_pcf_task_types(proc, pcftype); + task_create_pcf_types(pcftype, proc->nosv_types); } } } diff --git a/emu_task.c b/emu_task.c new file mode 100644 index 0000000..8003f90 --- /dev/null +++ b/emu_task.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2022 Barcelona Supercomputing Center (BSC) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "uthash.h" +#include "utlist.h" + +#include "ovni.h" +#include "emu.h" +#include "emu_task.h" +#include "prv.h" +#include "chan.h" + +void +task_create(uint32_t task_id, uint32_t type_id, struct task **task_map, struct task_type **type_map) +{ + /* Ensure the task id is new */ + struct task *task = NULL; + HASH_FIND_INT(*task_map, &task_id, task); + + if(task != NULL) + die("a task with id %u already exists\n", task_id); + + /* Ensure the type exists */ + struct task_type *type = NULL; + HASH_FIND_INT(*type_map, &type_id, type); + + if(type == NULL) + die("unknown task type id %u\n", type_id); + + task = calloc(1, sizeof(*task)); + + if(task == NULL) + die("calloc failed\n"); + + task->id = task_id; + task->type = type; + task->state = TASK_ST_CREATED; + task->thread = NULL; + + /* Add the new task to the hash table */ + HASH_ADD_INT(*task_map, id, task); + + dbg("new task created id=%d\n", task->id); +} + +void +task_execute(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack) +{ + struct task *top = *thread_task_stack; + struct task *task = NULL; + HASH_FIND_INT(*task_map, &task_id, task); + + if(task == NULL) + die("cannot find task with id %u\n", task_id); + + if(task->state != TASK_ST_CREATED) + die("task state is not created\n"); + + if(task->thread != NULL) + die("task already has a thread assigned\n"); + + if(cur_thread->state != TH_ST_RUNNING) + die("thread state is not running\n"); + + if(top == task) + die("thread already has assigned task %u\n", task_id); + + if(top && top->state != TASK_ST_RUNNING) + die("cannot execute a nested task from a non-running task\n"); + + task->state = TASK_ST_RUNNING; + task->thread = cur_thread; + + DL_PREPEND(*thread_task_stack, task); + + dbg("task id=%u runs now\n", task->id); +} + +void +task_pause(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack) +{ + struct task *top = *thread_task_stack; + struct task *task = NULL; + HASH_FIND_INT(*task_map, &task_id, task); + + if(task == NULL) + die("cannot find task with id %u\n", task_id); + + if(task->state != TASK_ST_RUNNING) + die("task state is not running\n"); + + if(cur_thread->state != TH_ST_RUNNING) + die("thread state is not running\n"); + + if(top != task) + die("thread has assigned a different task\n"); + + if(cur_thread != task->thread) + die("task is assigned to a different thread\n"); + + task->state = TASK_ST_PAUSED; + + dbg("task id=%d pauses\n", task->id); +} + +void +task_resume(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack) +{ + struct task *top = *thread_task_stack; + struct task *task = NULL; + HASH_FIND_INT(*task_map, &task_id, task); + + if(task == NULL) + die("cannot find task with id %u\n", task_id); + + if(task->state != TASK_ST_PAUSED) + die("task state is not paused\n"); + + if(cur_thread->state != TH_ST_RUNNING) + die("thread is not running\n"); + + if(top != task) + die("thread has assigned a different task\n"); + + if(cur_thread != task->thread) + die("task is assigned to a different thread\n"); + + task->state = TASK_ST_RUNNING; + + dbg("task id=%d resumes\n", task->id); +} + +void +task_end(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack) +{ + struct task *top = *thread_task_stack; + struct task *task = NULL; + HASH_FIND_INT(*task_map, &task_id, task); + + if(task == NULL) + die("cannot find task with id %u\n", task_id); + + if(task->state != TASK_ST_RUNNING) + die("task state is not running\n"); + + if(cur_thread->state != TH_ST_RUNNING) + die("thread is not running\n"); + + if(top != task) + die("thread has assigned a different task\n"); + + if(cur_thread != task->thread) + die("task is assigned to a different thread\n"); + + task->state = TASK_ST_DEAD; + + /* Don't unset the thread from the task, as it will be used + * later to ensure we switch to tasks of the same thread. */ + + DL_DELETE(*thread_task_stack, task); + + dbg("task id=%d ends\n", task->id); +} + +static uint32_t +get_task_type_gid(const char *label) +{ + uint32_t gid; + + HASH_VALUE(label, strlen(label), gid); + + /* Use non-negative values */ + gid &= 0x7FFFFFFF; + + if(gid == 0) + gid++; + + return gid; +} + +void +task_type_create(uint32_t typeid, const char *label, struct task_type **type_map) +{ + struct task_type *type; + /* Ensure the type id is new */ + HASH_FIND_INT(*type_map, &typeid, type); + + if(type != NULL) + { + err("A task type with id %d already exists\n", typeid); + abort(); + } + + type = calloc(1, sizeof(*type)); + + if(type == NULL) + { + perror("calloc"); + abort(); + } + + type->id = typeid; + + if(type->id == 0) + die("invalid task type id %d\n", type->id); + + type->gid = get_task_type_gid(label); + int n = snprintf(type->label, MAX_PCF_LABEL, "%s", label); + if(n >= MAX_PCF_LABEL) + die("task label too long: %s\n", label); + + /* Add the new task type to the hash table */ + HASH_ADD_INT(*type_map, id, type); + + dbg("new task type created id=%d label=%s\n", type->id, + type->label); +} + +void +task_create_pcf_types(struct pcf_type *pcftype, struct task_type *type_map) +{ + /* Emit types for all task types */ + struct task_type *tt; + for(tt = type_map; tt != NULL; tt = tt->hh.next) + { + struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid); + if(pcfvalue != NULL) + { + /* Ensure the label is the same, so we know that + * no collision occurred */ + if(strcmp(pcfvalue->label, tt->label) != 0) + die("collision occurred in task type labels\n"); + else + continue; + } + + pcf_add_value(pcftype, tt->gid, tt->label); + } +} + +struct task * +task_get_running(struct task *task_stack) +{ + struct task *task = task_stack; + if(task && task->state == TASK_ST_RUNNING) + return task; + + return NULL; +} diff --git a/emu_task.h b/emu_task.h new file mode 100644 index 0000000..1f8ce7b --- /dev/null +++ b/emu_task.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Barcelona Supercomputing Center (BSC) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef OVNI_EMU_TASK_H +#define OVNI_EMU_TASK_H + +#include "emu.h" + +void task_create(uint32_t task_id, uint32_t type_id, struct task **task_map, struct task_type **type_map); +void task_execute(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack); +void task_pause(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack); +void task_resume(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack); +void task_end(uint32_t task_id, struct ovni_ethread *cur_thread, struct task **task_map, struct task **thread_task_stack); +void task_type_create(uint32_t typeid, const char *label, struct task_type **type_map); +void task_create_pcf_types(struct pcf_type *pcftype, struct task_type *type_map); +struct task *task_get_running(struct task *task_stack); + +#endif /* OVNI_EMU_TASK_H */ diff --git a/pcf.c b/pcf.c index 74e55c3..2b6d30d 100644 --- a/pcf.c +++ b/pcf.c @@ -178,6 +178,29 @@ struct pcf_value_label kernel_cs_values[] = { { -1, NULL }, }; +struct pcf_value_label nanos6_ss_values[] = { + { ST_NULL, "NULL" }, + { ST_TOO_MANY_TH, "Unknown: multiple threads running" }, + { ST_NANOS6_TASK_RUNNING, "Task: Running" }, + { ST_NANOS6_SCHED_HUNGRY, "Scheduler: Waiting for tasks" }, + { ST_NANOS6_SCHED_SERVING, "Scheduler: Serving tasks" }, + { ST_NANOS6_SCHED_SUBMITTING, "Scheduler: Adding ready tasks" }, + { ST_NANOS6_SPAWNING, "Task: Spawning function" }, + { ST_NANOS6_ATTACHED, "Threading: Attached as external thread" }, + { ST_NANOS6_DEP_REG, "Dependency: Registering" }, + { ST_NANOS6_DEP_UNREG, "Dependency: Unregistering" }, + { ST_NANOS6_TASKWAIT, "Blocking: Taskwait" }, + { ST_NANOS6_BLOCKING, "Blocking: Blocking current task" }, + { ST_NANOS6_UNBLOCKING, "Blocking: Unblocking remote task" }, + { ST_NANOS6_WAITFOR, "Blocking: Wait For" }, + { ST_NANOS6_CREATING, "Task: Creating" }, + { ST_NANOS6_SUBMIT, "Task: Submitting" }, + { EV_NANOS6_SCHED_SEND, "EV Scheduler: Send task" }, + { EV_NANOS6_SCHED_RECV, "EV Scheduler: Recv task" }, + { EV_NANOS6_SCHED_SELF, "EV Scheduler: Self-assign task" }, + { -1, NULL }, +}; + struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = { [CHAN_OVNI_PID] = &default_values, [CHAN_OVNI_TID] = &default_values, @@ -197,6 +220,11 @@ struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = { [CHAN_OPENMP_MODE] = &openmp_mode_values, [CHAN_NODES_SUBSYSTEM] = &nodes_mode_values, + [CHAN_NANOS6_TASKID] = &default_values, + [CHAN_NANOS6_TYPE] = &default_values, + [CHAN_NANOS6_SUBSYSTEM] = &nanos6_ss_values, + [CHAN_NANOS6_RANK] = &default_values, + [CHAN_KERNEL_CS] = &kernel_cs_values, }; @@ -215,12 +243,17 @@ char *pcf_chan_name[CHAN_MAX] = { [CHAN_NOSV_TYPE] = "nOS-V task type", [CHAN_NOSV_APPID] = "nOS-V task AppID", [CHAN_NOSV_SUBSYSTEM] = "nOS-V subsystem", - [CHAN_NOSV_RANK] = "MPI rank", + [CHAN_NOSV_RANK] = "nOS-V task MPI rank", [CHAN_TAMPI_MODE] = "TAMPI mode", [CHAN_OPENMP_MODE] = "OpenMP mode", [CHAN_NODES_SUBSYSTEM] = "NODES subsystem", + [CHAN_NANOS6_TASKID] = "Nanos6 task ID", + [CHAN_NANOS6_TYPE] = "Nanos6 task type", + [CHAN_NANOS6_SUBSYSTEM] = "Nanos6 subsystem", + [CHAN_NANOS6_RANK] = "Nanos6 task MPI rank", + [CHAN_KERNEL_CS] = "Context switches", }; @@ -253,6 +286,11 @@ int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = { [CHAN_OPENMP_MODE] = { RUN_TH, RUN_TH }, [CHAN_NODES_SUBSYSTEM] = { RUN_TH, RUN_TH }, + [CHAN_NANOS6_TASKID] = { RUN_TH, RUN_TH }, + [CHAN_NANOS6_TYPE] = { RUN_TH, RUN_TH }, + [CHAN_NANOS6_SUBSYSTEM] = { ACT_TH, RUN_TH }, + [CHAN_NANOS6_RANK] = { RUN_TH, RUN_TH }, + [CHAN_KERNEL_CS] = { CUR_TH, ACT_TH }, }; @@ -326,7 +364,7 @@ create_type(struct pcf_file *pcf, enum chan c) { char label[MAX_PCF_LABEL]; enum chan_type ct = pcf->chantype; - int prv_type = chan_to_prvtype[c][ct]; + int prv_type = chan_to_prvtype[c]; if(prv_type == -1) return;