Add PCF information for nanos6
This commit is contained in:
		
							parent
							
								
									c94a786c1e
								
							
						
					
					
						commit
						4e2164646c
					
				| @ -27,6 +27,7 @@ add_library(emu STATIC | ||||
|   mux.c | ||||
|   path.c | ||||
|   proc.c | ||||
|   pcf.c | ||||
|   prv.c | ||||
|   pvt.c | ||||
|   recorder.c | ||||
| @ -41,6 +42,7 @@ add_library(emu STATIC | ||||
|   nanos6/connect.c | ||||
|   nanos6/create.c | ||||
|   nanos6/event.c | ||||
|   nanos6/pvt.c | ||||
| ) | ||||
| 
 | ||||
| add_executable(ovniemu ovniemu.c) | ||||
|  | ||||
| @ -156,3 +156,13 @@ emu_step(struct emu *emu) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| emu_finish(struct emu *emu) | ||||
| { | ||||
| 	if (recorder_finish(&emu->recorder) != 0) { | ||||
| 		err("recorder_finish failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -39,6 +39,7 @@ struct emu { | ||||
| int emu_init(struct emu *emu, int argc, char *argv[]); | ||||
| int emu_connect(struct emu *emu); | ||||
| int emu_step(struct emu *emu); | ||||
| int emu_finish(struct emu *emu); | ||||
| 
 | ||||
| static inline struct emu * | ||||
| emu_get(void *ptr) | ||||
|  | ||||
| @ -1,32 +1,14 @@ | ||||
| #include "nanos6_priv.h" | ||||
| 
 | ||||
| const enum nanos6_track th_track[] = { | ||||
| 	[CH_TASKID]    = RUN_TH, | ||||
| 	[CH_TYPE]      = RUN_TH, | ||||
| 	[CH_SUBSYSTEM] = ACT_TH, | ||||
| 	[CH_RANK]      = RUN_TH, | ||||
| 	[CH_THREAD]    = NONE, | ||||
| const enum nanos6_track chan_track[CH_MAX][CT_MAX] = { | ||||
| 	                /* Thread  CPU */ | ||||
| 	[CH_TASKID]    = { RUN_TH, RUN_TH }, | ||||
| 	[CH_TYPE]      = { RUN_TH, RUN_TH }, | ||||
| 	[CH_SUBSYSTEM] = { ACT_TH, RUN_TH }, | ||||
| 	[CH_RANK]      = { RUN_TH, RUN_TH }, | ||||
| 	[CH_THREAD]    = { NONE,   RUN_TH }, | ||||
| }; | ||||
| 
 | ||||
| const enum nanos6_track cpu_track[] = { | ||||
| 	[CH_TASKID]    = RUN_TH, | ||||
| 	[CH_TYPE]      = RUN_TH, | ||||
| 	[CH_SUBSYSTEM] = RUN_TH, | ||||
| 	[CH_RANK]      = RUN_TH, | ||||
| 	[CH_THREAD]    = RUN_TH, | ||||
| }; | ||||
| 
 | ||||
| static const int th_type[] = { | ||||
| 	[CH_TASKID]    = 35, | ||||
| 	[CH_TYPE]      = 36, | ||||
| 	[CH_SUBSYSTEM] = 37, | ||||
| 	[CH_RANK]      = 38, | ||||
| 	[CH_THREAD]    = 39, | ||||
| }; | ||||
| 
 | ||||
| static const int *cpu_type = th_type; | ||||
| 
 | ||||
| 
 | ||||
| static int | ||||
| connect_thread_mux(struct emu *emu, struct thread *thread) | ||||
| { | ||||
| @ -67,9 +49,10 @@ connect_thread_mux(struct emu *emu, struct thread *thread) | ||||
| 
 | ||||
| 		/* The tracking only sets the ch_out, but we keep both tracking
 | ||||
| 		 * updated as the CPU tracking channels may use them. */ | ||||
| 		if (th_track[i] == RUN_TH) | ||||
| 		enum nanos6_track track = chan_track[i][CT_TH]; | ||||
| 		if (track == RUN_TH) | ||||
| 			th->ch_out[i] = &th->ch_run[i]; | ||||
| 		else if (th_track[i] == ACT_TH) | ||||
| 		else if (track == ACT_TH) | ||||
| 			th->ch_out[i] = &th->ch_act[i]; | ||||
| 		else | ||||
| 			th->ch_out[i] = &th->ch[i]; | ||||
| @ -79,23 +62,6 @@ connect_thread_mux(struct emu *emu, struct thread *thread) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv) | ||||
| { | ||||
| 	struct nanos6_thread *th = EXT(thread, '6'); | ||||
| 	for (int i = 0; i < CH_MAX; i++) { | ||||
| 		struct chan *out = th->ch_out[i]; | ||||
| 		long type = th_type[i]; | ||||
| 		long row = thread->gindex; | ||||
| 		if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { | ||||
| 			err("prv_register failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i) | ||||
| { | ||||
| @ -104,12 +70,13 @@ add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i) | ||||
| 
 | ||||
| 		/* Choose input thread channel based on tracking mode */ | ||||
| 		struct chan *inp = NULL; | ||||
| 		if (cpu_track[i] == RUN_TH) | ||||
| 		enum nanos6_track track = chan_track[i][CT_CPU]; | ||||
| 		if (track == RUN_TH) | ||||
| 			inp = &th->ch_run[i]; | ||||
| 		else if (cpu_track[i] == ACT_TH) | ||||
| 		else if (track == ACT_TH) | ||||
| 			inp = &th->ch_act[i]; | ||||
| 		else | ||||
| 			die("cpu tracking must be 'running' or 'active'"); | ||||
| 			die("cpu tracking must be running or active"); | ||||
| 
 | ||||
| 		if (mux_add_input(mux, value_int64(t->gindex), inp) != 0) { | ||||
| 			err("mux_add_input failed"); | ||||
| @ -130,12 +97,13 @@ connect_cpu_mux(struct emu *emu, struct cpu *scpu) | ||||
| 
 | ||||
| 		/* Choose select CPU channel based on tracking mode */ | ||||
| 		struct chan *sel = NULL; | ||||
| 		if (cpu_track[i] == RUN_TH) | ||||
| 		enum nanos6_track track = chan_track[i][CT_CPU]; | ||||
| 		if (track == RUN_TH) | ||||
| 			sel = &scpu->chan[CPU_CHAN_THRUN]; | ||||
| 		else if (cpu_track[i] == ACT_TH) | ||||
| 		else if (track == ACT_TH) | ||||
| 			sel = &scpu->chan[CPU_CHAN_THACT]; | ||||
| 		else | ||||
| 			die("cpu tracking must be 'running' or 'active'"); | ||||
| 			die("cpu tracking must be running or active"); | ||||
| 
 | ||||
| 		if (mux_init(mux, &emu->bay, sel, out, NULL) != 0) { | ||||
| 			err("mux_init failed"); | ||||
| @ -151,8 +119,8 @@ connect_cpu_mux(struct emu *emu, struct cpu *scpu) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_threads(struct emu *emu) | ||||
| int | ||||
| nanos6_connect(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| @ -164,51 +132,6 @@ connect_threads(struct emu *emu) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Get thread PRV */ | ||||
| 	struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread"); | ||||
| 	if (pvt == NULL) { | ||||
| 		err("cannot find thread pvt"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	struct prv *prv = pvt_get_prv(pvt); | ||||
| 
 | ||||
| 	for (struct thread *t = sys->threads; t; t = t->gnext) { | ||||
| 		if (connect_thread_prv(emu, t, prv) != 0) { | ||||
| 			err("connect_thread_prv failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv) | ||||
| { | ||||
| 	struct nanos6_cpu *cpu = EXT(scpu, '6'); | ||||
| 	for (int i = 0; i < CH_MAX; i++) { | ||||
| 		struct chan *out = &cpu->ch[i]; | ||||
| 		long type = cpu_type[i]; | ||||
| 		long row = scpu->gindex; | ||||
| 		if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { | ||||
| 			err("prv_register failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| //static int
 | ||||
| //populate_cpu_pcf(struct emu *emu, struct pcf *pcf)
 | ||||
| //{
 | ||||
| //}
 | ||||
| 
 | ||||
| static int | ||||
| connect_cpus(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| 	/* cpus */ | ||||
| 	for (struct cpu *c = sys->cpus; c; c = c->next) { | ||||
| 		if (connect_cpu_mux(emu, c) != 0) { | ||||
| @ -217,37 +140,8 @@ connect_cpus(struct emu *emu) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Get cpu PRV */ | ||||
| 	struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu"); | ||||
| 	if (pvt == NULL) { | ||||
| 		err("cannot find cpu pvt"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	struct prv *prv = pvt_get_prv(pvt); | ||||
| 
 | ||||
| 	for (struct cpu *c = sys->cpus; c; c = c->next) { | ||||
| 		if (connect_cpu_prv(emu, c, prv) != 0) { | ||||
| 			err("connect_cpu_prv failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| //	struct pcf *pcf = pvt_get_pcf(pvt);
 | ||||
| //	populate_cpu_pcf(pcf, emu);
 | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| nanos6_connect(struct emu *emu) | ||||
| { | ||||
| 	if (connect_threads(emu) != 0) { | ||||
| 		err("connect_threads failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (connect_cpus(emu) != 0) { | ||||
| 		err("connect_cpus failed"); | ||||
| 	if (init_pvt(emu) != 0) { | ||||
| 		err("init_pvt failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
|  | ||||
| @ -10,7 +10,14 @@ | ||||
| #include "task.h" | ||||
| 
 | ||||
| /* Private enums */ | ||||
| 
 | ||||
| enum nanos6_chan_type { | ||||
| 	CT_TH = 0, | ||||
| 	CT_CPU, | ||||
| 	CT_MAX | ||||
| }; | ||||
| 
 | ||||
| enum nanos6_chan { | ||||
| 	CH_TASKID = 0, | ||||
| 	CH_TYPE, | ||||
| 	CH_SUBSYSTEM, | ||||
| @ -26,8 +33,7 @@ enum nanos6_track { | ||||
| 	TRACK_MAX, | ||||
| }; | ||||
| 
 | ||||
| extern const enum nanos6_track th_track[CH_MAX]; | ||||
| extern const enum nanos6_track cpu_track[CH_MAX]; | ||||
| extern const enum nanos6_track chan_track[CH_MAX][CT_MAX]; | ||||
| 
 | ||||
| enum nanos6_ss_state { | ||||
| 	ST_TASK_BODY = 1, | ||||
| @ -93,4 +99,6 @@ int nanos6_create(struct emu *emu); | ||||
| int nanos6_connect(struct emu *emu); | ||||
| int nanos6_event(struct emu *emu); | ||||
| 
 | ||||
| int init_pvt(struct emu *emu); | ||||
| 
 | ||||
| #endif /* NANOS6_PRIV_H */ | ||||
|  | ||||
							
								
								
									
										242
									
								
								src/emu/nanos6/pvt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								src/emu/nanos6/pvt.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,242 @@ | ||||
| #include "nanos6_priv.h" | ||||
| 
 | ||||
| /* TODO: Assign types on runtime and generate configs */ | ||||
| static const int pvt_type[] = { | ||||
| 	[CH_TASKID]    = 35, | ||||
| 	[CH_TYPE]      = 36, | ||||
| 	[CH_SUBSYSTEM] = 37, | ||||
| 	[CH_RANK]      = 38, | ||||
| 	[CH_THREAD]    = 39, | ||||
| }; | ||||
| 
 | ||||
| static const char *pcf_prefix[CH_MAX] = { | ||||
| 	[CH_TASKID]    = "Nanos6 task ID", | ||||
| 	[CH_TYPE]      = "Nanos6 task type", | ||||
| 	[CH_SUBSYSTEM] = "Nanos6 subsystem", | ||||
| 	[CH_RANK]      = "Nanos6 task MPI rank", | ||||
| 	[CH_THREAD]    = "Nanos6 thread type", | ||||
| }; | ||||
| 
 | ||||
| static const char *pcf_suffix[TRACK_MAX] = { | ||||
| 	[NONE] = "", | ||||
| 	[RUN_TH] = "of the RUNNING thread", | ||||
| 	[ACT_TH] = "of the ACTIVE thread", | ||||
| }; | ||||
| 
 | ||||
| static const struct pcf_value_label nanos6_ss_values[] = { | ||||
| 	{ ST_TASK_BODY,        "Task: Running body" }, | ||||
| 	{ ST_TASK_CREATING,    "Task: Creating" }, | ||||
| 	{ ST_TASK_SUBMIT,      "Task: Submitting" }, | ||||
| 	{ ST_TASK_SPAWNING,    "Task: Spawning function" }, | ||||
| 	{ ST_TASK_FOR,         "Task: Running task for" }, | ||||
| 	{ ST_SCHED_SERVING,    "Scheduler: Serving tasks" }, | ||||
| 	{ ST_SCHED_ADDING,     "Scheduler: Adding ready tasks" }, | ||||
| 	{ ST_SCHED_PROCESSING, "Scheduler: Processing ready tasks" }, | ||||
| 	{ ST_DEP_REG,          "Dependency: Registering" }, | ||||
| 	{ ST_DEP_UNREG,        "Dependency: Unregistering" }, | ||||
| 	{ ST_BLK_TASKWAIT,     "Blocking: Taskwait" }, | ||||
| 	{ ST_BLK_BLOCKING,     "Blocking: Blocking current task" }, | ||||
| 	{ ST_BLK_UNBLOCKING,   "Blocking: Unblocking remote task" }, | ||||
| 	{ ST_BLK_WAITFOR,      "Blocking: Wait for deadline" }, | ||||
| 	{ ST_HANDLING_TASK,    "Worker: Handling task" }, | ||||
| 	{ ST_WORKER_LOOP,      "Worker: Looking for work" }, | ||||
| 	{ ST_SWITCH_TO,        "Worker: Switching to another thread" }, | ||||
| 	{ ST_MIGRATE,          "Worker: Migrating CPU" }, | ||||
| 	{ ST_SUSPEND,          "Worker: Suspending thread" }, | ||||
| 	{ ST_RESUME,           "Worker: Resuming another thread" }, | ||||
| 	{ ST_ALLOCATING,       "Memory: Allocating" }, | ||||
| 	{ ST_FREEING,          "Memory: Freeing" }, | ||||
| 
 | ||||
| 	{ EV_SCHED_SEND,       "EV Scheduler: Send task" }, | ||||
| 	{ EV_SCHED_RECV,       "EV Scheduler: Recv task" }, | ||||
| 	{ EV_SCHED_SELF,       "EV Scheduler: Self-assign task" }, | ||||
| 	{ EV_CPU_IDLE,         "EV CPU: Becomes idle" }, | ||||
| 	{ EV_CPU_ACTIVE,       "EV CPU: Becomes active" }, | ||||
| 	{ EV_SIGNAL,           "EV Worker: Wakening another thread" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| static const struct pcf_value_label nanos6_thread_type[] = { | ||||
| 	{ ST_TH_EXTERNAL,   "External" }, | ||||
| 	{ ST_TH_WORKER,     "Worker" }, | ||||
| 	{ ST_TH_LEADER,     "Leader" }, | ||||
| 	{ ST_TH_MAIN,       "Main" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| static const struct pcf_value_label (*pcf_chan_value_labels[CH_MAX])[] = { | ||||
| 	[CH_SUBSYSTEM] = &nanos6_ss_values, | ||||
| 	[CH_THREAD]    = &nanos6_thread_type, | ||||
| }; | ||||
| 
 | ||||
| /* ------------------------------ pcf ------------------------------ */ | ||||
| 
 | ||||
| static int | ||||
| create_values(struct pcf_type *t, int c) | ||||
| { | ||||
| 	const struct pcf_value_label(*q)[] = pcf_chan_value_labels[c]; | ||||
| 
 | ||||
| 	if (q == NULL) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	for (const struct pcf_value_label *p = *q; p->label != NULL; p++) | ||||
| 		pcf_add_value(t, p->value, p->label); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| create_type(struct pcf *pcf, enum nanos6_chan c, enum nanos6_chan_type ct) | ||||
| { | ||||
| 	long type = pvt_type[c]; | ||||
| 
 | ||||
| 	if (type == -1) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Compute the label by joining the two parts */ | ||||
| 	const char *prefix = pcf_prefix[c]; | ||||
| 	int track_mode = chan_track[c][ct]; | ||||
| 	const char *suffix = pcf_suffix[track_mode]; | ||||
| 
 | ||||
| 	char label[MAX_PCF_LABEL]; | ||||
| 	int ret = snprintf(label, MAX_PCF_LABEL, "%s %s", | ||||
| 			prefix, suffix); | ||||
| 
 | ||||
| 	if (ret >= MAX_PCF_LABEL) { | ||||
| 		err("computed type label too long"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	struct pcf_type *pcftype = pcf_add_type(pcf, type, label); | ||||
| 
 | ||||
| 	return create_values(pcftype, c); | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| init_pcf(struct pcf *pcf, enum nanos6_chan_type ct) | ||||
| { | ||||
| 	/* Create default types and values */ | ||||
| 	for (enum nanos6_chan c = 0; c < CH_MAX; c++) { | ||||
| 		if (create_type(pcf, c, ct) != 0) { | ||||
| 			err("create_type failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* ------------------------------ prv ------------------------------ */ | ||||
| 
 | ||||
| static int | ||||
| connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv) | ||||
| { | ||||
| 	struct nanos6_thread *th = EXT(thread, '6'); | ||||
| 	for (int i = 0; i < CH_MAX; i++) { | ||||
| 		struct chan *out = th->ch_out[i]; | ||||
| 		long type = pvt_type[i]; | ||||
| 		long row = thread->gindex; | ||||
| 		if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { | ||||
| 			err("prv_register failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv) | ||||
| { | ||||
| 	struct nanos6_cpu *cpu = EXT(scpu, '6'); | ||||
| 	for (int i = 0; i < CH_MAX; i++) { | ||||
| 		struct chan *out = &cpu->ch[i]; | ||||
| 		long type = pvt_type[i]; | ||||
| 		long row = scpu->gindex; | ||||
| 		if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { | ||||
| 			err("prv_register failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_threads(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| 	/* Get thread PRV */ | ||||
| 	struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread"); | ||||
| 	if (pvt == NULL) { | ||||
| 		err("cannot find thread pvt"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Connect thread channels to PRV */ | ||||
| 	struct prv *prv = pvt_get_prv(pvt); | ||||
| 	for (struct thread *t = sys->threads; t; t = t->gnext) { | ||||
| 		if (connect_thread_prv(emu, t, prv) != 0) { | ||||
| 			err("connect_thread_prv failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init thread PCF */ | ||||
| 	struct pcf *pcf = pvt_get_pcf(pvt); | ||||
| 	if (init_pcf(pcf, CT_TH) != 0) { | ||||
| 		err("init_pcf failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| connect_cpus(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| 	/* Get cpu PRV */ | ||||
| 	struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu"); | ||||
| 	if (pvt == NULL) { | ||||
| 		err("cannot find cpu pvt"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Connect CPU channels to PRV */ | ||||
| 	struct prv *prv = pvt_get_prv(pvt); | ||||
| 	for (struct cpu *c = sys->cpus; c; c = c->next) { | ||||
| 		if (connect_cpu_prv(emu, c, prv) != 0) { | ||||
| 			err("connect_cpu_prv failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init CPU PCF */ | ||||
| 	struct pcf *pcf = pvt_get_pcf(pvt); | ||||
| 	if (init_pcf(pcf, CT_CPU) != 0) { | ||||
| 		err("init_pcf failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Connect all outputs to the paraver trace and setup PCF types */ | ||||
| int | ||||
| init_pvt(struct emu *emu) | ||||
| { | ||||
| 	if (connect_threads(emu) != 0) { | ||||
| 		err("connect_threads failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (connect_cpus(emu) != 0) { | ||||
| 		err("connect_cpus failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -21,16 +21,25 @@ main(int argc, char *argv[]) | ||||
| 	if (emu_connect(emu) != 0) | ||||
| 		die("emu_connect failed\n"); | ||||
| 
 | ||||
| 	err("emulation starts\n"); | ||||
| 	err("emulation starts"); | ||||
| 	int ret = 0; | ||||
| 	while ((ret = emu_step(emu)) == 0); | ||||
| 
 | ||||
| 	if (ret < 0) | ||||
| 		die("emu_step failed\n"); | ||||
| 	if (ret < 0) { | ||||
| 		err("emu_step failed"); | ||||
| 		ret = 1; | ||||
| 		/* continue to close the trace files */ | ||||
| 		err("emulation aborts!"); | ||||
| 	} else { | ||||
| 		err("emulation ends"); | ||||
| 	} | ||||
| 
 | ||||
| 	err("emulation ends\n"); | ||||
| 	if (emu_finish(emu) != 0) { | ||||
| 		err("emu_finish failed"); | ||||
| 		ret = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	free(emu); | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
							
								
								
									
										473
									
								
								src/emu/pcf.c
									
									
									
									
									
								
							
							
						
						
									
										473
									
								
								src/emu/pcf.c
									
									
									
									
									
								
							| @ -2,9 +2,8 @@ | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "pcf.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include <errno.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| @ -69,210 +68,210 @@ const uint32_t pcf_def_palette[] = { | ||||
| const uint32_t *pcf_palette = pcf_def_palette; | ||||
| const int pcf_palette_len = ARRAY_LEN(pcf_def_palette); | ||||
| 
 | ||||
| /* ------------------ Value labels --------------------- */ | ||||
| 
 | ||||
| struct pcf_value_label default_values[] = { | ||||
| 	{ ST_TOO_MANY_TH, "Unknown: Multiple threads running" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label ovni_state_values[] = { | ||||
| 	{ TH_ST_UNKNOWN, "Unknown" }, | ||||
| 	{ TH_ST_RUNNING, "Running" }, | ||||
| 	{ TH_ST_PAUSED,  "Paused"  }, | ||||
| 	{ TH_ST_DEAD,    "Dead"    }, | ||||
| 	{ TH_ST_COOLING, "Cooling" }, | ||||
| 	{ TH_ST_WARMING, "Warming" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label ovni_flush_values[] = { | ||||
| 	{ 0, "None" }, | ||||
| 	{ ST_OVNI_FLUSHING, "Flushing" }, | ||||
| 	{ ST_TOO_MANY_TH, "Unknown flushing state: Multiple threads running" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label nosv_ss_values[] = { | ||||
| 	/* Errors */ | ||||
| 	{ ST_BAD,                       "Unknown: bad happened (report bug)" }, | ||||
| 	{ ST_TOO_MANY_TH,               "Unknown: multiple threads running" }, | ||||
| 	/* Good values */ | ||||
| 	{ ST_NULL,                      "No subsystem" }, | ||||
| 	{ ST_NOSV_SCHED_HUNGRY,         "Scheduler: Hungry" }, | ||||
| 	{ ST_NOSV_SCHED_SERVING,        "Scheduler: Serving" }, | ||||
| 	{ ST_NOSV_SCHED_SUBMITTING,     "Scheduler: Submitting" }, | ||||
| 	{ ST_NOSV_MEM_ALLOCATING,       "Memory: Allocating" }, | ||||
| 	{ ST_NOSV_MEM_FREEING,          "Memory: Freeing" }, | ||||
| 	{ ST_NOSV_TASK_RUNNING,         "Task: Running" }, | ||||
| 	{ ST_NOSV_API_SUBMIT,           "API: Submit" }, | ||||
| 	{ ST_NOSV_API_PAUSE,            "API: Pause" }, | ||||
| 	{ ST_NOSV_API_YIELD,            "API: Yield" }, | ||||
| 	{ ST_NOSV_API_WAITFOR,          "API: Waitfor" }, | ||||
| 	{ ST_NOSV_API_SCHEDPOINT,       "API: Scheduling point" }, | ||||
| 	{ ST_NOSV_ATTACH,               "Thread: Attached" }, | ||||
| 	{ ST_NOSV_WORKER,               "Thread: Worker" }, | ||||
| 	{ ST_NOSV_DELEGATE,             "Thread: Delegate" }, | ||||
| 	{ EV_NOSV_SCHED_SEND,           "EV Scheduler: Send task" }, | ||||
| 	{ EV_NOSV_SCHED_RECV,           "EV Scheduler: Recv task" }, | ||||
| 	{ EV_NOSV_SCHED_SELF,           "EV Scheduler: Self-assign task" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label nodes_mode_values[] = { | ||||
| 	{ ST_NULL,              "NULL" }, | ||||
| 	{ ST_TOO_MANY_TH,       "NODES: Multiple threads running" }, | ||||
| 	{ ST_NODES_REGISTER,    "Dependencies: Registering task accesses" }, | ||||
| 	{ ST_NODES_UNREGISTER,  "Dependencies: Unregistering task accesses" }, | ||||
| 	{ ST_NODES_IF0_WAIT,    "If0: Waiting for an If0 task" }, | ||||
| 	{ ST_NODES_IF0_INLINE,  "If0: Executing an If0 task inline" }, | ||||
| 	{ ST_NODES_TASKWAIT,    "Taskwait: Taskwait" }, | ||||
| 	{ ST_NODES_CREATE,      "Add Task: Creating a task" }, | ||||
| 	{ ST_NODES_SUBMIT,      "Add Task: Submitting a task" }, | ||||
| 	{ ST_NODES_SPAWN,       "Spawn Function: Spawning a function" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label kernel_cs_values[] = { | ||||
| 	{ ST_NULL,              "NULL" }, | ||||
| 	{ ST_TOO_MANY_TH,       "Unknown: multiple threads running" }, | ||||
| 	{ ST_KERNEL_CSOUT,      "Context switch: Out of the CPU" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label nanos6_ss_values[] = { | ||||
| 	{ ST_NULL,                    "No subsystem" }, | ||||
| 	{ ST_TOO_MANY_TH,             "Unknown: multiple threads running" }, | ||||
| 	{ ST_NANOS6_TASK_BODY,        "Task: Running body" }, | ||||
| 	{ ST_NANOS6_TASK_CREATING,    "Task: Creating" }, | ||||
| 	{ ST_NANOS6_TASK_SUBMIT,      "Task: Submitting" }, | ||||
| 	{ ST_NANOS6_TASK_SPAWNING,    "Task: Spawning function" }, | ||||
| 	{ ST_NANOS6_TASK_FOR,         "Task: Running task for" }, | ||||
| 	{ ST_NANOS6_SCHED_SERVING,    "Scheduler: Serving tasks" }, | ||||
| 	{ ST_NANOS6_SCHED_ADDING,     "Scheduler: Adding ready tasks" }, | ||||
| 	{ ST_NANOS6_SCHED_PROCESSING, "Scheduler: Processing ready tasks" }, | ||||
| 	{ ST_NANOS6_DEP_REG,          "Dependency: Registering" }, | ||||
| 	{ ST_NANOS6_DEP_UNREG,        "Dependency: Unregistering" }, | ||||
| 	{ ST_NANOS6_BLK_TASKWAIT,     "Blocking: Taskwait" }, | ||||
| 	{ ST_NANOS6_BLK_BLOCKING,     "Blocking: Blocking current task" }, | ||||
| 	{ ST_NANOS6_BLK_UNBLOCKING,   "Blocking: Unblocking remote task" }, | ||||
| 	{ ST_NANOS6_BLK_WAITFOR,      "Blocking: Wait for deadline" }, | ||||
| 	{ ST_NANOS6_HANDLING_TASK,    "Worker: Handling task" }, | ||||
| 	{ ST_NANOS6_WORKER_LOOP,      "Worker: Looking for work" }, | ||||
| 	{ ST_NANOS6_SWITCH_TO,        "Worker: Switching to another thread" }, | ||||
| 	{ ST_NANOS6_MIGRATE,          "Worker: Migrating CPU" }, | ||||
| 	{ ST_NANOS6_SUSPEND,          "Worker: Suspending thread" }, | ||||
| 	{ ST_NANOS6_RESUME,           "Worker: Resuming another thread" }, | ||||
| 	{ ST_NANOS6_ALLOCATING,       "Memory: Allocating" }, | ||||
| 	{ ST_NANOS6_FREEING,          "Memory: Freeing" }, | ||||
| 	{ 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" }, | ||||
| 	{ EV_NANOS6_CPU_IDLE,         "EV CPU: Becomes idle" }, | ||||
| 	{ EV_NANOS6_CPU_ACTIVE,       "EV CPU: Becomes active" }, | ||||
| 	{ EV_NANOS6_SIGNAL,           "EV Worker: Wakening another thread" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label nanos6_thread_type[] = { | ||||
| 	{ ST_NULL,                 "No type" }, | ||||
| 	{ ST_TOO_MANY_TH,          "Unknown: multiple threads running" }, | ||||
| 	{ ST_NANOS6_TH_EXTERNAL,   "External" }, | ||||
| 	{ ST_NANOS6_TH_WORKER,     "Worker" }, | ||||
| 	{ ST_NANOS6_TH_LEADER,     "Leader" }, | ||||
| 	{ ST_NANOS6_TH_MAIN,       "Main" }, | ||||
| 	{ -1, NULL }, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = { | ||||
| 	[CHAN_OVNI_PID]         = &default_values, | ||||
| 	[CHAN_OVNI_TID]         = &default_values, | ||||
| 	[CHAN_OVNI_NRTHREADS]   = &default_values, | ||||
| 	[CHAN_OVNI_STATE]       = &ovni_state_values, | ||||
| 	[CHAN_OVNI_APPID]       = &default_values, | ||||
| 	[CHAN_OVNI_CPU]         = &default_values, | ||||
| 	[CHAN_OVNI_FLUSH]       = &ovni_flush_values, | ||||
| 
 | ||||
| 	[CHAN_NOSV_TASKID]      = &default_values, | ||||
| 	[CHAN_NOSV_TYPE]        = &default_values, | ||||
| 	[CHAN_NOSV_APPID]       = &default_values, | ||||
| 	[CHAN_NOSV_SUBSYSTEM]   = &nosv_ss_values, | ||||
| 	[CHAN_NOSV_RANK]        = &default_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_NANOS6_THREAD]    = &nanos6_thread_type, | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = &kernel_cs_values, | ||||
| }; | ||||
| 
 | ||||
| /* ------------------ Type labels --------------------- */ | ||||
| 
 | ||||
| char *pcf_chan_name[CHAN_MAX] = { | ||||
| 	[CHAN_OVNI_PID]         = "PID", | ||||
| 	[CHAN_OVNI_TID]         = "TID", | ||||
| 	[CHAN_OVNI_NRTHREADS]   = "Number of RUNNING threads", | ||||
| 	[CHAN_OVNI_STATE]       = "Execution state", | ||||
| 	[CHAN_OVNI_APPID]       = "AppID", | ||||
| 	[CHAN_OVNI_CPU]         = "CPU affinity", | ||||
| 	[CHAN_OVNI_FLUSH]       = "Flushing state", | ||||
| 
 | ||||
| 	[CHAN_NOSV_TASKID]      = "nOS-V TaskID", | ||||
| 	[CHAN_NOSV_TYPE]        = "nOS-V task type", | ||||
| 	[CHAN_NOSV_APPID]       = "nOS-V task AppID", | ||||
| 	[CHAN_NOSV_SUBSYSTEM]   = "nOS-V subsystem", | ||||
| 	[CHAN_NOSV_RANK]        = "nOS-V task MPI rank", | ||||
| 
 | ||||
| 	[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_NANOS6_THREAD]    = "Nanos6 thread type", | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = "Context switches", | ||||
| }; | ||||
| 
 | ||||
| enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX }; | ||||
| 
 | ||||
| char *pcf_suffix_name[SUFFIX_MAX] = { | ||||
| 	[NONE] = "", | ||||
| 	[CUR_TH] = "of the CURRENT thread", | ||||
| 	[RUN_TH] = "of the RUNNING thread", | ||||
| 	[ACT_TH] = "of the ACTIVE thread", | ||||
| }; | ||||
| 
 | ||||
| int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = { | ||||
| 	                        /*  Thread  CPU  */ | ||||
| 	[CHAN_OVNI_PID]         = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_OVNI_TID]         = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_OVNI_NRTHREADS]   = { NONE,   NONE   }, | ||||
| 	[CHAN_OVNI_STATE]       = { CUR_TH, NONE   }, | ||||
| 	[CHAN_OVNI_APPID]       = { NONE,   RUN_TH }, | ||||
| 	[CHAN_OVNI_CPU]         = { CUR_TH, NONE   }, | ||||
| 	[CHAN_OVNI_FLUSH]       = { CUR_TH, RUN_TH }, | ||||
| 
 | ||||
| 	[CHAN_NOSV_TASKID]      = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_NOSV_TYPE]        = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_NOSV_APPID]       = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_NOSV_SUBSYSTEM]   = { ACT_TH, RUN_TH }, | ||||
| 	[CHAN_NOSV_RANK]        = { 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_NANOS6_THREAD]    = { RUN_TH, NONE   }, | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = { RUN_TH, ACT_TH }, | ||||
| }; | ||||
| ///* ------------------ Value labels --------------------- */
 | ||||
| //
 | ||||
| //struct pcf_value_label default_values[] = {
 | ||||
| //	{ ST_TOO_MANY_TH, "Unknown: Multiple threads running" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label ovni_state_values[] = {
 | ||||
| //	{ TH_ST_UNKNOWN, "Unknown" },
 | ||||
| //	{ TH_ST_RUNNING, "Running" },
 | ||||
| //	{ TH_ST_PAUSED,  "Paused"  },
 | ||||
| //	{ TH_ST_DEAD,    "Dead"    },
 | ||||
| //	{ TH_ST_COOLING, "Cooling" },
 | ||||
| //	{ TH_ST_WARMING, "Warming" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label ovni_flush_values[] = {
 | ||||
| //	{ 0, "None" },
 | ||||
| //	{ ST_OVNI_FLUSHING, "Flushing" },
 | ||||
| //	{ ST_TOO_MANY_TH, "Unknown flushing state: Multiple threads running" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label nosv_ss_values[] = {
 | ||||
| //	/* Errors */
 | ||||
| //	{ ST_BAD,                       "Unknown: bad happened (report bug)" },
 | ||||
| //	{ ST_TOO_MANY_TH,               "Unknown: multiple threads running" },
 | ||||
| //	/* Good values */
 | ||||
| //	{ ST_NULL,                      "No subsystem" },
 | ||||
| //	{ ST_NOSV_SCHED_HUNGRY,         "Scheduler: Hungry" },
 | ||||
| //	{ ST_NOSV_SCHED_SERVING,        "Scheduler: Serving" },
 | ||||
| //	{ ST_NOSV_SCHED_SUBMITTING,     "Scheduler: Submitting" },
 | ||||
| //	{ ST_NOSV_MEM_ALLOCATING,       "Memory: Allocating" },
 | ||||
| //	{ ST_NOSV_MEM_FREEING,          "Memory: Freeing" },
 | ||||
| //	{ ST_NOSV_TASK_RUNNING,         "Task: Running" },
 | ||||
| //	{ ST_NOSV_API_SUBMIT,           "API: Submit" },
 | ||||
| //	{ ST_NOSV_API_PAUSE,            "API: Pause" },
 | ||||
| //	{ ST_NOSV_API_YIELD,            "API: Yield" },
 | ||||
| //	{ ST_NOSV_API_WAITFOR,          "API: Waitfor" },
 | ||||
| //	{ ST_NOSV_API_SCHEDPOINT,       "API: Scheduling point" },
 | ||||
| //	{ ST_NOSV_ATTACH,               "Thread: Attached" },
 | ||||
| //	{ ST_NOSV_WORKER,               "Thread: Worker" },
 | ||||
| //	{ ST_NOSV_DELEGATE,             "Thread: Delegate" },
 | ||||
| //	{ EV_NOSV_SCHED_SEND,           "EV Scheduler: Send task" },
 | ||||
| //	{ EV_NOSV_SCHED_RECV,           "EV Scheduler: Recv task" },
 | ||||
| //	{ EV_NOSV_SCHED_SELF,           "EV Scheduler: Self-assign task" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label nodes_mode_values[] = {
 | ||||
| //	{ ST_NULL,              "NULL" },
 | ||||
| //	{ ST_TOO_MANY_TH,       "NODES: Multiple threads running" },
 | ||||
| //	{ ST_NODES_REGISTER,    "Dependencies: Registering task accesses" },
 | ||||
| //	{ ST_NODES_UNREGISTER,  "Dependencies: Unregistering task accesses" },
 | ||||
| //	{ ST_NODES_IF0_WAIT,    "If0: Waiting for an If0 task" },
 | ||||
| //	{ ST_NODES_IF0_INLINE,  "If0: Executing an If0 task inline" },
 | ||||
| //	{ ST_NODES_TASKWAIT,    "Taskwait: Taskwait" },
 | ||||
| //	{ ST_NODES_CREATE,      "Add Task: Creating a task" },
 | ||||
| //	{ ST_NODES_SUBMIT,      "Add Task: Submitting a task" },
 | ||||
| //	{ ST_NODES_SPAWN,       "Spawn Function: Spawning a function" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label kernel_cs_values[] = {
 | ||||
| //	{ ST_NULL,              "NULL" },
 | ||||
| //	{ ST_TOO_MANY_TH,       "Unknown: multiple threads running" },
 | ||||
| //	{ ST_KERNEL_CSOUT,      "Context switch: Out of the CPU" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label nanos6_ss_values[] = {
 | ||||
| //	{ ST_NULL,                    "No subsystem" },
 | ||||
| //	{ ST_TOO_MANY_TH,             "Unknown: multiple threads running" },
 | ||||
| //	{ ST_NANOS6_TASK_BODY,        "Task: Running body" },
 | ||||
| //	{ ST_NANOS6_TASK_CREATING,    "Task: Creating" },
 | ||||
| //	{ ST_NANOS6_TASK_SUBMIT,      "Task: Submitting" },
 | ||||
| //	{ ST_NANOS6_TASK_SPAWNING,    "Task: Spawning function" },
 | ||||
| //	{ ST_NANOS6_TASK_FOR,         "Task: Running task for" },
 | ||||
| //	{ ST_NANOS6_SCHED_SERVING,    "Scheduler: Serving tasks" },
 | ||||
| //	{ ST_NANOS6_SCHED_ADDING,     "Scheduler: Adding ready tasks" },
 | ||||
| //	{ ST_NANOS6_SCHED_PROCESSING, "Scheduler: Processing ready tasks" },
 | ||||
| //	{ ST_NANOS6_DEP_REG,          "Dependency: Registering" },
 | ||||
| //	{ ST_NANOS6_DEP_UNREG,        "Dependency: Unregistering" },
 | ||||
| //	{ ST_NANOS6_BLK_TASKWAIT,     "Blocking: Taskwait" },
 | ||||
| //	{ ST_NANOS6_BLK_BLOCKING,     "Blocking: Blocking current task" },
 | ||||
| //	{ ST_NANOS6_BLK_UNBLOCKING,   "Blocking: Unblocking remote task" },
 | ||||
| //	{ ST_NANOS6_BLK_WAITFOR,      "Blocking: Wait for deadline" },
 | ||||
| //	{ ST_NANOS6_HANDLING_TASK,    "Worker: Handling task" },
 | ||||
| //	{ ST_NANOS6_WORKER_LOOP,      "Worker: Looking for work" },
 | ||||
| //	{ ST_NANOS6_SWITCH_TO,        "Worker: Switching to another thread" },
 | ||||
| //	{ ST_NANOS6_MIGRATE,          "Worker: Migrating CPU" },
 | ||||
| //	{ ST_NANOS6_SUSPEND,          "Worker: Suspending thread" },
 | ||||
| //	{ ST_NANOS6_RESUME,           "Worker: Resuming another thread" },
 | ||||
| //	{ ST_NANOS6_ALLOCATING,       "Memory: Allocating" },
 | ||||
| //	{ ST_NANOS6_FREEING,          "Memory: Freeing" },
 | ||||
| //	{ 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" },
 | ||||
| //	{ EV_NANOS6_CPU_IDLE,         "EV CPU: Becomes idle" },
 | ||||
| //	{ EV_NANOS6_CPU_ACTIVE,       "EV CPU: Becomes active" },
 | ||||
| //	{ EV_NANOS6_SIGNAL,           "EV Worker: Wakening another thread" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label nanos6_thread_type[] = {
 | ||||
| //	{ ST_NULL,                 "No type" },
 | ||||
| //	{ ST_TOO_MANY_TH,          "Unknown: multiple threads running" },
 | ||||
| //	{ ST_NANOS6_TH_EXTERNAL,   "External" },
 | ||||
| //	{ ST_NANOS6_TH_WORKER,     "Worker" },
 | ||||
| //	{ ST_NANOS6_TH_LEADER,     "Leader" },
 | ||||
| //	{ ST_NANOS6_TH_MAIN,       "Main" },
 | ||||
| //	{ -1, NULL },
 | ||||
| //};
 | ||||
| //
 | ||||
| //struct pcf_value_label (*pcf_chan_value_labels[CHAN_MAX])[] = {
 | ||||
| //	[CHAN_OVNI_PID]         = &default_values,
 | ||||
| //	[CHAN_OVNI_TID]         = &default_values,
 | ||||
| //	[CHAN_OVNI_NRTHREADS]   = &default_values,
 | ||||
| //	[CHAN_OVNI_STATE]       = &ovni_state_values,
 | ||||
| //	[CHAN_OVNI_APPID]       = &default_values,
 | ||||
| //	[CHAN_OVNI_CPU]         = &default_values,
 | ||||
| //	[CHAN_OVNI_FLUSH]       = &ovni_flush_values,
 | ||||
| //
 | ||||
| //	[CHAN_NOSV_TASKID]      = &default_values,
 | ||||
| //	[CHAN_NOSV_TYPE]        = &default_values,
 | ||||
| //	[CHAN_NOSV_APPID]       = &default_values,
 | ||||
| //	[CHAN_NOSV_SUBSYSTEM]   = &nosv_ss_values,
 | ||||
| //	[CHAN_NOSV_RANK]        = &default_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_NANOS6_THREAD]    = &nanos6_thread_type,
 | ||||
| //
 | ||||
| //	[CHAN_KERNEL_CS]        = &kernel_cs_values,
 | ||||
| //};
 | ||||
| //
 | ||||
| ///* ------------------ Type labels --------------------- */
 | ||||
| //
 | ||||
| //char *pcf_chan_name[CHAN_MAX] = {
 | ||||
| //	[CHAN_OVNI_PID]         = "PID",
 | ||||
| //	[CHAN_OVNI_TID]         = "TID",
 | ||||
| //	[CHAN_OVNI_NRTHREADS]   = "Number of RUNNING threads",
 | ||||
| //	[CHAN_OVNI_STATE]       = "Execution state",
 | ||||
| //	[CHAN_OVNI_APPID]       = "AppID",
 | ||||
| //	[CHAN_OVNI_CPU]         = "CPU affinity",
 | ||||
| //	[CHAN_OVNI_FLUSH]       = "Flushing state",
 | ||||
| //
 | ||||
| //	[CHAN_NOSV_TASKID]      = "nOS-V TaskID",
 | ||||
| //	[CHAN_NOSV_TYPE]        = "nOS-V task type",
 | ||||
| //	[CHAN_NOSV_APPID]       = "nOS-V task AppID",
 | ||||
| //	[CHAN_NOSV_SUBSYSTEM]   = "nOS-V subsystem",
 | ||||
| //	[CHAN_NOSV_RANK]        = "nOS-V task MPI rank",
 | ||||
| //
 | ||||
| //	[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_NANOS6_THREAD]    = "Nanos6 thread type",
 | ||||
| //
 | ||||
| //	[CHAN_KERNEL_CS]        = "Context switches",
 | ||||
| //};
 | ||||
| //
 | ||||
| //enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX };
 | ||||
| //
 | ||||
| //char *pcf_suffix_name[SUFFIX_MAX] = {
 | ||||
| //	[NONE] = "",
 | ||||
| //	[CUR_TH] = "of the CURRENT thread",
 | ||||
| //	[RUN_TH] = "of the RUNNING thread",
 | ||||
| //	[ACT_TH] = "of the ACTIVE thread",
 | ||||
| //};
 | ||||
| //
 | ||||
| //int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = {
 | ||||
| //	                        /*  Thread  CPU  */
 | ||||
| //	[CHAN_OVNI_PID]         = { RUN_TH, RUN_TH },
 | ||||
| //	[CHAN_OVNI_TID]         = { RUN_TH, RUN_TH },
 | ||||
| //	[CHAN_OVNI_NRTHREADS]   = { NONE,   NONE   },
 | ||||
| //	[CHAN_OVNI_STATE]       = { CUR_TH, NONE   },
 | ||||
| //	[CHAN_OVNI_APPID]       = { NONE,   RUN_TH },
 | ||||
| //	[CHAN_OVNI_CPU]         = { CUR_TH, NONE   },
 | ||||
| //	[CHAN_OVNI_FLUSH]       = { CUR_TH, RUN_TH },
 | ||||
| //
 | ||||
| //	[CHAN_NOSV_TASKID]      = { RUN_TH, RUN_TH },
 | ||||
| //	[CHAN_NOSV_TYPE]        = { RUN_TH, RUN_TH },
 | ||||
| //	[CHAN_NOSV_APPID]       = { RUN_TH, RUN_TH },
 | ||||
| //	[CHAN_NOSV_SUBSYSTEM]   = { ACT_TH, RUN_TH },
 | ||||
| //	[CHAN_NOSV_RANK]        = { 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_NANOS6_THREAD]    = { RUN_TH, NONE   },
 | ||||
| //
 | ||||
| //	[CHAN_KERNEL_CS]        = { RUN_TH, ACT_TH },
 | ||||
| //};
 | ||||
| 
 | ||||
| /* clang-format on */ | ||||
| 
 | ||||
| @ -324,61 +323,20 @@ write_types(struct pcf *pcf) | ||||
| 		write_type(pcf->f, t); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| create_values(struct pcf_type *t, enum chan c) | ||||
| { | ||||
| 	struct pcf_value_label(*q)[] = pcf_chan_value_labels[c]; | ||||
| 
 | ||||
| 	if (q == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (struct pcf_value_label *p = *q; p->label != NULL; p++) | ||||
| 		pcf_add_value(t, p->value, p->label); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| create_type(struct pcf *pcf, enum chan c) | ||||
| { | ||||
| 	enum chan_type ct = pcf->chantype; | ||||
| 	int prv_type = chan_to_prvtype[c]; | ||||
| 
 | ||||
| 	if (prv_type == -1) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* Compute the label by joining the two parts */ | ||||
| 	char *prefix = pcf_chan_name[c]; | ||||
| 	int isuffix = pcf_chan_suffix[c][ct]; | ||||
| 	char *suffix = pcf_suffix_name[isuffix]; | ||||
| 
 | ||||
| 	char label[MAX_PCF_LABEL]; | ||||
| 	int ret = snprintf(label, MAX_PCF_LABEL, "%s %s", | ||||
| 			prefix, suffix); | ||||
| 
 | ||||
| 	if (ret >= MAX_PCF_LABEL) | ||||
| 		die("computed type label too long\n"); | ||||
| 
 | ||||
| 	struct pcf_type *t = pcf_add_type(pcf, prv_type, label); | ||||
| 
 | ||||
| 	create_values(t, c); | ||||
| } | ||||
| 
 | ||||
| /** Open the given PCF file and create the default events. */ | ||||
| void | ||||
| pcf_open(struct pcf *pcf, char *path, int chantype) | ||||
| int | ||||
| pcf_open(struct pcf *pcf, char *path) | ||||
| { | ||||
| 	memset(pcf, 0, sizeof(*pcf)); | ||||
| 
 | ||||
| 	pcf->f = fopen(path, "w"); | ||||
| 	pcf->chantype = chantype; | ||||
| 
 | ||||
| 	if (pcf->f == NULL) { | ||||
| 		die("cannot open PCF file '%s': %s\n", | ||||
| 				path, strerror(errno)); | ||||
| 		err("cannot open PCF file '%s':", path); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Create default types and values */ | ||||
| 	for (enum chan c = 0; c < CHAN_MAX; c++) | ||||
| 		create_type(pcf, c); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| struct pcf_type * | ||||
| @ -461,17 +419,14 @@ pcf_add_value(struct pcf_type *type, int value, const char *label) | ||||
| 	return pcfvalue; | ||||
| } | ||||
| 
 | ||||
| /** Writes the defined event and values to the PCF file. */ | ||||
| void | ||||
| pcf_write(struct pcf *pcf) | ||||
| /** Writes the defined event and values to the PCF file and closes the file. */ | ||||
| int | ||||
| pcf_close(struct pcf *pcf) | ||||
| { | ||||
| 	write_header(pcf->f); | ||||
| 	write_colors(pcf->f, pcf_palette, pcf_palette_len); | ||||
| 	write_types(pcf); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| pcf_close(struct pcf *pcf) | ||||
| { | ||||
| 	fclose(pcf->f); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,6 @@ struct pcf_type { | ||||
| 
 | ||||
| struct pcf { | ||||
| 	FILE *f; | ||||
| 	int chantype; | ||||
| 	int pcf_ntypes; | ||||
| 	struct pcf_type *types; | ||||
| }; | ||||
| @ -42,22 +41,12 @@ struct pcf_value_label { | ||||
| 	char *label; | ||||
| }; | ||||
| 
 | ||||
| extern struct pcf_value_label nanos6_ss_values[]; | ||||
| 
 | ||||
| void pcf_open(struct pcf *pcf, char *path, int chantype); | ||||
| 
 | ||||
| void pcf_write(struct pcf *pcf); | ||||
| 
 | ||||
| void pcf_close(struct pcf *pcf); | ||||
| int pcf_open(struct pcf *pcf, char *path); | ||||
| int pcf_close(struct pcf *pcf); | ||||
| 
 | ||||
| struct pcf_type *pcf_find_type(struct pcf *pcf, int type_id); | ||||
| 
 | ||||
| struct pcf_type *pcf_add_type(struct pcf *pcf, int type_id, | ||||
| 		const char *label); | ||||
| 
 | ||||
| struct pcf_value *pcf_add_value(struct pcf_type *type, int value, | ||||
| 		const char *label); | ||||
| 
 | ||||
| struct pcf_type *pcf_add_type(struct pcf *pcf, int type_id, const char *label); | ||||
| struct pcf_value *pcf_add_value(struct pcf_type *type, int value, const char *label); | ||||
| struct pcf_value *pcf_find_value(struct pcf_type *type, int value); | ||||
| 
 | ||||
| #endif /* OVNI_PCF_H */ | ||||
|  | ||||
| @ -42,13 +42,14 @@ prv_open(struct prv *prv, long nrows, const char *path) | ||||
| 	return prv_open_file(prv, nrows, f); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| int | ||||
| prv_close(struct prv *prv) | ||||
| { | ||||
| 	/* Fix the header with the current duration */ | ||||
| 	fseek(prv->file, 0, SEEK_SET); | ||||
| 	write_header(prv->file, prv->time, prv->nrows); | ||||
| 	fclose(prv->file); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct prv_chan * | ||||
|  | ||||
| @ -37,6 +37,6 @@ int prv_open(struct prv *prv, long nrows, const char *path); | ||||
| int prv_open_file(struct prv *prv, long nrows, FILE *file); | ||||
| int prv_register(struct prv *prv, long row, long type, struct bay *bay, struct chan *chan, long flags); | ||||
| int prv_advance(struct prv *prv, int64_t time); | ||||
| void prv_close(struct prv *prv); | ||||
| int prv_close(struct prv *prv); | ||||
| 
 | ||||
| #endif /* PRV_H */ | ||||
|  | ||||
| @ -26,6 +26,17 @@ pvt_open(struct pvt *pvt, long nrows, const char *dir, const char *name) | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	char pcfpath[PATH_MAX]; | ||||
| 	if (snprintf(pcfpath, PATH_MAX, "%s/%s.pcf", dir, name) >= PATH_MAX) { | ||||
| 		err("snprintf failed: path too long"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	 | ||||
| 	if (pcf_open(&pvt->pcf, pcfpath) != 0) { | ||||
| 		err("pcf_open failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -35,8 +46,30 @@ pvt_get_prv(struct pvt *pvt) | ||||
| 	return &pvt->prv; | ||||
| } | ||||
| 
 | ||||
| struct pcf * | ||||
| pvt_get_pcf(struct pvt *pvt) | ||||
| { | ||||
| 	return &pvt->pcf; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| pvt_advance(struct pvt *pvt, int64_t time) | ||||
| { | ||||
| 	return prv_advance(&pvt->prv, time); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| pvt_close(struct pvt *pvt) | ||||
| { | ||||
| 	if (prv_close(&pvt->prv) != 0) { | ||||
| 		err("prv_close failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (pcf_close(&pvt->pcf) != 0) { | ||||
| 		err("pcf_close failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -22,5 +22,6 @@ int pvt_open(struct pvt *pvt, long nrows, const char *dir, const char *name); | ||||
| struct prv *pvt_get_prv(struct pvt *pvt); | ||||
| struct pcf *pvt_get_pcf(struct pvt *pvt); | ||||
| int pvt_advance(struct pvt *pvt, int64_t time); | ||||
| int pvt_close(struct pvt *pvt); | ||||
| 
 | ||||
| #endif /* PVT_H */ | ||||
|  | ||||
| @ -64,3 +64,16 @@ recorder_advance(struct recorder *rec, int64_t time) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| recorder_finish(struct recorder *rec) | ||||
| { | ||||
| 	for (struct pvt *pvt = rec->pvt; pvt; pvt = pvt->hh.next) { | ||||
| 		if (pvt_close(pvt) != 0) { | ||||
| 			err("pvt_close failed"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -19,5 +19,6 @@ int recorder_init(struct recorder *rec, const char *dir); | ||||
| struct pvt *recorder_find_pvt(struct recorder *rec, const char *name); | ||||
| struct pvt *recorder_add_pvt(struct recorder *rec, const char *name, long nrows); | ||||
| int recorder_advance(struct recorder *rec, int64_t time); | ||||
| int recorder_finish(struct recorder *rec); | ||||
| 
 | ||||
| #endif /* RECORDER_H */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user