Load thread tid from metadata
This commit is contained in:
		
							parent
							
								
									4ec966cb67
								
							
						
					
					
						commit
						aafaf6e954
					
				| @ -1,4 +1,4 @@ | ||||
| /* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
 | ||||
| /* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "metadata.h" | ||||
| @ -135,25 +135,3 @@ metadata_load_proc(const char *path, struct loom *loom, struct proc *proc) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| metadata_load_thread(const char *path, struct thread *thread) | ||||
| { | ||||
| 	JSON_Object *meta = load_json(path); | ||||
| 	if (meta == NULL) { | ||||
| 		err("cannot load thread metadata from file %s", path); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (check_version(meta) != 0) { | ||||
| 		err("version check failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (thread_load_metadata(thread, meta) != 0) { | ||||
| 		err("cannot load thread attributes"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| /* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC)
 | ||||
| /* Copyright (c) 2021-2024 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #ifndef METADATA_H | ||||
| @ -10,6 +10,5 @@ struct proc; | ||||
| struct thread; | ||||
| 
 | ||||
| USE_RET int metadata_load_proc(const char *path, struct loom *loom, struct proc *proc); | ||||
| USE_RET int metadata_load_thread(const char *path, struct thread *thread); | ||||
| 
 | ||||
| #endif /* METADATA_H */ | ||||
|  | ||||
| @ -24,11 +24,11 @@ | ||||
| struct bay; | ||||
| 
 | ||||
