Implement Nanos6 emulator model
This commit is contained in:
		
							parent
							
								
									7da7ff8c1c
								
							
						
					
					
						commit
						b226afb630
					
				| @ -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 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								cfg/all.cfg
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								cfg/cpu.cfg
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										4
									
								
								chan.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										7
									
								
								emu.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								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; i<emu->total_ncpus; i++) | ||||
|  | ||||
							
								
								
									
										120
									
								
								emu.h
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								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); | ||||
|  | ||||
							
								
								
									
										440
									
								
								emu_nanos6.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								emu_nanos6.c
									
									
									
									
									
										Normal file
									
								
							| @ -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 <https://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #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; i<emu->total_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; i<emu->total_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); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										322
									
								
								emu_nosv.c
									
									
									
									
									
								
							
							
						
						
									
										322
									
								
								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); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										263
									
								
								emu_task.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								emu_task.c
									
									
									
									
									
										Normal file
									
								
							| @ -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 <https://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #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; | ||||
| } | ||||
							
								
								
									
										32
									
								
								emu_task.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								emu_task.h
									
									
									
									
									
										Normal file
									
								
							| @ -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 <https://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #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 */ | ||||
							
								
								
									
										42
									
								
								pcf.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								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; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 David Alvarez
						David Alvarez