Finish task types in PCF for nanos6
This commit is contained in:
		
							parent
							
								
									dbea90f525
								
							
						
					
					
						commit
						a91b1c554a
					
				| @ -43,6 +43,7 @@ add_library(emu STATIC | ||||
|   nanos6/create.c | ||||
|   nanos6/event.c | ||||
|   nanos6/pvt.c | ||||
|   nanos6/finish.c | ||||
| ) | ||||
| 
 | ||||
| add_executable(ovniemu ovniemu.c) | ||||
|  | ||||
| @ -160,9 +160,15 @@ emu_step(struct emu *emu) | ||||
| int | ||||
| emu_finish(struct emu *emu) | ||||
| { | ||||
| 	if (model_finish(&emu->model, emu) != 0) { | ||||
| 		err("model_finish failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (recorder_finish(&emu->recorder) != 0) { | ||||
| 		err("recorder_finish failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -105,3 +105,22 @@ model_event(struct model *model, struct emu *emu, int index) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| model_finish(struct model *model, struct emu *emu) | ||||
| { | ||||
| 	for (int i = 0; i < MAX_MODELS; i++) { | ||||
| 		if (!model->enabled[i]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		struct model_spec *spec = model->spec[i]; | ||||
| 		if (spec->finish == NULL) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (spec->finish(emu) != 0) { | ||||
| 			err("finish failed for model '%c'", (char) i); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -14,6 +14,7 @@ struct model_spec { | ||||
| 	emu_hook_t *create; | ||||
| 	emu_hook_t *connect; | ||||
| 	emu_hook_t *event; | ||||
| 	emu_hook_t *finish; | ||||
| }; | ||||
| 
 | ||||
| #define MAX_MODELS 256 | ||||
| @ -31,5 +32,6 @@ int model_probe(struct model *model, struct emu *emu); | ||||
| int model_create(struct model *model, struct emu *emu); | ||||
| int model_connect(struct model *model, struct emu *emu); | ||||
| int model_event(struct model *model, struct emu *emu, int index); | ||||
| int model_finish(struct model *model, struct emu *emu); | ||||
| 
 | ||||
| #endif /* MODEL_H */ | ||||
|  | ||||
							
								
								
									
										44
									
								
								src/emu/nanos6/finish.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/emu/nanos6/finish.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| #include "nanos6_priv.h" | ||||
| 
 | ||||
| static int | ||||
| end_lint(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| 	/* Ensure we run out of subsystem states */ | ||||
| 	for (struct thread *t = sys->threads; t; t = t->gnext) { | ||||
| 		struct nanos6_thread *th = EXT(t, '6'); | ||||
| 		struct chan *ch = &th->ch[CH_SUBSYSTEM]; | ||||
| 		int stacked = ch->data.stack.n; | ||||
| 		if (stacked > 0) { | ||||
| 			struct value top; | ||||
| 			if (chan_read(ch, &top) != 0) { | ||||
| 				err("chan_read failed for subsystem"); | ||||
| 				return -1; | ||||
| 			} | ||||
| 
 | ||||
| 			err("thread %d ended with %d stacked nanos6 subsystems, top=\"%s\"\n", | ||||
| 					t->tid, stacked, ss_name(top.i)); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| nanos6_finish(struct emu *emu) | ||||
| { | ||||
| 	if (finish_pvt(emu) != 0) { | ||||
| 		err("finish_pvt failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* When running in linter mode perform additional checks */ | ||||
| 	if (emu->args.linter_mode && end_lint(emu) != 0) { | ||||
| 		err("end_lint failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| @ -98,7 +98,10 @@ int nanos6_probe(struct emu *emu); | ||||
| int nanos6_create(struct emu *emu); | ||||
| int nanos6_connect(struct emu *emu); | ||||
| int nanos6_event(struct emu *emu); | ||||
| int nanos6_finish(struct emu *emu); | ||||
| 
 | ||||
| int init_pvt(struct emu *emu); | ||||
| int finish_pvt(struct emu *emu); | ||||
| const char *ss_name(int ss); | ||||
| 
 | ||||
| #endif /* NANOS6_PRIV_H */ | ||||
|  | ||||
| @ -7,6 +7,7 @@ struct model_spec model_nanos6 = { | ||||
| 	.connect = nanos6_connect, | ||||
| 	.event   = nanos6_event, | ||||
| 	.probe   = nanos6_probe, | ||||
| 	.finish  = nanos6_finish, | ||||
| }; | ||||
| 
 | ||||
| int | ||||
|  | ||||
| @ -1,6 +1,12 @@ | ||||
| #include "nanos6_priv.h" | ||||
| 
 | ||||
| /* TODO: Assign types on runtime and generate configs */ | ||||
| 
 | ||||
| static const char *pvt_name[CT_MAX] = { | ||||
| 	[CT_TH]  = "thread", | ||||
| 	[CT_CPU] = "cpu", | ||||
| }; | ||||
| 
 | ||||
| static const int pvt_type[] = { | ||||
| 	[CH_TASKID]    = 35, | ||||
| 	[CH_TYPE]      = 36, | ||||
| @ -240,3 +246,48 @@ init_pvt(struct emu *emu) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| finish_pvt(struct emu *emu) | ||||
| { | ||||
| 	struct system *sys = &emu->system; | ||||
| 
 | ||||
| 	/* Emit task types for all channel types and processes */ | ||||
| 	for (enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) { | ||||
| 		struct pvt *pvt = recorder_find_pvt(&emu->recorder, pvt_name[ct]); | ||||
| 		if (pvt == NULL) { | ||||
| 			err("cannot find pvt with name '%s'", pvt_name[ct]); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		struct pcf *pcf = pvt_get_pcf(pvt); | ||||
| 		long typeid = pvt_type[CH_TYPE]; | ||||
| 		struct pcf_type *pcftype = pcf_find_type(pcf, typeid); | ||||
| 
 | ||||
| 		for (struct proc *p = sys->procs; p; p = p->gnext) { | ||||
| 			struct nanos6_proc *nanos6proc = EXT(p, '6'); | ||||
| 			struct task_info *info = &nanos6proc->task_info; | ||||
| 			if (task_create_pcf_types(pcftype, info->types) != 0) { | ||||
| 				err("task_create_pcf_types failed"); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| const char * | ||||
| ss_name(int ss) | ||||
| { | ||||
| 	static const char *unknown = "(unknown)"; | ||||
| 	const char *name = unknown; | ||||
| 	const struct pcf_value_label *pv; | ||||
| 	for (pv = &nanos6_ss_values[0]; pv->label; pv++) { | ||||
| 		if (pv->value == ss) { | ||||
| 			name = pv->label; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return name; | ||||
| } | ||||
|  | ||||
| @ -5,6 +5,7 @@ | ||||
| 
 | ||||
| #include "uthash.h" | ||||
| #include "utlist.h" | ||||
| #include "pcf.h" | ||||
| 
 | ||||
| struct task * | ||||
| task_find(struct task *tasks, uint32_t task_id) | ||||
| @ -281,24 +282,31 @@ task_type_create(struct task_info *info, uint32_t type_id, const char *label) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| //void
 | ||||
| //task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types)
 | ||||
| //{
 | ||||
| //	/* Emit types for all task types */
 | ||||
| //	for (struct task_type *tt = 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");
 | ||||
| //			else
 | ||||
| //				continue;
 | ||||
| //		}
 | ||||
| //
 | ||||
| //		pcf_add_value(pcftype, tt->gid, tt->label);
 | ||||
| //	}
 | ||||
| //}
 | ||||
| int | ||||
| task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	/* Emit types for all task types */ | ||||
| 	for (struct task_type *tt = 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) { | ||||
| 				err("collision occurred in task type labels: %s and %s", | ||||
| 						pcfvalue->label, tt->label); | ||||
| 				ret = -1; | ||||
| 			} else { | ||||
| 				continue; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		pcf_add_value(pcftype, tt->gid, tt->label); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| struct task * | ||||
| task_get_running(struct task_stack *stack) | ||||
|  | ||||
| @ -64,7 +64,7 @@ int task_end(struct task_stack *stack, struct task *task); | ||||
| struct task_type *task_type_find(struct task_type *types, uint32_t type_id); | ||||
| int task_type_create(struct task_info *info, uint32_t type_id, const char *label); | ||||
| 
 | ||||
| //void task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types);
 | ||||
| int task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types); | ||||
| struct task *task_get_running(struct task_stack *stack); | ||||
| 
 | ||||
| #endif /* TASK_H */ | ||||
|  | ||||
| @ -7,4 +7,4 @@ ovni_test(nested-tasks-bad.c SHOULD_FAIL | ||||
| ovni_test(task-types.c MP) | ||||
| ovni_test(blocking.c MP) | ||||
| ovni_test(ss-mismatch.c SHOULD_FAIL | ||||
|   REGEX "thread [0-9]\\+ ended with 1 extra stacked nanos6 subsystems, top=\"Worker: Looking for work\"") | ||||
|   REGEX "thread [0-9]\\+ ended with 1 stacked nanos6 subsystems, top=\"Worker: Looking for work\"") | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user