| static struct thread * | ||||
| create_thread(struct proc *proc, const char *tracedir, const char *relpath) | ||||
| create_thread(struct proc *proc, struct stream *s) | ||||
| { | ||||
| 	int tid; | ||||
| 	if (thread_relpath_get_tid(relpath, &tid) != 0) { | ||||
| 		err("cannot get thread tid from %s", relpath); | ||||
| 	if ((tid = thread_stream_get_tid(s)) < 0) { | ||||
| 		err("cannot get thread tid from stream: %s", s->relpath); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| @ -45,21 +45,13 @@ create_thread(struct proc *proc, const char *tracedir, const char *relpath) | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (thread_init_begin(thread, relpath) != 0) { | ||||
| 		err("cannot init thread"); | ||||
| 	if (thread_init_begin(thread, tid) != 0) { | ||||
| 		err("thread_init_begin failed: %s", s->relpath); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Build metadata path */ | ||||
| 	char mpath[PATH_MAX]; | ||||
| 	if (snprintf(mpath, PATH_MAX, "%s/%s/thread.%d.json", | ||||
| 				tracedir, proc->id, tid) >= PATH_MAX) { | ||||
| 		err("path too long"); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	if (metadata_load_thread(mpath, thread) != 0) { | ||||
| 		err("cannot load metadata from %s", mpath); | ||||
| 	if (thread_load_metadata(thread, s) != 0) { | ||||
| 		err("thread_load_metadata failed: %s", s->relpath); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| @ -276,7 +268,7 @@ create_system(struct system *sys, struct trace *trace) | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		struct thread *thread = create_thread(proc, dir, s->relpath); | ||||
| 		struct thread *thread = create_thread(proc, s); | ||||
| 		if (thread == NULL) { | ||||
| 			err("create_thread failed"); | ||||
| 			return -1; | ||||
|  | ||||
| @ -15,6 +15,7 @@ | ||||
| #include "pv/prv.h" | ||||
| #include "pv/pvt.h" | ||||
| #include "recorder.h" | ||||
| #include "stream.h" | ||||
| #include "value.h" | ||||
| struct proc; | ||||
| 
 | ||||
| @ -59,75 +60,37 @@ static const struct pcf_value_label (*pcf_labels[TH_CHAN_MAX])[] = { | ||||
| 	[TH_CHAN_STATE] = &state_name, | ||||
| }; | ||||
| 
 | ||||
| static int | ||||
| get_tid(const char *id, int *tid) | ||||
| int | ||||
| thread_stream_get_tid(struct stream *s) | ||||
| { | ||||
| 	/* The id must be like "loom.host01.123/proc.345/thread.567" */ | ||||
| 	if (path_count(id, '/') != 2) { | ||||
| 		err("proc id can only contain two '/': %s", id); | ||||
| 	JSON_Object *meta = stream_metadata(s); | ||||
| 
 | ||||
| 	double tid = json_object_dotget_number(meta, "ovni.tid"); | ||||
| 
 | ||||
| 	/* Zero is used for errors, so forbidden for tid too */ | ||||
| 	if (tid == 0) { | ||||
| 		err("cannot get attribute ovni.tid for stream: %s", | ||||
| 				s->relpath); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Get the thread.567 part */ | ||||
| 	const char *thname; | ||||
| 	if (path_strip(id, 2, &thname) != 0) { | ||||
| 		err("cannot get thread name"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Ensure the prefix is ok */ | ||||
| 	const char prefix[] = "thread."; | ||||
| 	if (!path_has_prefix(thname, prefix)) { | ||||
| 		err("thread name must start with '%s': %s", prefix, thname); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Get the 567 part */ | ||||
| 	const char *tidstr; | ||||
| 	if (path_next(thname, '.', &tidstr) != 0) { | ||||
| 		err("cannot find thread dot in '%s'", id); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	char *endptr; | ||||
| 	errno = 0; | ||||
| 	*tid = (int) strtol(tidstr, &endptr, 10); | ||||
| 	if (errno != 0) { | ||||
| 		err("strtol failed for '%s':", tidstr); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	if (endptr == tidstr) { | ||||
| 		err("no digits in tid string '%s'", tidstr); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return (int) tid; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| thread_relpath_get_tid(const char *relpath, int *tid) | ||||
| { | ||||
| 	return get_tid(relpath, tid); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| thread_init_begin(struct thread *thread, const char *relpath) | ||||
| thread_init_begin(struct thread *thread, int tid) | ||||
| { | ||||
| 	memset(thread, 0, sizeof(struct thread)); | ||||
| 
 | ||||
| 	thread->state = TH_ST_UNKNOWN; | ||||
| 	thread->gindex = -1; | ||||
| 	thread->tid = tid; | ||||
| 
 | ||||
| 	if (snprintf(thread->id, PATH_MAX, "%s", relpath) >= PATH_MAX) { | ||||
| 	if (snprintf(thread->id, PATH_MAX, "thread.%d", tid) >= PATH_MAX) { | ||||
| 		err("relpath too long"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (get_tid(thread->id, &thread->tid) != 0) { | ||||
| 		err("cannot parse thread tid"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| @ -445,12 +408,9 @@ thread_migrate_cpu(struct thread *th, struct cpu *cpu) | ||||
| } | ||||
| 
 | ||||
| int | ||||
| thread_load_metadata(struct thread *thread, JSON_Object *meta) | ||||
| thread_load_metadata(struct thread *thread, struct stream *s) | ||||
| { | ||||
| 	if (meta == NULL) { | ||||
| 		err("metadata is null"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	JSON_Object *meta = stream_metadata(s); | ||||
| 
 | ||||
| 	if (thread->meta != NULL) { | ||||
| 		err("thread %s already loaded metadata", thread->id); | ||||
|  | ||||
| @ -20,6 +20,7 @@ struct pcf; | ||||
| struct proc; | ||||
| struct recorder; | ||||
| struct value; | ||||
| struct stream; | ||||
| 
 | ||||
| /* Emulated thread runtime status */ | ||||
| enum thread_state { | ||||
| @ -82,10 +83,10 @@ struct thread { | ||||
| 	UT_hash_handle hh; /* threads in the process */ | ||||
| }; | ||||
| 
 | ||||
| USE_RET int thread_relpath_get_tid(const char *relpath, int *tid); | ||||
| USE_RET int thread_init_begin(struct thread *thread, const char *relpath); | ||||
| USE_RET int thread_stream_get_tid(struct stream *s); | ||||
| USE_RET int thread_init_begin(struct thread *thread, int tid); | ||||
| USE_RET int thread_init_end(struct thread *thread); | ||||
| USE_RET int thread_load_metadata(struct thread *thread, JSON_Object *meta); | ||||
| USE_RET int thread_load_metadata(struct thread *thread, struct stream *s); | ||||
| USE_RET int thread_set_state(struct thread *th, enum thread_state state); | ||||
| USE_RET int thread_set_cpu(struct thread *th, struct cpu *cpu); | ||||
| USE_RET int thread_unset_cpu(struct thread *th); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user