Follow K&R coding style using clang-format
This commit is contained in:
		
							parent
							
								
									baefb2b01c
								
							
						
					
					
						commit
						177429fabc
					
				
							
								
								
									
										31
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| Language: Cpp | ||||
| BasedOnStyle: LLVM | ||||
| 
 | ||||
| AlignAfterOpenBracket: DontAlign | ||||
| AlignConsecutiveAssignments: None | ||||
| AllowShortBlocksOnASingleLine: false | ||||
| AllowShortFunctionsOnASingleLine: None | ||||
| AllowShortIfStatementsOnASingleLine: false | ||||
| AlwaysBreakAfterDefinitionReturnType: true | ||||
| BreakBeforeBinaryOperators: NonAssignment | ||||
| BreakBeforeBraces: Custom | ||||
| BreakConstructorInitializers: AfterColon | ||||
| BraceWrapping: | ||||
|   AfterControlStatement: false | ||||
|   AfterFunction: true | ||||
|   AfterStruct: false | ||||
|   AfterUnion: false | ||||
|   BeforeElse: false | ||||
| ColumnLimit: 0 | ||||
| ContinuationIndentWidth: 8 | ||||
| IncludeBlocks: Preserve | ||||
| IndentCaseLabels: true | ||||
| IndentWidth: 8 | ||||
| KeepEmptyLinesAtTheStartOfBlocks: false | ||||
| MaxEmptyLinesToKeep: 2 | ||||
| SortIncludes: true | ||||
| SpaceAfterCStyleCast: true | ||||
| SpacesBeforeTrailingComments: 0 | ||||
| TabWidth: 8 | ||||
| UseTab: Always | ||||
| ... | ||||
							
								
								
									
										167
									
								
								chan.c
									
									
									
									
									
								
							
							
						
						
									
										167
									
								
								chan.c
									
									
									
									
									
								
							| @ -27,10 +27,10 @@ chan_init(struct ovni_chan *chan, enum chan_track track, int row, int type, FILE | ||||
| static void | ||||
| mark_dirty(struct ovni_chan *chan, enum chan_dirty dirty) | ||||
| { | ||||
| 	if(chan->dirty != CHAN_CLEAN) | ||||
| 	if (chan->dirty != CHAN_CLEAN) | ||||
| 		die("mark_dirty: chan %d already dirty\n", chan->id); | ||||
| 
 | ||||
| 	if(dirty == CHAN_CLEAN) | ||||
| 	if (dirty == CHAN_CLEAN) | ||||
| 		die("mark_dirty: cannot use CHAN_CLEAN\n"); | ||||
| 
 | ||||
| 	dbg("adding dirty chan %d to list\n", chan->id); | ||||
| @ -40,15 +40,15 @@ mark_dirty(struct ovni_chan *chan, enum chan_dirty dirty) | ||||
| 
 | ||||
| void | ||||
| chan_th_init(struct ovni_ethread *th, | ||||
| 		struct ovni_chan **update_list, | ||||
| 		enum chan id, | ||||
| 		enum chan_track track, | ||||
| 		int init_st, | ||||
| 		int enabled, | ||||
| 		int dirty, | ||||
| 		int row, | ||||
| 		FILE *prv, | ||||
| 		int64_t *clock) | ||||
| 	struct ovni_chan **update_list, | ||||
| 	enum chan id, | ||||
| 	enum chan_track track, | ||||
| 	int init_st, | ||||
| 	int enabled, | ||||
| 	int dirty, | ||||
| 	int row, | ||||
| 	FILE *prv, | ||||
| 	int64_t *clock) | ||||
| { | ||||
| 	struct ovni_chan *chan; | ||||
| 	int prvth; | ||||
| @ -63,21 +63,21 @@ chan_th_init(struct ovni_ethread *th, | ||||
| 	chan->update_list = update_list; | ||||
| 	chan->enabled = enabled; | ||||
| 	chan->stack[chan->n++] = init_st; | ||||
| 	if(dirty) | ||||
| 	if (dirty) | ||||
| 		mark_dirty(chan, CHAN_DIRTY_ACTIVE); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| chan_cpu_init(struct ovni_cpu *cpu, | ||||
| 		struct ovni_chan **update_list, | ||||
| 		enum chan id, | ||||
| 		enum chan_track track, | ||||
| 		int init_st, | ||||
| 		int enabled, | ||||
| 		int dirty, | ||||
| 		int row, | ||||
| 		FILE *prv, | ||||
| 		int64_t *clock) | ||||
| 	struct ovni_chan **update_list, | ||||
| 	enum chan id, | ||||
| 	enum chan_track track, | ||||
| 	int init_st, | ||||
| 	int enabled, | ||||
| 	int dirty, | ||||
| 	int row, | ||||
| 	FILE *prv, | ||||
| 	int64_t *clock) | ||||
| { | ||||
| 	struct ovni_chan *chan; | ||||
| 	int prvcpu; | ||||
| @ -92,7 +92,7 @@ chan_cpu_init(struct ovni_cpu *cpu, | ||||
| 	chan->update_list = update_list; | ||||
| 	chan->enabled = enabled; | ||||
| 	chan->stack[chan->n++] = init_st; | ||||
| 	if(dirty) | ||||
| 	if (dirty) | ||||
| 		mark_dirty(chan, CHAN_DIRTY_ACTIVE); | ||||
| } | ||||
| 
 | ||||
| @ -102,9 +102,8 @@ chan_dump_update_list(struct ovni_chan *chan) | ||||
| 	struct ovni_chan *c; | ||||
| 
 | ||||
| 	dbg("update list for chan %d at %p:\n", | ||||
| 			chan->id, (void *) chan); | ||||
| 	for(c = *chan->update_list; c; c = c->next) | ||||
| 	{ | ||||
| 		chan->id, (void *) chan); | ||||
| 	for (c = *chan->update_list; c; c = c->next) { | ||||
| 		dbg(" chan %d at %p\n", c->id, (void *) c); | ||||
| 	} | ||||
| } | ||||
| @ -116,8 +115,7 @@ chan_enable(struct ovni_chan *chan, int enabled) | ||||
| 
 | ||||
| 	dbg("chan_enable chan=%d enabled=%d\n", chan->id, enabled); | ||||
| 
 | ||||
| 	if(chan->enabled == enabled) | ||||
| 	{ | ||||
| 	if (chan->enabled == enabled) { | ||||
| 		err("chan_enable: chan already in enabled=%d\n", enabled); | ||||
| 		abort(); | ||||
| 	} | ||||
| @ -126,14 +124,11 @@ chan_enable(struct ovni_chan *chan, int enabled) | ||||
| 	chan->t = *chan->clock; | ||||
| 
 | ||||
| 	/* Only append if not dirty */ | ||||
| 	if(!chan->dirty) | ||||
| 	{ | ||||
| 	if (!chan->dirty) { | ||||
| 		mark_dirty(chan, CHAN_DIRTY_ACTIVE); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		dbg("already dirty chan %d: skip update list\n", | ||||
| 				chan->id); | ||||
| 			chan->id); | ||||
| 		chan_dump_update_list(chan); | ||||
| 	} | ||||
| } | ||||
| @ -157,40 +152,36 @@ chan_set(struct ovni_chan *chan, int st) | ||||
| 
 | ||||
| 	dbg("chan_set chan %d st=%d\n", chan->id, st); | ||||
| 
 | ||||
| 	if(!chan->enabled) | ||||
| 	if (!chan->enabled) | ||||
| 		die("chan_set: chan %d not enabled\n", chan->id); | ||||
| 
 | ||||
| 	/* Only chan_set can set the 0 state */ | ||||
| 	if(st < 0) | ||||
| 	if (st < 0) | ||||
| 		die("chan_set: cannot set a negative state %d\n", st); | ||||
| 
 | ||||
| 	/* Don't enforce this check if we are dirty because the channel was
 | ||||
| 	 * just enabled; it may collide with a new state 0 set via chan_set() | ||||
| 	 * used by the tracking channels */ | ||||
| 	if(chan->dirty != CHAN_DIRTY_ACTIVE | ||||
| 			&& chan->lastst >= 0 | ||||
| 			&& chan->lastst == st) | ||||
| 	{ | ||||
| 	if (chan->dirty != CHAN_DIRTY_ACTIVE | ||||
| 		&& chan->lastst >= 0 | ||||
| 		&& chan->lastst == st) { | ||||
| 		err("chan_set id=%d cannot emit the state %d twice\n", | ||||
| 				chan->id, st); | ||||
| 			chan->id, st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	if(chan->n == 0) | ||||
| 	if (chan->n == 0) | ||||
| 		chan->n = 1; | ||||
| 
 | ||||
| 	chan->stack[chan->n - 1] = st; | ||||
| 	chan->t = *chan->clock; | ||||
| 
 | ||||
| 	/* Only append if not dirty */ | ||||
| 	if(!chan->dirty) | ||||
| 	{ | ||||
| 	if (!chan->dirty) { | ||||
| 		mark_dirty(chan, CHAN_DIRTY_VALUE); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		dbg("already dirty chan %d: skip update list\n", | ||||
| 				chan->id); | ||||
| 			chan->id); | ||||
| 		chan_dump_update_list(chan); | ||||
| 	} | ||||
| } | ||||
| @ -200,28 +191,25 @@ chan_push(struct ovni_chan *chan, int st) | ||||
| { | ||||
| 	dbg("chan_push chan %d st=%d\n", chan->id, st); | ||||
| 
 | ||||
| 	if(!chan->enabled) | ||||
| 	if (!chan->enabled) | ||||
| 		die("chan_push: chan %d not enabled\n", chan->id); | ||||
| 
 | ||||
| 	if(st <= 0) | ||||
| 	{ | ||||
| 	if (st <= 0) { | ||||
| 		err("chan_push: cannot push a non-positive state %d\n", st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Cannot be dirty */ | ||||
| 	if(chan->dirty != CHAN_CLEAN) | ||||
| 	if (chan->dirty != CHAN_CLEAN) | ||||
| 		die("chan_push: chan %d not clean", chan->id); | ||||
| 
 | ||||
| 	if(chan->lastst >= 0 && chan->lastst == st) | ||||
| 	{ | ||||
| 	if (chan->lastst >= 0 && chan->lastst == st) { | ||||
| 		err("chan_push id=%d cannot emit the state %d twice\n", | ||||
| 				chan->id, st); | ||||
| 			chan->id, st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	if(chan->n >= MAX_CHAN_STACK) | ||||
| 	{ | ||||
| 	if (chan->n >= MAX_CHAN_STACK) { | ||||
| 		err("chan_push: channel stack full\n"); | ||||
| 		abort(); | ||||
| 	} | ||||
| @ -239,25 +227,23 @@ chan_pop(struct ovni_chan *chan, int expected_st) | ||||
| 
 | ||||
| 	dbg("chan_pop chan %d expected_st=%d\n", chan->id, expected_st); | ||||
| 
 | ||||
| 	if(!chan->enabled) | ||||
| 	if (!chan->enabled) | ||||
| 		die("chan_pop: chan %d not enabled\n", chan->id); | ||||
| 
 | ||||
| 	/* Cannot be dirty */ | ||||
| 	if(chan->dirty != CHAN_CLEAN) | ||||
| 	if (chan->dirty != CHAN_CLEAN) | ||||
| 		die("chan_pop: chan %d not clean", chan->id); | ||||
| 
 | ||||
| 	if(chan->n <= 0) | ||||
| 	{ | ||||
| 	if (chan->n <= 0) { | ||||
| 		err("chan_pop: channel empty\n"); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	st = chan->stack[chan->n - 1]; | ||||
| 
 | ||||
| 	if(expected_st >= 0 && st != expected_st) | ||||
| 	{ | ||||
| 	if (expected_st >= 0 && st != expected_st) { | ||||
| 		err("chan_pop: unexpected channel state %d (expected %d)\n", | ||||
| 				st, expected_st); | ||||
| 			st, expected_st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| @ -267,16 +253,14 @@ chan_pop(struct ovni_chan *chan, int expected_st) | ||||
| 	st = chan_get_st(chan); | ||||
| 
 | ||||
| 	/* A st == 0 can be obtained when returning to the initial state */ | ||||
| 	if(st < 0) | ||||
| 	{ | ||||
| 	if (st < 0) { | ||||
| 		err("chan_pop: obtained negative state %d from the stack\n", st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	if(chan->lastst >= 0 && chan->lastst == st) | ||||
| 	{ | ||||
| 	if (chan->lastst >= 0 && chan->lastst == st) { | ||||
| 		err("chan_pop id=%d cannot emit the state %d twice\n", | ||||
| 				chan->id, st); | ||||
| 			chan->id, st); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| @ -292,19 +276,19 @@ chan_ev(struct ovni_chan *chan, int ev) | ||||
| { | ||||
| 	dbg("chan_ev chan %d ev=%d\n", chan->id, ev); | ||||
| 
 | ||||
| 	if(!chan->enabled) | ||||
| 	if (!chan->enabled) | ||||
| 		die("chan_ev: chan %d not enabled\n", chan->id); | ||||
| 
 | ||||
| 	/* Cannot be dirty */ | ||||
| 	if(chan->dirty != CHAN_CLEAN) | ||||
| 	if (chan->dirty != CHAN_CLEAN) | ||||
| 		die("chan_ev: chan %d is dirty\n", chan->id); | ||||
| 
 | ||||
| 	if(ev <= 0) | ||||
| 	if (ev <= 0) | ||||
| 		die("chan_ev: cannot emit non-positive state %d\n", ev); | ||||
| 
 | ||||
| 	if(chan->lastst >= 0 && chan->lastst == ev) | ||||
| 	if (chan->lastst >= 0 && chan->lastst == ev) | ||||
| 		die("chan_ev id=%d cannot emit the state %d twice\n", | ||||
| 				chan->id, ev); | ||||
| 			chan->id, ev); | ||||
| 
 | ||||
| 	chan->ev = ev; | ||||
| 	chan->t = *chan->clock; | ||||
| @ -315,38 +299,36 @@ chan_ev(struct ovni_chan *chan, int ev) | ||||
| int | ||||
| chan_get_st(struct ovni_chan *chan) | ||||
| { | ||||
| 	if(chan->enabled == 0) | ||||
| 	if (chan->enabled == 0) | ||||
| 		return chan->badst; | ||||
| 
 | ||||
| 	if(chan->n == 0) | ||||
| 	if (chan->n == 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if(chan->n < 0) | ||||
| 	if (chan->n < 0) | ||||
| 		die("chan_get_st: chan %d has negative n\n", chan->id); | ||||
| 
 | ||||
| 	return chan->stack[chan->n-1]; | ||||
| 	return chan->stack[chan->n - 1]; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| emit(struct ovni_chan *chan, int64_t t, int state) | ||||
| { | ||||
| 	if(chan->dirty == CHAN_CLEAN) | ||||
| 	if (chan->dirty == CHAN_CLEAN) | ||||
| 		die("emit: chan %d is not dirty\n", chan->id); | ||||
| 
 | ||||
| 	/* A channel can only emit the same state as lastst if is dirty because
 | ||||
| 	 * it has been enabled or disabled. Otherwise is a bug (ie. you have two | ||||
| 	 * consecutive ovni events?) */ | ||||
| 	if(chan->lastst != -1 | ||||
| 			&& chan->dirty == CHAN_DIRTY_VALUE | ||||
| 			&& chan->lastst == state) | ||||
| 	{ | ||||
| 	if (chan->lastst != -1 | ||||
| 		&& chan->dirty == CHAN_DIRTY_VALUE | ||||
| 		&& chan->lastst == state) { | ||||
| 		/* TODO: Print the raw clock of the offending event */ | ||||
| 		die("emit: chan %d cannot emit the same state %d twice\n", | ||||
| 				chan->id, state); | ||||
| 			chan->id, state); | ||||
| 	} | ||||
| 
 | ||||
| 	if(chan->lastst != state) | ||||
| 	{ | ||||
| 	if (chan->lastst != state) { | ||||
| 		prv_ev(chan->prv, chan->row, t, chan->type, state); | ||||
| 
 | ||||
| 		chan->lastst = state; | ||||
| @ -358,16 +340,16 @@ emit_ev(struct ovni_chan *chan) | ||||
| { | ||||
| 	int new, last; | ||||
| 
 | ||||
| 	if(!chan->enabled) | ||||
| 	if (!chan->enabled) | ||||
| 		die("emit_ev: chan %d is not enabled\n", chan->id); | ||||
| 
 | ||||
| 	if(chan->ev == -1) | ||||
| 	if (chan->ev == -1) | ||||
| 		die("emit_ev: chan %d cannot emit -1 ev\n", chan->id); | ||||
| 
 | ||||
| 	new = chan->ev; | ||||
| 	last = chan_get_st(chan); | ||||
| 
 | ||||
| 	emit(chan, chan->t-1, new); | ||||
| 	emit(chan, chan->t - 1, new); | ||||
| 	emit(chan, chan->t, last); | ||||
| 
 | ||||
| 	chan->ev = -1; | ||||
| @ -387,16 +369,15 @@ emit_st(struct ovni_chan *chan) | ||||
| void | ||||
| chan_emit(struct ovni_chan *chan) | ||||
| { | ||||
| 	if(likely(chan->dirty == 0)) | ||||
| 	if (likely(chan->dirty == 0)) | ||||
| 		return; | ||||
| 
 | ||||
| 	dbg("chan_emit chan %d\n", chan->id); | ||||
| 
 | ||||
| 	/* Emit badst if disabled */ | ||||
| 	if(chan->enabled == 0) | ||||
| 	{ | ||||
| 	if (chan->enabled == 0) { | ||||
| 		/* No punctual events allowed when disabled */ | ||||
| 		if(chan->ev != -1) | ||||
| 		if (chan->ev != -1) | ||||
| 			die("chan_emit: no punctual event allowed when disabled\n"); | ||||
| 
 | ||||
| 		emit_st(chan); | ||||
| @ -404,7 +385,7 @@ chan_emit(struct ovni_chan *chan) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Otherwise, emit punctual event if any or the state */ | ||||
| 	if(chan->ev != -1) | ||||
| 	if (chan->ev != -1) | ||||
| 		emit_ev(chan); | ||||
| 	else | ||||
| 		emit_st(chan); | ||||
|  | ||||
							
								
								
									
										36
									
								
								chan.h
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								chan.h
									
									
									
									
									
								
							| @ -8,27 +8,27 @@ | ||||
| 
 | ||||
| void | ||||
| chan_th_init(struct ovni_ethread *th, | ||||
| 		struct ovni_chan **update_list, | ||||
| 		enum chan id, | ||||
| 		enum chan_track track, | ||||
| 		int init_st, | ||||
| 		int enabled, | ||||
| 		int dirty, | ||||
| 		int row, | ||||
| 		FILE *prv, | ||||
| 		int64_t *clock); | ||||
| 	struct ovni_chan **update_list, | ||||
| 	enum chan id, | ||||
| 	enum chan_track track, | ||||
| 	int init_st, | ||||
| 	int enabled, | ||||
| 	int dirty, | ||||
| 	int row, | ||||
| 	FILE *prv, | ||||
| 	int64_t *clock); | ||||
| 
 | ||||
| void | ||||
| chan_cpu_init(struct ovni_cpu *cpu, | ||||
| 		struct ovni_chan **update_list, | ||||
| 		enum chan id, | ||||
| 		enum chan_track track, | ||||
| 		int row, | ||||
| 		int init_st, | ||||
| 		int enabled, | ||||
| 		int dirty, | ||||
| 		FILE *prv, | ||||
| 		int64_t *clock); | ||||
| 	struct ovni_chan **update_list, | ||||
| 	enum chan id, | ||||
| 	enum chan_track track, | ||||
| 	int row, | ||||
| 	int init_st, | ||||
| 	int enabled, | ||||
| 	int dirty, | ||||
| 	FILE *prv, | ||||
| 	int64_t *clock); | ||||
| 
 | ||||
| void | ||||
| chan_enable(struct ovni_chan *chan, int enabled); | ||||
|  | ||||
							
								
								
									
										7
									
								
								compat.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								compat.h
									
									
									
									
									
								
							| @ -11,11 +11,12 @@ | ||||
| /* Define gettid for older glibc versions (below 2.30) */ | ||||
| #if defined(__GLIBC__) | ||||
| #if !__GLIBC_PREREQ(2, 30) | ||||
| static inline pid_t gettid(void) | ||||
| static inline pid_t | ||||
| gettid(void) | ||||
| { | ||||
| 	return (pid_t)syscall(SYS_gettid); | ||||
| 	return (pid_t) syscall(SYS_gettid); | ||||
| } | ||||
| #endif /* !__GLIBC_PREREQ(2, 30) */ | ||||
| #endif /* defined(__GLIBC__) */ | ||||
| 
 | ||||
| #endif // COMPAT_H
 | ||||
| #endif// COMPAT_H
 | ||||
|  | ||||
							
								
								
									
										91
									
								
								dump.c
									
									
									
									
									
								
							
							
						
						
									
										91
									
								
								dump.c
									
									
									
									
									
								
							| @ -3,26 +3,26 @@ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdatomic.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <linux/limits.h> | ||||
| #include <errno.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdatomic.h> | ||||
| #include <dirent.h>  | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "trace.h" | ||||
| #include "emu.h" | ||||
| 
 | ||||
| int filter_tid = -1; | ||||
| char *tracedir; | ||||
| 
 | ||||
| //static void
 | ||||
| //hexdump(uint8_t *buf, size_t size)
 | ||||
| // static void
 | ||||
| // hexdump(uint8_t *buf, size_t size)
 | ||||
| //{
 | ||||
| //	size_t i, j;
 | ||||
| //
 | ||||
| @ -36,7 +36,7 @@ char *tracedir; | ||||
| //		}
 | ||||
| //		fprintf(stderr, "\n");
 | ||||
| //	}
 | ||||
| //}
 | ||||
| // }
 | ||||
| 
 | ||||
| static void | ||||
| emit(struct ovni_stream *stream, struct ovni_ev *ev) | ||||
| @ -44,25 +44,24 @@ emit(struct ovni_stream *stream, struct ovni_ev *ev) | ||||
| 	uint64_t clock; | ||||
| 	int i, payloadsize; | ||||
| 
 | ||||
| 	//printf("sizeof(*ev) = %d\n", sizeof(*ev));
 | ||||
| 	//hexdump((uint8_t *) ev, sizeof(*ev));
 | ||||
| 	// printf("sizeof(*ev) = %d\n", sizeof(*ev));
 | ||||
| 	// hexdump((uint8_t *) ev, sizeof(*ev));
 | ||||
| 
 | ||||
| 	clock = ovni_ev_get_clock(ev); | ||||
| 
 | ||||
| 	printf("%s.%d.%d  %ld  %c%c%c", | ||||
| 			stream->loom->hostname, | ||||
| 			stream->proc->pid, | ||||
| 			stream->thread->tid, | ||||
| 			clock, | ||||
| 			ev->header.model, | ||||
| 			ev->header.category, | ||||
| 			ev->header.value); | ||||
| 		stream->loom->hostname, | ||||
| 		stream->proc->pid, | ||||
| 		stream->thread->tid, | ||||
| 		clock, | ||||
| 		ev->header.model, | ||||
| 		ev->header.category, | ||||
| 		ev->header.value); | ||||
| 
 | ||||
| 	payloadsize = ovni_payload_size(ev); | ||||
| 	if(payloadsize > 0) | ||||
| 	{ | ||||
| 	if (payloadsize > 0) { | ||||
| 		printf(" "); | ||||
| 		for(i=0; i<payloadsize; i++) | ||||
| 		for (i = 0; i < payloadsize; i++) | ||||
| 			printf(":%02x", ev->payload.u8[i]); | ||||
| 	} | ||||
| 	printf("\n"); | ||||
| @ -81,50 +80,45 @@ dump_events(struct ovni_trace *trace) | ||||
| 	struct ovni_stream *stream; | ||||
| 
 | ||||
| 	/* Load events */ | ||||
| 	for(i=0; i<trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nstreams; i++) { | ||||
| 		stream = &trace->stream[i]; | ||||
| 
 | ||||
| 		/* It can be inactive if it has been disabled by the
 | ||||
| 		 * thread TID filter */ | ||||
| 		if(stream->active) | ||||
| 		if (stream->active) | ||||
| 			ovni_load_next_event(stream); | ||||
| 	} | ||||
| 
 | ||||
| 	lastclock = 0; | ||||
| 
 | ||||
| 	while(1) | ||||
| 	{ | ||||
| 	while (1) { | ||||
| 		f = -1; | ||||
| 		minclock = 0; | ||||
| 
 | ||||
| 		/* Select next event based on the clock */ | ||||
| 		for(i=0; i<trace->nstreams; i++) | ||||
| 		{ | ||||
| 		for (i = 0; i < trace->nstreams; i++) { | ||||
| 			stream = &trace->stream[i]; | ||||
| 
 | ||||
| 			if(!stream->active) | ||||
| 			if (!stream->active) | ||||
| 				continue; | ||||
| 
 | ||||
| 			ev = stream->cur_ev; | ||||
| 			if(f < 0 || ovni_ev_get_clock(ev) < minclock) | ||||
| 			{ | ||||
| 			if (f < 0 || ovni_ev_get_clock(ev) < minclock) { | ||||
| 				f = i; | ||||
| 				minclock = ovni_ev_get_clock(ev); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
 | ||||
| 		// fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
 | ||||
| 
 | ||||
| 		if(f < 0) | ||||
| 		if (f < 0) | ||||
| 			break; | ||||
| 
 | ||||
| 		stream = &trace->stream[f]; | ||||
| 
 | ||||
| 		if(lastclock > ovni_ev_get_clock(stream->cur_ev)) | ||||
| 		{ | ||||
| 		if (lastclock > ovni_ev_get_clock(stream->cur_ev)) { | ||||
| 			fprintf(stdout, "warning: backwards jump in time %lu -> %lu\n", | ||||
| 					lastclock, ovni_ev_get_clock(stream->cur_ev)); | ||||
| 				lastclock, ovni_ev_get_clock(stream->cur_ev)); | ||||
| 		} | ||||
| 
 | ||||
| 		/* Emit current event */ | ||||
| @ -138,7 +132,6 @@ dump_events(struct ovni_trace *trace) | ||||
| 		/* Unset the index */ | ||||
| 		f = -1; | ||||
| 		minclock = 0; | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -166,10 +159,8 @@ parse_args(int argc, char *argv[]) | ||||
| { | ||||
| 	int opt; | ||||
| 
 | ||||
| 	while((opt = getopt(argc, argv, "t:")) != -1) | ||||
| 	{ | ||||
| 		switch(opt) | ||||
| 		{ | ||||
| 	while ((opt = getopt(argc, argv, "t:")) != -1) { | ||||
| 		switch (opt) { | ||||
| 			case 't': | ||||
| 				filter_tid = atoi(optarg); | ||||
| 				break; | ||||
| @ -178,8 +169,7 @@ parse_args(int argc, char *argv[]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(optind >= argc) | ||||
| 	{ | ||||
| 	if (optind >= argc) { | ||||
| 		err("missing tracedir\n"); | ||||
| 		usage(argc, argv); | ||||
| 	} | ||||
| @ -187,25 +177,24 @@ parse_args(int argc, char *argv[]) | ||||
| 	tracedir = argv[optind]; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	parse_args(argc, argv); | ||||
| 
 | ||||
| 	struct ovni_trace *trace = calloc(1, sizeof(struct ovni_trace)); | ||||
| 
 | ||||
| 	if(ovni_load_trace(trace, tracedir)) | ||||
| 	if (ovni_load_trace(trace, tracedir)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if(ovni_load_streams(trace)) | ||||
| 	if (ovni_load_streams(trace)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if(filter_tid != -1) | ||||
| 	{ | ||||
| 		for(size_t i=0; i<trace->nstreams; i++) | ||||
| 		{ | ||||
| 	if (filter_tid != -1) { | ||||
| 		for (size_t i = 0; i < trace->nstreams; i++) { | ||||
| 			struct ovni_stream *stream; | ||||
| 			stream = &trace->stream[i]; | ||||
| 			if(stream->tid != filter_tid) | ||||
| 			if (stream->tid != filter_tid) | ||||
| 				stream->active = 0; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										467
									
								
								emu.c
									
									
									
									
									
								
							
							
						
						
									
										467
									
								
								emu.c
									
									
									
									
									
								
							| @ -3,25 +3,25 @@ | ||||
| 
 | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| 
 | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdio.h> | ||||
| #include <stdatomic.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <linux/limits.h> | ||||
| #include <errno.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdatomic.h> | ||||
| #include <dirent.h> | ||||
| #include <unistd.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "trace.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "pcf.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "pcf.h" | ||||
| #include "prv.h" | ||||
| #include "trace.h" | ||||
| #include "utlist.h" | ||||
| 
 | ||||
| /* Obtains the corrected clock of the given event */ | ||||
| @ -39,22 +39,21 @@ print_ev(struct ovni_stream *stream, struct ovni_ev *ev) | ||||
| 
 | ||||
| 	UNUSED(delta); | ||||
| 
 | ||||
| 	//dbg("sizeof(*ev) = %d\n", sizeof(*ev));
 | ||||
| 	//hexdump((uint8_t *) ev, sizeof(*ev));
 | ||||
| 	// dbg("sizeof(*ev) = %d\n", sizeof(*ev));
 | ||||
| 	// hexdump((uint8_t *) ev, sizeof(*ev));
 | ||||
| 
 | ||||
| 	clock = evclock(stream, ev); | ||||
| 
 | ||||
| 	delta = clock - stream->lastclock; | ||||
| 
 | ||||
| 	dbg(">>> %s.%d.%d %c %c %c % 20ld % 15ld ", | ||||
| 			stream->loom->hostname, | ||||
| 			stream->proc->pid, | ||||
| 			stream->thread->tid, | ||||
| 			ev->header.model, ev->header.category, ev->header.value, clock, delta); | ||||
| 		stream->loom->hostname, | ||||
| 		stream->proc->pid, | ||||
| 		stream->thread->tid, | ||||
| 		ev->header.model, ev->header.category, ev->header.value, clock, delta); | ||||
| 
 | ||||
| 	payloadsize = ovni_payload_size(ev); | ||||
| 	for(i=0; i<payloadsize; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < payloadsize; i++) { | ||||
| 		dbg("%d ", ev->payload.u8[i]); | ||||
| 	} | ||||
| 	dbg("\n"); | ||||
| @ -73,8 +72,7 @@ cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th) | ||||
| 	int th_enabled, cpu_enabled, st; | ||||
| 	struct ovni_chan *th_chan; | ||||
| 
 | ||||
| 	switch (cpu_chan->track) | ||||
| 	{ | ||||
| 	switch (cpu_chan->track) { | ||||
| 		case CHAN_TRACK_TH_RUNNING: | ||||
| 			cpu_enabled = th->is_running; | ||||
| 			break; | ||||
| @ -91,44 +89,36 @@ cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th) | ||||
| 	th_enabled = chan_is_enabled(th_chan); | ||||
| 
 | ||||
| 	/* Enable the cpu channel if needed */ | ||||
| 	if(cpu_enabled && !chan_is_enabled(cpu_chan)) | ||||
| 	if (cpu_enabled && !chan_is_enabled(cpu_chan)) | ||||
| 		chan_enable(cpu_chan, cpu_enabled); | ||||
| 
 | ||||
| 	/* Copy the state from the thread channel if needed */ | ||||
| 	if(th_enabled && cpu_enabled) | ||||
| 	{ | ||||
| 	if (th_enabled && cpu_enabled) { | ||||
| 		/* Both enabled: simply follow the same value */ | ||||
| 		st = chan_get_st(th_chan); | ||||
| 		if(chan_get_st(cpu_chan) != st) | ||||
| 		if (chan_get_st(cpu_chan) != st) | ||||
| 			chan_set(cpu_chan, st); | ||||
| 	} | ||||
| 	else if(th_enabled && !cpu_enabled) | ||||
| 	{ | ||||
| 	} else if (th_enabled && !cpu_enabled) { | ||||
| 		/* Only thread enabled: disable CPU */ | ||||
| 		if(chan_is_enabled(cpu_chan)) | ||||
| 		if (chan_is_enabled(cpu_chan)) | ||||
| 			chan_disable(cpu_chan); | ||||
| 	} | ||||
| 	else if(!th_enabled && cpu_enabled) | ||||
| 	{ | ||||
| 	} else if (!th_enabled && cpu_enabled) { | ||||
| 		/* Only CPU enabled: is this possible? Set to bad */ | ||||
| 		chan_set(cpu_chan, ST_BAD); | ||||
| 		err("warning: cpu %s chan %d enabled but tracked thread %d chan disabled\n", | ||||
| 				cpu_chan->cpu->name, | ||||
| 				cpu_chan->id, | ||||
| 				th->tid); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 			cpu_chan->cpu->name, | ||||
| 			cpu_chan->id, | ||||
| 			th->tid); | ||||
| 	} else { | ||||
| 		/* Both disabled: disable CPU channel if needed */ | ||||
| 		if(chan_is_enabled(cpu_chan)) | ||||
| 		if (chan_is_enabled(cpu_chan)) | ||||
| 			chan_disable(cpu_chan); | ||||
| 	} | ||||
| 
 | ||||
| 	dbg("cpu %s chan %d enabled=%d state=%d\n", | ||||
| 			cpu_chan->cpu->name, cpu_chan->id, | ||||
| 			chan_is_enabled(cpu_chan), | ||||
| 			chan_get_st(cpu_chan)); | ||||
| 
 | ||||
| 		cpu_chan->cpu->name, cpu_chan->id, | ||||
| 		chan_is_enabled(cpu_chan), | ||||
| 		chan_get_st(cpu_chan)); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| @ -139,8 +129,7 @@ emu_cpu_update_chan(struct ovni_cpu *cpu, struct ovni_chan *cpu_chan) | ||||
| 
 | ||||
| 	/* Determine the source of tracking */ | ||||
| 
 | ||||
| 	switch (cpu_chan->track) | ||||
| 	{ | ||||
| 	switch (cpu_chan->track) { | ||||
| 		case CHAN_TRACK_TH_RUNNING: | ||||
| 			count = cpu->nrunning_threads; | ||||
| 			th = cpu->th_running; | ||||
| @ -156,32 +145,27 @@ emu_cpu_update_chan(struct ovni_cpu *cpu, struct ovni_chan *cpu_chan) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Based on how many threads, determine the state */ | ||||
| 	if(count == 0) | ||||
| 	{ | ||||
| 	if (count == 0) { | ||||
| 		/* The channel can be already disabled (migration of paused
 | ||||
| 		 * thread) so only disable it if needed. */ | ||||
| 		if(chan_is_enabled(cpu_chan)) | ||||
| 		if (chan_is_enabled(cpu_chan)) | ||||
| 			chan_disable(cpu_chan); | ||||
| 	} | ||||
| 	else if(count == 1) | ||||
| 	{ | ||||
| 		if(th == NULL) | ||||
| 	} else if (count == 1) { | ||||
| 		if (th == NULL) | ||||
| 			die("emu_cpu_update_chan: tracking thread is NULL\n"); | ||||
| 
 | ||||
| 		/* A unique thread found: copy the state */ | ||||
| 		dbg("cpu_update_chan: unique thread %d found, updating chan %d\n", | ||||
| 				th->tid, cpu_chan->id); | ||||
| 			th->tid, cpu_chan->id); | ||||
| 
 | ||||
| 		cpu_update_tracking_chan(cpu_chan, th); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		/* More than one thread: enable the channel and set it to a
 | ||||
| 		 * error value */ | ||||
| 		if(!chan_is_enabled(cpu_chan)) | ||||
| 		if (!chan_is_enabled(cpu_chan)) | ||||
| 			chan_enable(cpu_chan, 1); | ||||
| 
 | ||||
| 		if(chan_get_st(cpu_chan) != ST_TOO_MANY_TH) | ||||
| 		if (chan_get_st(cpu_chan) != ST_TOO_MANY_TH) | ||||
| 			chan_set(cpu_chan, ST_TOO_MANY_TH); | ||||
| 	} | ||||
| } | ||||
| @ -197,13 +181,13 @@ propagate_channels(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	DL_FOREACH_SAFE(emu->th_chan, th_chan, tmp) | ||||
| 	{ | ||||
| 		if(th_chan->thread == NULL) | ||||
| 		if (th_chan->thread == NULL) | ||||
| 			die("propagate_channels: channel thread is NULL\n"); | ||||
| 
 | ||||
| 		thread = th_chan->thread; | ||||
| 
 | ||||
| 		/* No CPU in the thread */ | ||||
| 		if(thread->cpu == NULL) | ||||
| 		if (thread->cpu == NULL) | ||||
| 			continue; | ||||
| 
 | ||||
| 		cpu = thread->cpu; | ||||
| @ -211,7 +195,7 @@ propagate_channels(struct ovni_emu *emu) | ||||
| 		cpu_chan = &cpu->chan[th_chan->id]; | ||||
| 
 | ||||
| 		dbg("propagate thread %d chan %d in cpu %s\n", | ||||
| 				thread->tid, th_chan->id, cpu->name); | ||||
| 			thread->tid, th_chan->id, cpu->name); | ||||
| 
 | ||||
| 		emu_cpu_update_chan(cpu, cpu_chan); | ||||
| 	} | ||||
| @ -266,15 +250,28 @@ hook_end(struct ovni_emu *emu) | ||||
| static void | ||||
| hook_pre(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 		case 'O': hook_pre_ovni(emu); break; | ||||
| 		case 'V': hook_pre_nosv(emu); break; | ||||
| 		case 'T': hook_pre_tampi(emu); break; | ||||
| 		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; | ||||
| 	switch (emu->cur_ev->header.model) { | ||||
| 		case 'O': | ||||
| 			hook_pre_ovni(emu); | ||||
| 			break; | ||||
| 		case 'V': | ||||
| 			hook_pre_nosv(emu); | ||||
| 			break; | ||||
| 		case 'T': | ||||
| 			hook_pre_tampi(emu); | ||||
| 			break; | ||||
| 		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; | ||||
| 	} | ||||
| @ -283,11 +280,10 @@ hook_pre(struct ovni_emu *emu) | ||||
| static void | ||||
| hook_post(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.model) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.model) { | ||||
| 		default: | ||||
| 			  //dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			  break; | ||||
| 			// dbg("unknown model %c\n", emu->cur_ev->model);
 | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -310,16 +306,17 @@ set_current(struct ovni_emu *emu, struct ovni_stream *stream) | ||||
|  * | ||||
|  * Invert the comparison function to get a min-heap instead | ||||
|  */ | ||||
| static inline int stream_cmp(heap_node_t *a, heap_node_t *b) | ||||
| static inline int | ||||
| stream_cmp(heap_node_t *a, heap_node_t *b) | ||||
| { | ||||
| 	struct ovni_stream *sa, *sb; | ||||
| 
 | ||||
| 	sa = heap_elem(a, struct ovni_stream, hh); | ||||
| 	sb = heap_elem(b, struct ovni_stream, hh); | ||||
| 
 | ||||
| 	if(sb->lastclock < sa->lastclock) | ||||
| 	if (sb->lastclock < sa->lastclock) | ||||
| 		return -1; | ||||
| 	else if(sb->lastclock > sa->lastclock) | ||||
| 	else if (sb->lastclock > sa->lastclock) | ||||
| 		return +1; | ||||
| 	else | ||||
| 		return 0; | ||||
| @ -330,7 +327,7 @@ get_time(void) | ||||
| { | ||||
| 	struct timespec ts; | ||||
| 	clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
| 	return (double)ts.tv_sec + (double)ts.tv_nsec * 1.0e-9; | ||||
| 	return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -346,8 +343,7 @@ print_progress(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	written = cpu_written + th_written; | ||||
| 
 | ||||
| 	progress = ((double) emu->global_offset) / | ||||
| 		((double) emu->global_size); | ||||
| 	progress = ((double) emu->global_offset) / ((double) emu->global_size); | ||||
| 
 | ||||
| 	time_now = get_time(); | ||||
| 	time_elapsed = time_now - emu->start_emulation_time; | ||||
| @ -361,12 +357,12 @@ print_progress(struct ovni_emu *emu) | ||||
| 	sec = (int) ((time_left / 60.0 - min) * 60); | ||||
| 
 | ||||
| 	err("%.1f%% done at %.0f Kev/s, out %.1f GB CPU / %.1f GB TH at %.1f MB/s (%d min %d s left)\n", | ||||
| 			100.0 * progress, | ||||
| 			speed_in / 1024.0, | ||||
| 			cpu_written / (1024.0 * 1024.0 * 1024.0), | ||||
| 			th_written / (1024.0 * 1024.0 * 1024.0), | ||||
| 			speed_out / (1024.0 * 1024), | ||||
| 			min, sec); | ||||
| 		100.0 * progress, | ||||
| 		speed_in / 1024.0, | ||||
| 		cpu_written / (1024.0 * 1024.0 * 1024.0), | ||||
| 		th_written / (1024.0 * 1024.0 * 1024.0), | ||||
| 		speed_out / (1024.0 * 1024), | ||||
| 		min, sec); | ||||
| } | ||||
| 
 | ||||
| /* Loads the next event and sets the lastclock in the stream.
 | ||||
| @ -374,7 +370,7 @@ print_progress(struct ovni_emu *emu) | ||||
| static int | ||||
| emu_step_stream(struct ovni_emu *emu, struct ovni_stream *stream) | ||||
| { | ||||
| 	if(ovni_load_next_event(stream) < 0) | ||||
| 	if (ovni_load_next_event(stream) < 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	stream->lastclock = evclock(stream, stream->cur_ev); | ||||
| @ -396,19 +392,19 @@ next_event(struct ovni_emu *emu) | ||||
| 	node = heap_pop_max(&emu->sorted_stream, stream_cmp); | ||||
| 
 | ||||
| 	/* No more streams */ | ||||
| 	if(node == NULL) | ||||
| 	if (node == NULL) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	stream = heap_elem(node, struct ovni_stream, hh); | ||||
| 
 | ||||
| 	if(stream == NULL) | ||||
| 	if (stream == NULL) | ||||
| 		die("next_event: heap_elem returned NULL\n"); | ||||
| 
 | ||||
| 	set_current(emu, stream); | ||||
| 
 | ||||
| 	emu->global_offset += ovni_ev_size(stream->cur_ev); | ||||
| 
 | ||||
| 	//err("stream %d clock at %ld\n", stream->tid, stream->lastclock);
 | ||||
| 	// err("stream %d clock at %ld\n", stream->tid, stream->lastclock);
 | ||||
| 
 | ||||
| 	/* This can happen if two events are not ordered in the stream, but the
 | ||||
| 	 * emulator picks other events in the middle. Example: | ||||
| @ -423,19 +419,17 @@ next_event(struct ovni_emu *emu) | ||||
| 	 * 12 | ||||
| 	 * ... | ||||
| 	 * */ | ||||
| 	if(emu->lastclock > stream->lastclock) | ||||
| 	{ | ||||
| 	if (emu->lastclock > stream->lastclock) { | ||||
| 		err("warning: backwards jump in time %lu -> %lu for tid %d\n", | ||||
| 				emu->lastclock, stream->lastclock, stream->tid); | ||||
| 			emu->lastclock, stream->lastclock, stream->tid); | ||||
| 
 | ||||
| 		if(emu->enable_linter) | ||||
| 		if (emu->enable_linter) | ||||
| 			abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	emu->lastclock = stream->lastclock; | ||||
| 
 | ||||
| 	if(!done_first) | ||||
| 	{ | ||||
| 	if (!done_first) { | ||||
| 		done_first = 1; | ||||
| 		emu->firstclock = emu->lastclock; | ||||
| 	} | ||||
| @ -459,16 +453,14 @@ emu_load_first_events(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	/* Load initial streams and events */ | ||||
| 	trace = &emu->trace; | ||||
| 	for(i=0; i<trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nstreams; i++) { | ||||
| 		stream = &trace->stream[i]; | ||||
| 		emu->global_size += stream->size; | ||||
| 
 | ||||
| 		if(emu_step_stream(emu, stream) < 0) | ||||
| 		{ | ||||
| 		if (emu_step_stream(emu, stream) < 0) { | ||||
| 			err("warning: empty stream for tid %d\n", stream->tid); | ||||
| 
 | ||||
| 			if(emu->enable_linter) | ||||
| 			if (emu->enable_linter) | ||||
| 				abort(); | ||||
| 
 | ||||
| 			continue; | ||||
| @ -494,8 +486,7 @@ emulate(struct ovni_emu *emu) | ||||
| 	emit_channels(emu); | ||||
| 
 | ||||
| 	/* Then process all events */ | ||||
| 	for(i=0; next_event(emu) == 0; i++) | ||||
| 	{ | ||||
| 	for (i = 0; next_event(emu) == 0; i++) { | ||||
| 		print_cur_ev(emu); | ||||
| 
 | ||||
| 		hook_pre(emu); | ||||
| @ -505,8 +496,7 @@ emulate(struct ovni_emu *emu) | ||||
| 
 | ||||
| 		hook_post(emu); | ||||
| 
 | ||||
| 		if(i >= 50000) | ||||
| 		{ | ||||
| 		if (i >= 50000) { | ||||
| 			print_progress(emu); | ||||
| 			i = 0; | ||||
| 		} | ||||
| @ -527,10 +517,9 @@ emu_get_thread(struct ovni_eproc *proc, int tid) | ||||
| 	size_t i; | ||||
| 	struct ovni_ethread *thread; | ||||
| 
 | ||||
| 	for(i=0; i<proc->nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < proc->nthreads; i++) { | ||||
| 		thread = &proc->thread[i]; | ||||
| 		if(thread->tid == tid) | ||||
| 		if (thread->tid == tid) | ||||
| 			return thread; | ||||
| 	} | ||||
| 
 | ||||
| @ -544,13 +533,13 @@ add_new_cpu(struct ovni_emu *emu, struct ovni_loom *loom, int i, int phyid) | ||||
| 
 | ||||
| 	cpu = &loom->cpu[i]; | ||||
| 
 | ||||
| 	if(i < 0 || i >= (int) loom->ncpus) | ||||
| 	if (i < 0 || i >= (int) loom->ncpus) | ||||
| 		die("CPU with index %d in loom %s is out of bounds\n", | ||||
| 				i, loom->hostname); | ||||
| 			i, loom->hostname); | ||||
| 
 | ||||
| 	if(cpu->state != CPU_ST_UNKNOWN) | ||||
| 	if (cpu->state != CPU_ST_UNKNOWN) | ||||
| 		die("new cpu %d in unexpected state in loom %s\n", | ||||
| 				i, loom->hostname); | ||||
| 			i, loom->hostname); | ||||
| 
 | ||||
| 	cpu->state = CPU_ST_READY; | ||||
| 	cpu->i = i; | ||||
| @ -563,43 +552,42 @@ add_new_cpu(struct ovni_emu *emu, struct ovni_loom *loom, int i, int phyid) | ||||
| 
 | ||||
| static int | ||||
| proc_load_cpus(struct ovni_emu *emu, struct ovni_loom *loom, | ||||
| 		struct ovni_eproc *proc, | ||||
| 		struct ovni_eproc *metadata_proc) | ||||
| 	struct ovni_eproc *proc, | ||||
| 	struct ovni_eproc *metadata_proc) | ||||
| { | ||||
| 	JSON_Object *meta = json_value_get_object(proc->meta); | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("json_value_get_object() failed\n"); | ||||
| 
 | ||||
| 	JSON_Array *cpuarray = json_object_get_array(meta, "cpus"); | ||||
| 
 | ||||
| 	/* This process doesn't have the cpu list */ | ||||
| 	if(cpuarray == NULL) | ||||
| 	if (cpuarray == NULL) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	if(metadata_proc) | ||||
| 	if (metadata_proc) | ||||
| 		die("duplicated metadata for proc %d and %d in loom %s\n", | ||||
| 				metadata_proc->pid, proc->pid, | ||||
| 				loom->hostname); | ||||
| 			metadata_proc->pid, proc->pid, | ||||
| 			loom->hostname); | ||||
| 
 | ||||
| 	if(loom->ncpus != 0) | ||||
| 	if (loom->ncpus != 0) | ||||
| 		die("loom %s already has CPUs\n", loom->hostname); | ||||
| 
 | ||||
| 	loom->ncpus = json_array_get_count(cpuarray); | ||||
| 
 | ||||
| 	if(loom->ncpus == 0) | ||||
| 	if (loom->ncpus == 0) | ||||
| 		die("loom %s proc %d has metadata but no CPUs\n", | ||||
| 				loom->hostname, proc->pid); | ||||
| 			loom->hostname, proc->pid); | ||||
| 
 | ||||
| 	loom->cpu = calloc(loom->ncpus, sizeof(struct ovni_cpu)); | ||||
| 
 | ||||
| 	if(loom->cpu == NULL) | ||||
| 	if (loom->cpu == NULL) | ||||
| 		die("calloc failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	for(size_t i = 0; i < loom->ncpus; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < loom->ncpus; i++) { | ||||
| 		JSON_Object *cpu = json_array_get_object(cpuarray, i); | ||||
| 
 | ||||
| 		if(cpu == NULL) | ||||
| 		if (cpu == NULL) | ||||
| 			die("proc_load_cpus: json_array_get_object() failed\n"); | ||||
| 
 | ||||
| 		int index = (int) json_object_get_number(cpu, "index"); | ||||
| @ -612,9 +600,9 @@ proc_load_cpus(struct ovni_emu *emu, struct ovni_loom *loom, | ||||
| 
 | ||||
| 	/* Init the vcpu as well */ | ||||
| 	struct ovni_cpu *vcpu = &loom->vcpu; | ||||
| 	if(vcpu->state != CPU_ST_UNKNOWN) | ||||
| 	if (vcpu->state != CPU_ST_UNKNOWN) | ||||
| 		die("unexpected virtual CPU state in loom %s\n", | ||||
| 				loom->hostname); | ||||
| 			loom->hostname); | ||||
| 
 | ||||
| 	vcpu->state = CPU_ST_READY; | ||||
| 	vcpu->i = -1; | ||||
| @ -638,33 +626,31 @@ load_metadata(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		loom->offset_ncpus = emu->total_ncpus; | ||||
| 
 | ||||
| 		struct ovni_eproc *metadata_proc = NULL; | ||||
| 
 | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 
 | ||||
| 			if(proc_load_cpus(emu, loom, proc, metadata_proc) < 0) | ||||
| 			if (proc_load_cpus(emu, loom, proc, metadata_proc) < 0) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if(metadata_proc) | ||||
| 			if (metadata_proc) | ||||
| 				die("duplicated metadata found in pid %d and %d\n", | ||||
| 						metadata_proc->pid, | ||||
| 						proc->pid); | ||||
| 					metadata_proc->pid, | ||||
| 					proc->pid); | ||||
| 
 | ||||
| 			metadata_proc = proc; | ||||
| 		} | ||||
| 
 | ||||
| 		/* One of the process must have the list of CPUs */ | ||||
| 		if(metadata_proc == NULL) | ||||
| 		if (metadata_proc == NULL) | ||||
| 			die("no metadata found in loom %s\n", loom->hostname); | ||||
| 
 | ||||
| 		if(loom->ncpus == 0) | ||||
| 		if (loom->ncpus == 0) | ||||
| 			die("no CPUs found in loom %s\n", loom->hostname); | ||||
| 	} | ||||
| } | ||||
| @ -679,14 +665,12 @@ destroy_metadata(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 
 | ||||
| 			if(proc->meta == NULL) | ||||
| 			if (proc->meta == NULL) | ||||
| 				die("cannot destroy metadata: is NULL\n"); | ||||
| 
 | ||||
| 			json_value_free(proc->meta); | ||||
| @ -707,10 +691,9 @@ open_prvs(struct ovni_emu *emu, char *tracedir) | ||||
| 
 | ||||
| 	emu->prv_thread = fopen(path, "w"); | ||||
| 
 | ||||
| 	if(emu->prv_thread == NULL) | ||||
| 	{ | ||||
| 	if (emu->prv_thread == NULL) { | ||||
| 		err("error opening thread PRV file %s: %s\n", path, | ||||
| 				strerror(errno)); | ||||
| 			strerror(errno)); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| @ -718,10 +701,9 @@ open_prvs(struct ovni_emu *emu, char *tracedir) | ||||
| 
 | ||||
| 	emu->prv_cpu = fopen(path, "w"); | ||||
| 
 | ||||
| 	if(emu->prv_cpu == NULL) | ||||
| 	{ | ||||
| 	if (emu->prv_cpu == NULL) { | ||||
| 		err("error opening cpu PRV file %s: %s\n", path, | ||||
| 				strerror(errno)); | ||||
| 			strerror(errno)); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| @ -788,10 +770,8 @@ parse_args(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| { | ||||
| 	int opt; | ||||
| 
 | ||||
| 	while((opt = getopt(argc, argv, "c:l")) != -1) | ||||
| 	{ | ||||
| 		switch(opt) | ||||
| 		{ | ||||
| 	while ((opt = getopt(argc, argv, "c:l")) != -1) { | ||||
| 		switch (opt) { | ||||
| 			case 'c': | ||||
| 				emu->clock_offset_file = optarg; | ||||
| 				break; | ||||
| @ -803,8 +783,7 @@ parse_args(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(optind >= argc) | ||||
| 	{ | ||||
| 	if (optind >= argc) { | ||||
| 		err("missing tracedir\n"); | ||||
| 		usage(argc, argv); | ||||
| 	} | ||||
| @ -817,22 +796,21 @@ set_clock_offsets(struct ovni_emu *emu, const char *host, size_t offset) | ||||
| { | ||||
| 	size_t matches = 0; | ||||
| 
 | ||||
| 	for(size_t i = 0; i < emu->trace.nlooms; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < emu->trace.nlooms; i++) { | ||||
| 		struct ovni_loom *loom = &emu->trace.loom[i]; | ||||
| 
 | ||||
| 		/* Match the hostname exactly */ | ||||
| 		if(strcmp(loom->hostname, host) != 0) | ||||
| 		if (strcmp(loom->hostname, host) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if(loom->clock_offset != 0) | ||||
| 		if (loom->clock_offset != 0) | ||||
| 			die("loom %s already has a clock offset\n", loom->dname); | ||||
| 
 | ||||
| 		loom->clock_offset = offset; | ||||
| 		matches++; | ||||
| 	} | ||||
| 
 | ||||
| 	if(matches == 0) | ||||
| 	if (matches == 0) | ||||
| 		die("no loom has hostname %s\n", host); | ||||
| } | ||||
| 
 | ||||
| @ -849,53 +827,44 @@ load_clock_offsets(struct ovni_emu *emu) | ||||
| 	struct ovni_trace *trace; | ||||
| 	struct ovni_stream *stream; | ||||
| 
 | ||||
| 	if(emu->clock_offset_file != NULL) | ||||
| 	{ | ||||
| 	if (emu->clock_offset_file != NULL) { | ||||
| 		f = fopen(emu->clock_offset_file, "r"); | ||||
| 
 | ||||
| 		/* If provided by the user, it must exist */ | ||||
| 		if(f == NULL) | ||||
| 		{ | ||||
| 		if (f == NULL) { | ||||
| 			err("error opening clock offset file %s: %s\n", | ||||
| 					emu->clock_offset_file, | ||||
| 					strerror(errno)); | ||||
| 				emu->clock_offset_file, | ||||
| 				strerror(errno)); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		char path[PATH_MAX]; | ||||
| 		if(snprintf(path, PATH_MAX, "%s/clock-offsets.txt", | ||||
| 					emu->tracedir) >= PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(path, PATH_MAX, "%s/clock-offsets.txt", | ||||
| 			    emu->tracedir) | ||||
| 			>= PATH_MAX) { | ||||
| 			die("clock offset path too long\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		f = fopen(path, "r"); | ||||
| 
 | ||||
| 		if(f == NULL) | ||||
| 		{ | ||||
| 		if (f == NULL) { | ||||
| 			/* May not exist, but is fine */ | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Ignore header line */ | ||||
| 	if(fgets(buf, 1024, f) == NULL) | ||||
| 	{ | ||||
| 	if (fgets(buf, 1024, f) == NULL) { | ||||
| 		perror("fgets failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	while(1) | ||||
| 	{ | ||||
| 	while (1) { | ||||
| 		errno = 0; | ||||
| 		ret = fscanf(f, "%d %s %lf %lf %lf", &rank, host, &offset, &mean, &std); | ||||
| 
 | ||||
| 		if(ret == EOF) | ||||
| 		{ | ||||
| 			if(errno != 0) | ||||
| 			{ | ||||
| 		if (ret == EOF) { | ||||
| 			if (errno != 0) { | ||||
| 				perror("fscanf failed"); | ||||
| 				exit(EXIT_FAILURE); | ||||
| 			} | ||||
| @ -903,10 +872,9 @@ load_clock_offsets(struct ovni_emu *emu) | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if(ret != 5) | ||||
| 		{ | ||||
| 		if (ret != 5) { | ||||
| 			err("fscanf read %d instead of 5 fields in %s\n", | ||||
| 					ret, emu->clock_offset_file); | ||||
| 				ret, emu->clock_offset_file); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 
 | ||||
| @ -917,8 +885,7 @@ load_clock_offsets(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nstreams; i++) { | ||||
| 		stream = &trace->stream[i]; | ||||
| 		loom = stream->loom; | ||||
| 		stream->clock_offset = loom->clock_offset; | ||||
| @ -941,8 +908,7 @@ write_row_cpu(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	f = fopen(path, "w"); | ||||
| 
 | ||||
| 	if(f == NULL) | ||||
| 	{ | ||||
| 	if (f == NULL) { | ||||
| 		perror("cannot open row file"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -953,8 +919,7 @@ write_row_cpu(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	fprintf(f, "LEVEL THREAD SIZE %ld\n", emu->total_ncpus); | ||||
| 
 | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_ncpus; i++) { | ||||
| 		cpu = emu->global_cpu[i]; | ||||
| 		fprintf(f, "%s\n", cpu->name); | ||||
| 	} | ||||
| @ -974,8 +939,7 @@ write_row_thread(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	f = fopen(path, "w"); | ||||
| 
 | ||||
| 	if(f == NULL) | ||||
| 	{ | ||||
| 	if (f == NULL) { | ||||
| 		perror("cannot open row file"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -986,8 +950,7 @@ write_row_thread(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	fprintf(f, "LEVEL THREAD SIZE %ld\n", emu->total_nthreads); | ||||
| 
 | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		fprintf(f, "THREAD %d.%d\n", th->proc->appid, th->tid); | ||||
| 	} | ||||
| @ -1009,15 +972,12 @@ init_threads(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 			emu->total_nprocs++; | ||||
| 			for(k=0; k<proc->nthreads; k++) | ||||
| 			{ | ||||
| 			for (k = 0; k < proc->nthreads; k++) { | ||||
| 				thread = &proc->thread[k]; | ||||
| 				emu->total_nthreads++; | ||||
| 			} | ||||
| @ -1025,22 +985,18 @@ init_threads(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	emu->global_thread = calloc(emu->total_nthreads, | ||||
| 			sizeof(*emu->global_thread)); | ||||
| 		sizeof(*emu->global_thread)); | ||||
| 
 | ||||
| 	if(emu->global_thread == NULL) | ||||
| 	{ | ||||
| 	if (emu->global_thread == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	for(gi=0, i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (gi = 0, i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 			for(k=0; k<proc->nthreads; k++) | ||||
| 			{ | ||||
| 			for (k = 0; k < proc->nthreads; k++) { | ||||
| 				thread = &proc->thread[k]; | ||||
| 
 | ||||
| 				emu->global_thread[gi++] = thread; | ||||
| @ -1060,25 +1016,22 @@ init_cpus(struct ovni_emu *emu) | ||||
| 	trace = &emu->trace; | ||||
| 
 | ||||
| 	emu->global_cpu = calloc(emu->total_ncpus, | ||||
| 			sizeof(*emu->global_cpu)); | ||||
| 		sizeof(*emu->global_cpu)); | ||||
| 
 | ||||
| 	if(emu->global_cpu == NULL) | ||||
| 	{ | ||||
| 	if (emu->global_cpu == NULL) { | ||||
| 		perror("calloc"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->ncpus; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->ncpus; j++) { | ||||
| 			cpu = &loom->cpu[j]; | ||||
| 			emu->global_cpu[cpu->gindex] = cpu; | ||||
| 
 | ||||
| 			if(snprintf(cpu->name, MAX_CPU_NAME, "CPU %ld.%ld", | ||||
| 						i, j) >= MAX_CPU_NAME) | ||||
| 			{ | ||||
| 			if (snprintf(cpu->name, MAX_CPU_NAME, "CPU %ld.%ld", | ||||
| 				    i, j) | ||||
| 				>= MAX_CPU_NAME) { | ||||
| 				err("error cpu %ld.%ld name too long\n", i, j); | ||||
| 				exit(EXIT_FAILURE); | ||||
| 			} | ||||
| @ -1086,9 +1039,9 @@ init_cpus(struct ovni_emu *emu) | ||||
| 		} | ||||
| 
 | ||||
| 		emu->global_cpu[loom->vcpu.gindex] = &loom->vcpu; | ||||
| 		if(snprintf(loom->vcpu.name, MAX_CPU_NAME, "CPU %ld.*", | ||||
| 					i) >= MAX_CPU_NAME) | ||||
| 		{ | ||||
| 		if (snprintf(loom->vcpu.name, MAX_CPU_NAME, "CPU %ld.*", | ||||
| 			    i) | ||||
| 			>= MAX_CPU_NAME) { | ||||
| 			err("error cpu %ld.* name too long\n", i); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| @ -1104,11 +1057,10 @@ create_pcf_cpus(struct ovni_emu *emu) | ||||
| 	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++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < emu->total_ncpus; i++) { | ||||
| 		int value = i + 1; | ||||
| 		char *label = emu->global_cpu[i]->name; | ||||
| 
 | ||||
| @ -1123,14 +1075,12 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| 
 | ||||
| 	parse_args(emu, argc, argv); | ||||
| 
 | ||||
| 	if(ovni_load_trace(&emu->trace, emu->tracedir)) | ||||
| 	{ | ||||
| 	if (ovni_load_trace(&emu->trace, emu->tracedir)) { | ||||
| 		err("error loading ovni trace\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	if(ovni_load_streams(&emu->trace)) | ||||
| 	{ | ||||
| 	if (ovni_load_streams(&emu->trace)) { | ||||
| 		err("error loading streams\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -1151,8 +1101,8 @@ emu_init(struct ovni_emu *emu, int argc, char *argv[]) | ||||
| 	emu->global_offset = 0; | ||||
| 
 | ||||
| 	err("loaded %ld cpus and %ld threads\n", | ||||
| 			emu->total_ncpus, | ||||
| 			emu->total_nthreads); | ||||
| 		emu->total_ncpus, | ||||
| 		emu->total_nthreads); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -1181,41 +1131,41 @@ emu_destroy(struct ovni_emu *emu) | ||||
| } | ||||
| 
 | ||||
| void | ||||
| edie(struct ovni_emu *emu, const char* fmt, ...) | ||||
| edie(struct ovni_emu *emu, const char *fmt, ...) | ||||
| { | ||||
|     va_list args; | ||||
|     va_start(args, fmt); | ||||
| 	va_list args; | ||||
| 	va_start(args, fmt); | ||||
| 
 | ||||
|     fprintf(stderr, "fatal: "); | ||||
|     vfprintf(stderr, fmt, args); | ||||
|     va_end(args); | ||||
| 	fprintf(stderr, "fatal: "); | ||||
| 	vfprintf(stderr, fmt, args); | ||||
| 	va_end(args); | ||||
| 
 | ||||
|     fprintf(stderr, "fatal: while evaluating the event %c%c%c with clock=%ld in thread=%d\n", | ||||
| 		    emu->cur_ev->header.model, | ||||
| 		    emu->cur_ev->header.category, | ||||
| 		    emu->cur_ev->header.value, | ||||
| 		    emu->cur_ev->header.clock, | ||||
| 		    emu->cur_thread->tid); | ||||
| 	fprintf(stderr, "fatal: while evaluating the event %c%c%c with clock=%ld in thread=%d\n", | ||||
| 		emu->cur_ev->header.model, | ||||
| 		emu->cur_ev->header.category, | ||||
| 		emu->cur_ev->header.value, | ||||
| 		emu->cur_ev->header.clock, | ||||
| 		emu->cur_thread->tid); | ||||
| 
 | ||||
|     abort(); | ||||
| 	abort(); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| eerr(struct ovni_emu *emu, const char* fmt, ...) | ||||
| eerr(struct ovni_emu *emu, const char *fmt, ...) | ||||
| { | ||||
|     va_list args; | ||||
|     va_start(args, fmt); | ||||
| 	va_list args; | ||||
| 	va_start(args, fmt); | ||||
| 
 | ||||
|     fprintf(stderr, "fatal: "); | ||||
|     vfprintf(stderr, fmt, args); | ||||
|     va_end(args); | ||||
| 	fprintf(stderr, "fatal: "); | ||||
| 	vfprintf(stderr, fmt, args); | ||||
| 	va_end(args); | ||||
| 
 | ||||
|     fprintf(stderr, "fatal: while evaluating the event %c%c%c with clock=%ld in thread=%d\n", | ||||
| 		    emu->cur_ev->header.model, | ||||
| 		    emu->cur_ev->header.category, | ||||
| 		    emu->cur_ev->header.value, | ||||
| 		    emu->cur_ev->header.clock, | ||||
| 		    emu->cur_thread->tid); | ||||
| 	fprintf(stderr, "fatal: while evaluating the event %c%c%c with clock=%ld in thread=%d\n", | ||||
| 		emu->cur_ev->header.model, | ||||
| 		emu->cur_ev->header.category, | ||||
| 		emu->cur_ev->header.value, | ||||
| 		emu->cur_ev->header.clock, | ||||
| 		emu->cur_thread->tid); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| @ -1225,8 +1175,7 @@ main(int argc, char *argv[]) | ||||
| 
 | ||||
| 	emu = malloc(sizeof(struct ovni_emu)); | ||||
| 
 | ||||
| 	if(emu == NULL) | ||||
| 	{ | ||||
| 	if (emu == NULL) { | ||||
| 		perror("malloc"); | ||||
| 		return 1; | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										34
									
								
								emu.h
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								emu.h
									
									
									
									
									
								
							| @ -7,11 +7,11 @@ | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "ovni.h" | ||||
| #include "uthash.h" | ||||
| #include "parson.h" | ||||
| #include "heap.h" | ||||
| #include "ovni.h" | ||||
| #include "parson.h" | ||||
| #include "pcf.h" | ||||
| #include "uthash.h" | ||||
| 
 | ||||
| /* Emulated thread runtime status */ | ||||
| enum ethread_state { | ||||
| @ -136,8 +136,8 @@ struct ovni_ethread; | ||||
| struct ovni_eproc; | ||||
| 
 | ||||
| struct task_type { | ||||
| 	uint32_t id;    /* Per-process task identifier */ | ||||
| 	uint32_t gid;   /* Global identifier computed from the label */ | ||||
| 	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; | ||||
| }; | ||||
| @ -158,17 +158,17 @@ struct task { | ||||
| }; | ||||
| 
 | ||||
| struct task_info { | ||||
|     /* Both hash maps of all known tasks and types */ | ||||
|     struct task_type *types; | ||||
|     struct task *tasks; | ||||
| 	/* Both hash maps of all known tasks and types */ | ||||
| 	struct task_type *types; | ||||
| 	struct task *tasks; | ||||
| }; | ||||
| 
 | ||||
| struct task_stack { | ||||
|     union { | ||||
|         struct task *top; /* Synctactic sugar */ | ||||
|         struct task *tasks; | ||||
|     }; | ||||
|     struct ovni_ethread *thread; | ||||
| 	union { | ||||
| 		struct task *top; /* Synctactic sugar */ | ||||
| 		struct task *tasks; | ||||
| 	}; | ||||
| 	struct ovni_ethread *thread; | ||||
| }; | ||||
| 
 | ||||
| #define MAX_CHAN_STACK 512 | ||||
| @ -383,7 +383,7 @@ struct ovni_eproc { | ||||
| 	/* TODO: Use dynamic allocation */ | ||||
| 
 | ||||
| 	struct task_info nosv_task_info; | ||||
|     struct task_info nanos6_task_info; | ||||
| 	struct task_info nanos6_task_info; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| @ -445,7 +445,7 @@ struct ovni_loom { | ||||
| 	size_t nprocs; | ||||
| 	char hostname[OVNI_MAX_HOSTNAME]; | ||||
| 	char dname[PATH_MAX]; /* Loom directory name */ | ||||
| 	char path[PATH_MAX]; /* Relative to cwd */ | ||||
| 	char path[PATH_MAX];  /* Relative to cwd */ | ||||
| 
 | ||||
| 	size_t max_ncpus; | ||||
| 	size_t max_phyid; | ||||
| @ -546,8 +546,8 @@ struct ovni_emu { | ||||
| 
 | ||||
| /* Emulator function declaration */ | ||||
| 
 | ||||
| void edie(struct ovni_emu *emu, const char* fmt, ...); | ||||
| void eerr(struct ovni_emu *emu, const char* fmt, ...); | ||||
| void edie(struct ovni_emu *emu, const char *fmt, ...); | ||||
| void eerr(struct ovni_emu *emu, const char *fmt, ...); | ||||
| 
 | ||||
| void hook_init_ovni(struct ovni_emu *emu); | ||||
| void hook_pre_ovni(struct ovni_emu *emu); | ||||
|  | ||||
							
								
								
									
										28
									
								
								emu_kernel.c
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								emu_kernel.c
									
									
									
									
									
								
							| @ -3,11 +3,11 @@ | ||||
| 
 | ||||
| #include "uthash.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "trace.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| #include "trace.h" | ||||
| 
 | ||||
| /* --------------------------- init ------------------------------- */ | ||||
| 
 | ||||
| @ -27,8 +27,7 @@ hook_init_kernel(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		row = th->gindex + 1; | ||||
| 		uth = &emu->th_chan; | ||||
| @ -37,8 +36,7 @@ hook_init_kernel(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_ncpus; i++) { | ||||
| 		cpu = emu->global_cpu[i]; | ||||
| 		row = cpu->gindex + 1; | ||||
| 		ucpu = &emu->cpu_chan; | ||||
| @ -58,8 +56,7 @@ context_switch(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan = &th->chan[CHAN_KERNEL_CS]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'O': | ||||
| 			chan_push(chan, ST_KERNEL_CSOUT); | ||||
| 			break; | ||||
| @ -68,24 +65,23 @@ context_switch(struct ovni_emu *emu) | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected value '%c' (expecting 'O' or 'I')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_kernel(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != 'K') | ||||
| 	if (emu->cur_ev->header.model != 'K') | ||||
| 		edie(emu, "hook_pre_kernel: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'C': | ||||
| 			context_switch(emu); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "hook_pre_kernel: unexpected event with category %c\n", | ||||
| 					emu->cur_ev->header.category); | ||||
| 				emu->cur_ev->header.category); | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										419
									
								
								emu_nanos6.c
									
									
									
									
									
								
							
							
						
						
									
										419
									
								
								emu_nanos6.c
									
									
									
									
									
								
							| @ -4,11 +4,11 @@ | ||||
| #include "uthash.h" | ||||
| #include "utlist.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "emu_task.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| 
 | ||||
| void | ||||
| hook_init_nanos6(struct ovni_emu *emu) | ||||
| @ -25,37 +25,34 @@ hook_init_nanos6(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(size_t i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (size_t 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); | ||||
| 		chan_th_init(th, uth, CHAN_NANOS6_THREAD,    CHAN_TRACK_NONE,       0, 1, 1, row, prv_th, clock); | ||||
| 		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); | ||||
| 		chan_th_init(th, uth, CHAN_NANOS6_THREAD, CHAN_TRACK_NONE, 0, 1, 1, row, prv_th, clock); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the Nanos6 channels in all cpus */ | ||||
| 	for(size_t i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (size_t 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_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); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NANOS6_THREAD,    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); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NANOS6_THREAD, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init task stack */ | ||||
| 	for(size_t i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		th->nanos6_task_stack.thread = th; | ||||
| 	} | ||||
| @ -72,7 +69,7 @@ chan_task_stopped(struct ovni_emu *emu) | ||||
| 	chan_set(&th->chan[CHAN_NANOS6_TASKID], 0); | ||||
| 	chan_set(&th->chan[CHAN_NANOS6_TYPE], 0); | ||||
| 
 | ||||
| 	if(emu->cur_loom->rank_enabled) | ||||
| 	if (emu->cur_loom->rank_enabled) | ||||
| 		chan_set(&th->chan[CHAN_NANOS6_RANK], 0); | ||||
| } | ||||
| 
 | ||||
| @ -85,41 +82,41 @@ chan_task_running(struct ovni_emu *emu, struct task *task) | ||||
| 	th = emu->cur_thread; | ||||
| 	proc = emu->cur_proc; | ||||
| 
 | ||||
| 	if(task->id == 0) | ||||
| 	if (task->id == 0) | ||||
| 		edie(emu, "task id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(task->type->gid == 0) | ||||
| 	if (task->type->gid == 0) | ||||
| 		edie(emu, "task type gid cannot be 0\n"); | ||||
| 
 | ||||
| 	if(proc->appid <= 0) | ||||
| 	if (proc->appid <= 0) | ||||
| 		edie(emu, "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) | ||||
| 	if (emu->cur_loom->rank_enabled) | ||||
| 		chan_set(&th->chan[CHAN_NANOS6_RANK], proc->rank + 1); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| chan_task_switch(struct ovni_emu *emu, | ||||
| 		struct task *prev, struct task *next) | ||||
| 	struct task *prev, struct task *next) | ||||
| { | ||||
| 	struct ovni_ethread *th = emu->cur_thread; | ||||
| 
 | ||||
| 	if(!prev || !next) | ||||
| 	if (!prev || !next) | ||||
| 		edie(emu, "cannot switch to or from a NULL task\n"); | ||||
| 
 | ||||
| 	if(prev == next) | ||||
| 	if (prev == next) | ||||
| 		edie(emu, "cannot switch to the same task\n"); | ||||
| 
 | ||||
| 	if(next->id == 0) | ||||
| 	if (next->id == 0) | ||||
| 		edie(emu, "next task id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(next->type->gid == 0) | ||||
| 	if (next->type->gid == 0) | ||||
| 		edie(emu, "next task type id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(prev->thread != next->thread) | ||||
| 	if (prev->thread != next->thread) | ||||
| 		edie(emu, "cannot switch to a task of another thread\n"); | ||||
| 
 | ||||
| 	/* No need to change the rank as we will switch to tasks from
 | ||||
| @ -130,14 +127,14 @@ chan_task_switch(struct ovni_emu *emu, | ||||
| 	 * 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->type->gid != next->type->gid) | ||||
| 	if (prev->type->gid != next->type->gid) | ||||
| 		chan_set(&th->chan[CHAN_NANOS6_TYPE], next->type->gid); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| update_task_state(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(ovni_payload_size(emu->cur_ev) < 4) | ||||
| 	if (ovni_payload_size(emu->cur_ev) < 4) | ||||
| 		edie(emu, "missing task id in payload\n"); | ||||
| 
 | ||||
| 	uint32_t task_id = emu->cur_ev->payload.u32[0]; | ||||
| @ -150,17 +147,24 @@ update_task_state(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	struct task *task = task_find(info->tasks, task_id); | ||||
| 
 | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot find task with id %u\n", task_id); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'x': task_execute(emu, stack, task); break; | ||||
| 		case 'e': task_end(emu, stack, task); break; | ||||
| 		case 'p': task_pause(emu, stack, task); break; | ||||
| 		case 'r': task_resume(emu, stack, task); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'x': | ||||
| 			task_execute(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'e': | ||||
| 			task_end(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			task_pause(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			task_resume(emu, stack, task); | ||||
| 			break; | ||||
| 		default: | ||||
| 			  edie(emu, "unexpected Nanos6 task event\n"); | ||||
| 			edie(emu, "unexpected Nanos6 task event\n"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -170,13 +174,13 @@ expand_transition_value(struct ovni_emu *emu, int was_running, int runs_now) | ||||
| 	char tr = emu->cur_ev->header.value; | ||||
| 
 | ||||
| 	/* Ensure we don't clobber the value */ | ||||
| 	if(tr == 'X' || tr == 'E') | ||||
| 	if (tr == 'X' || tr == 'E') | ||||
| 		edie(emu, "unexpected event value %c\n", tr); | ||||
| 
 | ||||
| 	/* Modify the event value to detect nested transitions */ | ||||
| 	if(tr == 'x' && was_running) | ||||
| 	if (tr == 'x' && was_running) | ||||
| 		tr = 'X'; /* Execute a new nested task */ | ||||
| 	else if(tr == 'e' && runs_now) | ||||
| 	else if (tr == 'e' && runs_now) | ||||
| 		tr = 'E'; /* End a nested task */ | ||||
| 
 | ||||
| 	return tr; | ||||
| @ -184,10 +188,9 @@ expand_transition_value(struct ovni_emu *emu, int was_running, int runs_now) | ||||
| 
 | ||||
| static void | ||||
| update_task_channels(struct ovni_emu *emu, | ||||
| 		char tr, struct task *prev, struct task *next) | ||||
| 	char tr, struct task *prev, struct task *next) | ||||
| { | ||||
| 	switch(tr) | ||||
| 	{ | ||||
| 	switch (tr) { | ||||
| 		case 'x': | ||||
| 		case 'r': | ||||
| 			chan_task_running(emu, next); | ||||
| @ -208,23 +211,22 @@ update_task_channels(struct ovni_emu *emu, | ||||
| 
 | ||||
| static void | ||||
| enforce_task_rules(struct ovni_emu *emu, | ||||
| 		char tr, struct task *prev, struct task *next) | ||||
| 	char tr, struct task *prev, struct task *next) | ||||
| 
 | ||||
| { | ||||
| 	UNUSED(prev); | ||||
| 
 | ||||
| 	/* If a task has just entered the running state, it must show
 | ||||
| 	 * the running task body subsystem */ | ||||
| 	if(tr == 'x' || tr == 'X') | ||||
| 	{ | ||||
| 		if(next->state != TASK_ST_RUNNING) | ||||
| 	if (tr == 'x' || tr == 'X') { | ||||
| 		if (next->state != TASK_ST_RUNNING) | ||||
| 			edie(emu, "a Nanos6 task starts running but not in the running state\n"); | ||||
| 
 | ||||
| 		struct ovni_ethread *th = emu->cur_thread; | ||||
| 		struct ovni_chan *sschan = &th->chan[CHAN_NANOS6_SUBSYSTEM]; | ||||
| 		int st = chan_get_st(sschan); | ||||
| 
 | ||||
| 		if(st != 0 && st != ST_NANOS6_TASK_BODY) | ||||
| 		if (st != 0 && st != ST_NANOS6_TASK_BODY) | ||||
| 			edie(emu, "a Nanos6 task starts running but not in the \"running body\" subsystem state\n"); | ||||
| 	} | ||||
| } | ||||
| @ -255,7 +257,7 @@ update_task(struct ovni_emu *emu) | ||||
| static void | ||||
| create_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(ovni_payload_size(emu->cur_ev) != 8) | ||||
| 	if (ovni_payload_size(emu->cur_ev) != 8) | ||||
| 		edie(emu, "cannot create task: unexpected payload size\n"); | ||||
| 
 | ||||
| 	uint32_t task_id = emu->cur_ev->payload.u32[0]; | ||||
| @ -269,8 +271,7 @@ create_task(struct ovni_emu *emu) | ||||
| static void | ||||
| pre_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'c': | ||||
| 			create_task(emu); | ||||
| 			break; | ||||
| @ -290,10 +291,10 @@ pre_type(struct ovni_emu *emu) | ||||
| { | ||||
| 	uint8_t value = emu->cur_ev->header.value; | ||||
| 
 | ||||
| 	if(value != 'c') | ||||
| 	if (value != 'c') | ||||
| 		edie(emu, "unexpected event value %c\n", value); | ||||
| 
 | ||||
| 	if((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) | ||||
| 	if ((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) | ||||
| 		edie(emu, "expecting a jumbo event\n"); | ||||
| 
 | ||||
| 	uint8_t *data = &emu->cur_ev->payload.jumbo.data[0]; | ||||
| @ -316,12 +317,19 @@ pre_deps(struct ovni_emu *emu) | ||||
| 	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; | ||||
| 	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: | ||||
| 			edie(emu, "unknown Nanos6 dependency event\n"); | ||||
| 	} | ||||
| @ -336,16 +344,31 @@ pre_blocking(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'b': chan_push(chan_th, ST_NANOS6_BLK_BLOCKING); break; | ||||
| 		case 'B': chan_pop (chan_th, ST_NANOS6_BLK_BLOCKING); break; | ||||
| 		case 'u': chan_push(chan_th, ST_NANOS6_BLK_UNBLOCKING); break; | ||||
| 		case 'U': chan_pop (chan_th, ST_NANOS6_BLK_UNBLOCKING); break; | ||||
| 		case 'w': chan_push(chan_th, ST_NANOS6_BLK_TASKWAIT); break; | ||||
| 		case 'W': chan_pop (chan_th, ST_NANOS6_BLK_TASKWAIT); break; | ||||
| 		case 'f': chan_push(chan_th, ST_NANOS6_BLK_WAITFOR); break; | ||||
| 		case 'F': chan_pop (chan_th, ST_NANOS6_BLK_WAITFOR); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'b': | ||||
| 			chan_push(chan_th, ST_NANOS6_BLK_BLOCKING); | ||||
| 			break; | ||||
| 		case 'B': | ||||
| 			chan_pop(chan_th, ST_NANOS6_BLK_BLOCKING); | ||||
| 			break; | ||||
| 		case 'u': | ||||
| 			chan_push(chan_th, ST_NANOS6_BLK_UNBLOCKING); | ||||
| 			break; | ||||
| 		case 'U': | ||||
| 			chan_pop(chan_th, ST_NANOS6_BLK_UNBLOCKING); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			chan_push(chan_th, ST_NANOS6_BLK_TASKWAIT); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			chan_pop(chan_th, ST_NANOS6_BLK_TASKWAIT); | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			chan_push(chan_th, ST_NANOS6_BLK_WAITFOR); | ||||
| 			break; | ||||
| 		case 'F': | ||||
| 			chan_pop(chan_th, ST_NANOS6_BLK_WAITFOR); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unknown Nanos6 blocking event\n"); | ||||
| 	} | ||||
| @ -360,21 +383,46 @@ pre_worker(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case '[': chan_push(chan_th, ST_NANOS6_WORKER_LOOP); break; | ||||
| 		case ']': chan_pop (chan_th, ST_NANOS6_WORKER_LOOP); break; | ||||
| 		case 't': chan_push(chan_th, ST_NANOS6_HANDLING_TASK); break; | ||||
| 		case 'T': chan_pop (chan_th, ST_NANOS6_HANDLING_TASK); break; | ||||
| 		case 'w': chan_push(chan_th, ST_NANOS6_SWITCH_TO); break; | ||||
| 		case 'W': chan_pop (chan_th, ST_NANOS6_SWITCH_TO); break; | ||||
| 		case 'm': chan_push(chan_th, ST_NANOS6_MIGRATE); break; | ||||
| 		case 'M': chan_pop (chan_th, ST_NANOS6_MIGRATE); break; | ||||
| 		case 's': chan_push(chan_th, ST_NANOS6_SUSPEND); break; | ||||
| 		case 'S': chan_pop (chan_th, ST_NANOS6_SUSPEND); break; | ||||
| 		case 'r': chan_push(chan_th, ST_NANOS6_RESUME); break; | ||||
| 		case 'R': chan_pop (chan_th, ST_NANOS6_RESUME); break; | ||||
| 		case '*': chan_ev  (chan_th, EV_NANOS6_SIGNAL); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan_th, ST_NANOS6_WORKER_LOOP); | ||||
| 			break; | ||||
| 		case ']': | ||||
| 			chan_pop(chan_th, ST_NANOS6_WORKER_LOOP); | ||||
| 			break; | ||||
| 		case 't': | ||||
| 			chan_push(chan_th, ST_NANOS6_HANDLING_TASK); | ||||
| 			break; | ||||
| 		case 'T': | ||||
| 			chan_pop(chan_th, ST_NANOS6_HANDLING_TASK); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			chan_push(chan_th, ST_NANOS6_SWITCH_TO); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			chan_pop(chan_th, ST_NANOS6_SWITCH_TO); | ||||
| 			break; | ||||
| 		case 'm': | ||||
| 			chan_push(chan_th, ST_NANOS6_MIGRATE); | ||||
| 			break; | ||||
| 		case 'M': | ||||
| 			chan_pop(chan_th, ST_NANOS6_MIGRATE); | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			chan_push(chan_th, ST_NANOS6_SUSPEND); | ||||
| 			break; | ||||
| 		case 'S': | ||||
| 			chan_pop(chan_th, ST_NANOS6_SUSPEND); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			chan_push(chan_th, ST_NANOS6_RESUME); | ||||
| 			break; | ||||
| 		case 'R': | ||||
| 			chan_pop(chan_th, ST_NANOS6_RESUME); | ||||
| 			break; | ||||
| 		case '*': | ||||
| 			chan_ev(chan_th, EV_NANOS6_SIGNAL); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unknown Nanos6 worker event\n"); | ||||
| 	} | ||||
| @ -389,12 +437,19 @@ pre_memory(struct ovni_emu *emu) | ||||
| 	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_ALLOCATING); break; | ||||
| 		case 'A': chan_pop (chan_th, ST_NANOS6_ALLOCATING); break; | ||||
| 		case 'f': chan_push(chan_th, ST_NANOS6_FREEING); break; | ||||
| 		case 'F': chan_pop (chan_th, ST_NANOS6_FREEING); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'a': | ||||
| 			chan_push(chan_th, ST_NANOS6_ALLOCATING); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			chan_pop(chan_th, ST_NANOS6_ALLOCATING); | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			chan_push(chan_th, ST_NANOS6_FREEING); | ||||
| 			break; | ||||
| 		case 'F': | ||||
| 			chan_pop(chan_th, ST_NANOS6_FREEING); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unknown Nanos6 memory event\n"); | ||||
| 	} | ||||
| @ -409,17 +464,34 @@ pre_sched(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NANOS6_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case '[': chan_push(chan_th, ST_NANOS6_SCHED_SERVING); break; | ||||
| 		case ']': chan_pop (chan_th, ST_NANOS6_SCHED_SERVING); break; | ||||
| 		case 'a': chan_push(chan_th, ST_NANOS6_SCHED_ADDING); break; | ||||
| 		case 'A': chan_pop (chan_th, ST_NANOS6_SCHED_ADDING); break; | ||||
| 		case 'p': chan_push(chan_th, ST_NANOS6_SCHED_PROCESSING); break; | ||||
| 		case 'P': chan_pop (chan_th, ST_NANOS6_SCHED_PROCESSING); 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; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan_th, ST_NANOS6_SCHED_SERVING); | ||||
| 			break; | ||||
| 		case ']': | ||||
| 			chan_pop(chan_th, ST_NANOS6_SCHED_SERVING); | ||||
| 			break; | ||||
| 		case 'a': | ||||
| 			chan_push(chan_th, ST_NANOS6_SCHED_ADDING); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			chan_pop(chan_th, ST_NANOS6_SCHED_ADDING); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			chan_push(chan_th, ST_NANOS6_SCHED_PROCESSING); | ||||
| 			break; | ||||
| 		case 'P': | ||||
| 			chan_pop(chan_th, ST_NANOS6_SCHED_PROCESSING); | ||||
| 			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: | ||||
| 			edie(emu, "unknown Nanos6 scheduler event\n"); | ||||
| 	} | ||||
| @ -434,16 +506,31 @@ pre_thread(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NANOS6_THREAD]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'e': chan_push(chan_th, ST_NANOS6_TH_EXTERNAL); break; | ||||
| 		case 'E': chan_pop (chan_th, ST_NANOS6_TH_EXTERNAL); break; | ||||
| 		case 'w': chan_push(chan_th, ST_NANOS6_TH_WORKER); break; | ||||
| 		case 'W': chan_pop (chan_th, ST_NANOS6_TH_WORKER); break; | ||||
| 		case 'l': chan_push(chan_th, ST_NANOS6_TH_LEADER); break; | ||||
| 		case 'L': chan_pop (chan_th, ST_NANOS6_TH_LEADER); break; | ||||
| 		case 'm': chan_push(chan_th, ST_NANOS6_TH_MAIN); break; | ||||
| 		case 'M': chan_pop (chan_th, ST_NANOS6_TH_MAIN); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'e': | ||||
| 			chan_push(chan_th, ST_NANOS6_TH_EXTERNAL); | ||||
| 			break; | ||||
| 		case 'E': | ||||
| 			chan_pop(chan_th, ST_NANOS6_TH_EXTERNAL); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			chan_push(chan_th, ST_NANOS6_TH_WORKER); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			chan_pop(chan_th, ST_NANOS6_TH_WORKER); | ||||
| 			break; | ||||
| 		case 'l': | ||||
| 			chan_push(chan_th, ST_NANOS6_TH_LEADER); | ||||
| 			break; | ||||
| 		case 'L': | ||||
| 			chan_pop(chan_th, ST_NANOS6_TH_LEADER); | ||||
| 			break; | ||||
| 		case 'm': | ||||
| 			chan_push(chan_th, ST_NANOS6_TH_MAIN); | ||||
| 			break; | ||||
| 		case 'M': | ||||
| 			chan_pop(chan_th, ST_NANOS6_TH_MAIN); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unknown Nanos6 thread type event\n"); | ||||
| 	} | ||||
| @ -460,13 +547,16 @@ pre_ss(struct ovni_emu *emu, int st) | ||||
| 
 | ||||
| 	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; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan_th, st); | ||||
| 			break; | ||||
| 		case ']': | ||||
| 			chan_pop(chan_th, st); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected value '%c' (expecting '[' or ']')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -476,16 +566,15 @@ check_affinity(struct ovni_emu *emu) | ||||
| 	struct ovni_ethread *th = emu->cur_thread; | ||||
| 	struct ovni_cpu *cpu = th->cpu; | ||||
| 
 | ||||
| 	if(!cpu || cpu->virtual) | ||||
| 	if (!cpu || cpu->virtual) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(cpu->nrunning_threads > 1) | ||||
| 	{ | ||||
| 	if (cpu->nrunning_threads > 1) { | ||||
| 		eerr(emu, "cpu %s has more than one thread running\n", cpu->name); | ||||
| 
 | ||||
| 		/* Only abort in linter mode so we can still see the
 | ||||
| 		 * trace to find out what was happening */ | ||||
| 		if(emu->enable_linter) | ||||
| 		if (emu->enable_linter) | ||||
| 			abort(); | ||||
| 	} | ||||
| } | ||||
| @ -493,30 +582,55 @@ check_affinity(struct ovni_emu *emu) | ||||
| void | ||||
| hook_pre_nanos6(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != '6') | ||||
| 	if (emu->cur_ev->header.model != '6') | ||||
| 		edie(emu, "hook_pre_nanos6: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	if(!emu->cur_thread->is_active) { | ||||
| 	if (!emu->cur_thread->is_active) { | ||||
| 		edie(emu, "hook_pre_nanos6: current thread %d not active\n", | ||||
| 				emu->cur_thread->tid); | ||||
| 			emu->cur_thread->tid); | ||||
| 	} | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 		case 'T': pre_task(emu); break; | ||||
| 		case 'C': pre_ss(emu, ST_NANOS6_TASK_CREATING); break; | ||||
| 		case 'Y': pre_type(emu); break; | ||||
| 		case 'S': pre_sched(emu); break; | ||||
| 		case 'U': pre_ss(emu, ST_NANOS6_TASK_SUBMIT); break; | ||||
| 		case 'F': pre_ss(emu, ST_NANOS6_TASK_SPAWNING); break; | ||||
| 		case 'O': pre_ss(emu, ST_NANOS6_TASK_FOR); break; | ||||
| 		case 't': pre_ss(emu, ST_NANOS6_TASK_BODY); break; | ||||
| 		case 'H': pre_thread(emu); break; | ||||
| 		case 'D': pre_deps(emu); break; | ||||
| 		case 'B': pre_blocking(emu); break; | ||||
| 		case 'W': pre_worker(emu); break; | ||||
| 		case 'M': pre_memory(emu); break; | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'T': | ||||
| 			pre_task(emu); | ||||
| 			break; | ||||
| 		case 'C': | ||||
| 			pre_ss(emu, ST_NANOS6_TASK_CREATING); | ||||
| 			break; | ||||
| 		case 'Y': | ||||
| 			pre_type(emu); | ||||
| 			break; | ||||
| 		case 'S': | ||||
| 			pre_sched(emu); | ||||
| 			break; | ||||
| 		case 'U': | ||||
| 			pre_ss(emu, ST_NANOS6_TASK_SUBMIT); | ||||
| 			break; | ||||
| 		case 'F': | ||||
| 			pre_ss(emu, ST_NANOS6_TASK_SPAWNING); | ||||
| 			break; | ||||
| 		case 'O': | ||||
| 			pre_ss(emu, ST_NANOS6_TASK_FOR); | ||||
| 			break; | ||||
| 		case 't': | ||||
| 			pre_ss(emu, ST_NANOS6_TASK_BODY); | ||||
| 			break; | ||||
| 		case 'H': | ||||
| 			pre_thread(emu); | ||||
| 			break; | ||||
| 		case 'D': | ||||
| 			pre_deps(emu); | ||||
| 			break; | ||||
| 		case 'B': | ||||
| 			pre_blocking(emu); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			pre_worker(emu); | ||||
| 			break; | ||||
| 		case 'M': | ||||
| 			pre_memory(emu); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unknown Nanos6 event category\n"); | ||||
| 	} | ||||
| @ -528,27 +642,23 @@ static void | ||||
| end_lint(struct ovni_emu *emu) | ||||
| { | ||||
| 	/* Ensure we run out of subsystem states */ | ||||
| 	for(size_t i = 0; i < emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < emu->total_nthreads; i++) { | ||||
| 		struct ovni_ethread *th = emu->global_thread[i]; | ||||
| 		struct ovni_chan *ch = &th->chan[CHAN_NANOS6_SUBSYSTEM]; | ||||
| 		if(ch->n != 1) | ||||
| 		{ | ||||
| 		if (ch->n != 1) { | ||||
| 			int top = ch->stack[ch->n - 1]; | ||||
| 
 | ||||
| 			struct pcf_value_label *pv; | ||||
| 			char *name = "(unknown)"; | ||||
| 			for(pv = &nanos6_ss_values[0]; pv->label; pv++) | ||||
| 			{ | ||||
| 				if(pv->value == top) | ||||
| 				{ | ||||
| 			for (pv = &nanos6_ss_values[0]; pv->label; pv++) { | ||||
| 				if (pv->value == top) { | ||||
| 					name = pv->label; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			die("thread %d ended with %d extra stacked nanos6 subsystems, top=\"%s\"\n", | ||||
| 					th->tid, ch->n - 1, name); | ||||
| 				th->tid, ch->n - 1, name); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -557,17 +667,14 @@ 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++) | ||||
| 	{ | ||||
| 	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++) | ||||
| 		{ | ||||
| 		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++) | ||||
| 			{ | ||||
| 			for (size_t j = 0; j < loom->nprocs; j++) { | ||||
| 				struct ovni_eproc *proc = &loom->proc[j]; | ||||
| 				task_create_pcf_types(pcftype, proc->nanos6_task_info.types); | ||||
| 			} | ||||
| @ -575,6 +682,6 @@ hook_end_nanos6(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* When running in linter mode perform additional checks */ | ||||
| 	if(emu->enable_linter) | ||||
| 	if (emu->enable_linter) | ||||
| 		end_lint(emu); | ||||
| } | ||||
|  | ||||
							
								
								
									
										60
									
								
								emu_nodes.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								emu_nodes.c
									
									
									
									
									
								
							| @ -3,10 +3,10 @@ | ||||
| 
 | ||||
| #include "uthash.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| /* --------------------------- init ------------------------------- */ | ||||
| 
 | ||||
| @ -26,8 +26,7 @@ hook_init_nodes(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		row = th->gindex + 1; | ||||
| 		uth = &emu->th_chan; | ||||
| @ -36,8 +35,7 @@ hook_init_nodes(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_ncpus; i++) { | ||||
| 		cpu = emu->global_cpu[i]; | ||||
| 		row = cpu->gindex + 1; | ||||
| 		ucpu = &emu->cpu_chan; | ||||
| @ -57,8 +55,7 @@ pre_subsystem(struct ovni_emu *emu, int st) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan = &th->chan[CHAN_NODES_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan, st); | ||||
| 			break; | ||||
| @ -67,31 +64,46 @@ pre_subsystem(struct ovni_emu *emu, int st) | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected value '%c' (expecting '[' or ']')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_nodes(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != 'D') | ||||
| 	if (emu->cur_ev->header.model != 'D') | ||||
| 		edie(emu, "hook_pre_nodes: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	if(!emu->cur_thread->is_running) | ||||
| 	if (!emu->cur_thread->is_running) | ||||
| 		edie(emu, "hook_pre_nodes: current thread %d not running\n", | ||||
| 				emu->cur_thread->tid); | ||||
| 			emu->cur_thread->tid); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 		case 'R': pre_subsystem(emu, ST_NODES_REGISTER); break; | ||||
| 		case 'U': pre_subsystem(emu, ST_NODES_UNREGISTER); break; | ||||
| 		case 'W': pre_subsystem(emu, ST_NODES_IF0_WAIT); break; | ||||
| 		case 'I': pre_subsystem(emu, ST_NODES_IF0_INLINE); break; | ||||
| 		case 'T': pre_subsystem(emu, ST_NODES_TASKWAIT); break; | ||||
| 		case 'C': pre_subsystem(emu, ST_NODES_CREATE); break; | ||||
| 		case 'S': pre_subsystem(emu, ST_NODES_SUBMIT); break; | ||||
| 		case 'P': pre_subsystem(emu, ST_NODES_SPAWN); break; | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'R': | ||||
| 			pre_subsystem(emu, ST_NODES_REGISTER); | ||||
| 			break; | ||||
| 		case 'U': | ||||
| 			pre_subsystem(emu, ST_NODES_UNREGISTER); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			pre_subsystem(emu, ST_NODES_IF0_WAIT); | ||||
| 			break; | ||||
| 		case 'I': | ||||
| 			pre_subsystem(emu, ST_NODES_IF0_INLINE); | ||||
| 			break; | ||||
| 		case 'T': | ||||
| 			pre_subsystem(emu, ST_NODES_TASKWAIT); | ||||
| 			break; | ||||
| 		case 'C': | ||||
| 			pre_subsystem(emu, ST_NODES_CREATE); | ||||
| 			break; | ||||
| 		case 'S': | ||||
| 			pre_subsystem(emu, ST_NODES_SUBMIT); | ||||
| 			break; | ||||
| 		case 'P': | ||||
| 			pre_subsystem(emu, ST_NODES_SPAWN); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										289
									
								
								emu_nosv.c
									
									
									
									
									
								
							
							
						
						
									
										289
									
								
								emu_nosv.c
									
									
									
									
									
								
							| @ -4,11 +4,11 @@ | ||||
| #include "uthash.h" | ||||
| #include "utlist.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "emu_task.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| 
 | ||||
| /* --------------------------- init ------------------------------- */ | ||||
| 
 | ||||
| @ -28,17 +28,16 @@ hook_init_nosv(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	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_NOSV_TASKID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_TYPE,   CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_APPID,  CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_RANK,   CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_TYPE, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_APPID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_NOSV_RANK, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_th, clock); | ||||
| 
 | ||||
| 		/* We allow threads to emit subsystem events in cooling and
 | ||||
| 		 * warming states as well, as they may be allocating memory. | ||||
| @ -48,22 +47,20 @@ hook_init_nosv(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the nosv channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	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_NOSV_TASKID,    CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_TYPE,      CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_APPID,     CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_RANK,      CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_TASKID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_TYPE, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_APPID, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_RANK, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_NOSV_SUBSYSTEM, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init task stack */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		th->nosv_task_stack.thread = th; | ||||
| 	} | ||||
| @ -80,7 +77,7 @@ chan_task_stopped(struct ovni_emu *emu) | ||||
| 	chan_set(&th->chan[CHAN_NOSV_TYPE], 0); | ||||
| 	chan_set(&th->chan[CHAN_NOSV_APPID], 0); | ||||
| 
 | ||||
| 	if(emu->cur_loom->rank_enabled) | ||||
| 	if (emu->cur_loom->rank_enabled) | ||||
| 		chan_set(&th->chan[CHAN_NOSV_RANK], 0); | ||||
| 
 | ||||
| 	/* XXX: Do we need this transition? */ | ||||
| @ -96,20 +93,20 @@ chan_task_running(struct ovni_emu *emu, struct task *task) | ||||
| 	th = emu->cur_thread; | ||||
| 	proc = emu->cur_proc; | ||||
| 
 | ||||
| 	if(task->id == 0) | ||||
| 	if (task->id == 0) | ||||
| 		edie(emu, "task id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(task->type->gid == 0) | ||||
| 	if (task->type->gid == 0) | ||||
| 		edie(emu, "task type gid cannot be 0\n"); | ||||
| 
 | ||||
| 	if(proc->appid <= 0) | ||||
| 	if (proc->appid <= 0) | ||||
| 		edie(emu, "app id must be positive\n"); | ||||
| 
 | ||||
| 	chan_set(&th->chan[CHAN_NOSV_TASKID], task->id); | ||||
| 	chan_set(&th->chan[CHAN_NOSV_TYPE], task->type->gid); | ||||
| 	chan_set(&th->chan[CHAN_NOSV_APPID], proc->appid); | ||||
| 
 | ||||
| 	if(emu->cur_loom->rank_enabled) | ||||
| 	if (emu->cur_loom->rank_enabled) | ||||
| 		chan_set(&th->chan[CHAN_NOSV_RANK], proc->rank + 1); | ||||
| 
 | ||||
| 	chan_push(&th->chan[CHAN_NOSV_SUBSYSTEM], ST_NOSV_TASK_RUNNING); | ||||
| @ -117,23 +114,23 @@ chan_task_running(struct ovni_emu *emu, struct task *task) | ||||
| 
 | ||||
| static void | ||||
| chan_task_switch(struct ovni_emu *emu, | ||||
| 		struct task *prev, struct task *next) | ||||
| 	struct task *prev, struct task *next) | ||||
| { | ||||
| 	struct ovni_ethread *th = emu->cur_thread; | ||||
| 
 | ||||
| 	if(!prev || !next) | ||||
| 	if (!prev || !next) | ||||
| 		edie(emu, "cannot switch to or from a NULL task\n"); | ||||
| 
 | ||||
| 	if(prev == next) | ||||
| 	if (prev == next) | ||||
| 		edie(emu, "cannot switch to the same task\n"); | ||||
| 
 | ||||
| 	if(next->id == 0) | ||||
| 	if (next->id == 0) | ||||
| 		edie(emu, "next task id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(next->type->gid == 0) | ||||
| 	if (next->type->gid == 0) | ||||
| 		edie(emu, "next task type id cannot be 0\n"); | ||||
| 
 | ||||
| 	if(prev->thread != next->thread) | ||||
| 	if (prev->thread != next->thread) | ||||
| 		edie(emu, "cannot switch to a task of another thread\n"); | ||||
| 
 | ||||
| 	/* No need to change the rank or app ID, as we can only switch
 | ||||
| @ -144,14 +141,14 @@ chan_task_switch(struct ovni_emu *emu, | ||||
| 	 * 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->type->gid != next->type->gid) | ||||
| 	if (prev->type->gid != next->type->gid) | ||||
| 		chan_set(&th->chan[CHAN_NOSV_TYPE], next->type->gid); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| update_task_state(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(ovni_payload_size(emu->cur_ev) < 4) | ||||
| 	if (ovni_payload_size(emu->cur_ev) < 4) | ||||
| 		edie(emu, "missing task id in payload\n"); | ||||
| 
 | ||||
| 	uint32_t task_id = emu->cur_ev->payload.u32[0]; | ||||
| @ -164,18 +161,25 @@ update_task_state(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	struct task *task = task_find(info->tasks, task_id); | ||||
| 
 | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot find task with id %u\n", task_id); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'x': task_execute(emu, stack, task); break; | ||||
| 		case 'e': task_end(emu, stack, task); break; | ||||
| 		case 'p': task_pause(emu, stack, task); break; | ||||
| 		case 'r': task_resume(emu, stack, task); break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'x': | ||||
| 			task_execute(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'e': | ||||
| 			task_end(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			task_pause(emu, stack, task); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			task_resume(emu, stack, task); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected Nanos6 task event value %c\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -185,13 +189,13 @@ expand_transition_value(struct ovni_emu *emu, int was_running, int runs_now) | ||||
| 	char tr = emu->cur_ev->header.value; | ||||
| 
 | ||||
| 	/* Ensure we don't clobber the value */ | ||||
| 	if(tr == 'X' || tr == 'E') | ||||
| 	if (tr == 'X' || tr == 'E') | ||||
| 		edie(emu, "unexpected event value %c\n", tr); | ||||
| 
 | ||||
| 	/* Modify the event value to detect nested transitions */ | ||||
| 	if(tr == 'x' && was_running) | ||||
| 	if (tr == 'x' && was_running) | ||||
| 		tr = 'X'; /* Execute a new nested task */ | ||||
| 	else if(tr == 'e' && runs_now) | ||||
| 	else if (tr == 'e' && runs_now) | ||||
| 		tr = 'E'; /* End a nested task */ | ||||
| 
 | ||||
| 	return tr; | ||||
| @ -199,17 +203,28 @@ expand_transition_value(struct ovni_emu *emu, int was_running, int runs_now) | ||||
| 
 | ||||
| static void | ||||
| update_task_channels(struct ovni_emu *emu, | ||||
| 		char tr, struct task *prev, struct task *next) | ||||
| 	char tr, struct task *prev, struct task *next) | ||||
| { | ||||
| 	switch(tr) | ||||
| 	{ | ||||
| 		case 'x': chan_task_running(emu, next); break; | ||||
| 		case 'r': chan_task_running(emu, next); break; | ||||
| 		case 'e': chan_task_stopped(emu); break; | ||||
| 		case 'p': chan_task_stopped(emu); break; | ||||
| 	switch (tr) { | ||||
| 		case 'x': | ||||
| 			chan_task_running(emu, next); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			chan_task_running(emu, next); | ||||
| 			break; | ||||
| 		case 'e': | ||||
| 			chan_task_stopped(emu); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			chan_task_stopped(emu); | ||||
| 			break; | ||||
| 		/* Additional nested transitions */ | ||||
| 		case 'X': chan_task_switch(emu, prev, next); break; | ||||
| 		case 'E': chan_task_switch(emu, prev, next); break; | ||||
| 		case 'X': | ||||
| 			chan_task_switch(emu, prev, next); | ||||
| 			break; | ||||
| 		case 'E': | ||||
| 			chan_task_switch(emu, prev, next); | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected transition value %c\n", tr); | ||||
| 	} | ||||
| @ -239,7 +254,7 @@ update_task(struct ovni_emu *emu) | ||||
| static void | ||||
| create_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(ovni_payload_size(emu->cur_ev) != 8) | ||||
| 	if (ovni_payload_size(emu->cur_ev) != 8) | ||||
| 		edie(emu, "cannot create task: unexpected payload size\n"); | ||||
| 
 | ||||
| 	uint32_t task_id = emu->cur_ev->payload.u32[0]; | ||||
| @ -253,8 +268,7 @@ create_task(struct ovni_emu *emu) | ||||
| static void | ||||
| pre_task(struct ovni_emu *emu) | ||||
| { | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'c': | ||||
| 			create_task(emu); | ||||
| 			break; | ||||
| @ -266,18 +280,18 @@ pre_task(struct ovni_emu *emu) | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected task event value %c\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_type(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.value != 'c') | ||||
| 	if (emu->cur_ev->header.value != 'c') | ||||
| 		edie(emu, "unexpected event value %c\n", | ||||
| 				emu->cur_ev->header.value); | ||||
| 			emu->cur_ev->header.value); | ||||
| 
 | ||||
| 	if((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) | ||||
| 	if ((emu->cur_ev->header.flags & OVNI_EV_JUMBO) == 0) | ||||
| 		edie(emu, "expecting a jumbo event\n"); | ||||
| 
 | ||||
| 	uint8_t *data = &emu->cur_ev->payload.jumbo.data[0]; | ||||
| @ -300,8 +314,7 @@ pre_sched(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NOSV_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'h': | ||||
| 			chan_push(chan_th, ST_NOSV_SCHED_HUNGRY); | ||||
| 			break; | ||||
| @ -337,19 +350,39 @@ pre_api(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NOSV_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 's': chan_push(chan_th, ST_NOSV_API_SUBMIT); break; | ||||
| 		case 'S': chan_pop (chan_th, ST_NOSV_API_SUBMIT); break; | ||||
| 		case 'p': chan_push(chan_th, ST_NOSV_API_PAUSE); break; | ||||
| 		case 'P': chan_pop (chan_th, ST_NOSV_API_PAUSE); break; | ||||
| 		case 'y': chan_push(chan_th, ST_NOSV_API_YIELD); break; | ||||
| 		case 'Y': chan_pop (chan_th, ST_NOSV_API_YIELD); break; | ||||
| 		case 'w': chan_push(chan_th, ST_NOSV_API_WAITFOR); break; | ||||
| 		case 'W': chan_pop (chan_th, ST_NOSV_API_WAITFOR); break; | ||||
| 		case 'c': chan_push(chan_th, ST_NOSV_API_SCHEDPOINT); break; | ||||
| 		case 'C': chan_pop (chan_th, ST_NOSV_API_SCHEDPOINT); break; | ||||
| 		default: break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 's': | ||||
| 			chan_push(chan_th, ST_NOSV_API_SUBMIT); | ||||
| 			break; | ||||
| 		case 'S': | ||||
| 			chan_pop(chan_th, ST_NOSV_API_SUBMIT); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			chan_push(chan_th, ST_NOSV_API_PAUSE); | ||||
| 			break; | ||||
| 		case 'P': | ||||
| 			chan_pop(chan_th, ST_NOSV_API_PAUSE); | ||||
| 			break; | ||||
| 		case 'y': | ||||
| 			chan_push(chan_th, ST_NOSV_API_YIELD); | ||||
| 			break; | ||||
| 		case 'Y': | ||||
| 			chan_pop(chan_th, ST_NOSV_API_YIELD); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			chan_push(chan_th, ST_NOSV_API_WAITFOR); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			chan_pop(chan_th, ST_NOSV_API_WAITFOR); | ||||
| 			break; | ||||
| 		case 'c': | ||||
| 			chan_push(chan_th, ST_NOSV_API_SCHEDPOINT); | ||||
| 			break; | ||||
| 		case 'C': | ||||
| 			chan_pop(chan_th, ST_NOSV_API_SCHEDPOINT); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -362,13 +395,21 @@ pre_mem(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NOSV_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'a': chan_push(chan_th, ST_NOSV_MEM_ALLOCATING); break; | ||||
| 		case 'A': chan_pop (chan_th, ST_NOSV_MEM_ALLOCATING); break; | ||||
| 		case 'f': chan_push(chan_th, ST_NOSV_MEM_FREEING); break; | ||||
| 		case 'F': chan_pop (chan_th, ST_NOSV_MEM_FREEING); break; | ||||
| 		default: break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'a': | ||||
| 			chan_push(chan_th, ST_NOSV_MEM_ALLOCATING); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			chan_pop(chan_th, ST_NOSV_MEM_ALLOCATING); | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			chan_push(chan_th, ST_NOSV_MEM_FREEING); | ||||
| 			break; | ||||
| 		case 'F': | ||||
| 			chan_pop(chan_th, ST_NOSV_MEM_FREEING); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -381,15 +422,27 @@ pre_thread_type(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_NOSV_SUBSYSTEM]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 'a': chan_push(chan_th, ST_NOSV_ATTACH); break; | ||||
| 		case 'A': chan_pop (chan_th, ST_NOSV_ATTACH); break; | ||||
| 		case 'w': chan_push(chan_th, ST_NOSV_WORKER); break; | ||||
| 		case 'W': chan_pop (chan_th, ST_NOSV_WORKER); break; | ||||
| 		case 'd': chan_push(chan_th, ST_NOSV_DELEGATE); break; | ||||
| 		case 'D': chan_pop (chan_th, ST_NOSV_DELEGATE); break; | ||||
| 		default: break; | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 'a': | ||||
| 			chan_push(chan_th, ST_NOSV_ATTACH); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			chan_pop(chan_th, ST_NOSV_ATTACH); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			chan_push(chan_th, ST_NOSV_WORKER); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			chan_pop(chan_th, ST_NOSV_WORKER); | ||||
| 			break; | ||||
| 		case 'd': | ||||
| 			chan_push(chan_th, ST_NOSV_DELEGATE); | ||||
| 			break; | ||||
| 		case 'D': | ||||
| 			chan_pop(chan_th, ST_NOSV_DELEGATE); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -404,8 +457,7 @@ pre_ss(struct ovni_emu *emu, int st) | ||||
| 
 | ||||
| 	dbg("pre_ss chan id %d st=%d\n", chan_th->id, st); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan_th, st); | ||||
| 			break; | ||||
| @ -414,7 +466,7 @@ pre_ss(struct ovni_emu *emu, int st) | ||||
| 			break; | ||||
| 		default: | ||||
| 			err("unexpected value '%c' (expecting '[' or ']')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 			abort(); | ||||
| 	} | ||||
| } | ||||
| @ -425,44 +477,56 @@ check_affinity(struct ovni_emu *emu) | ||||
| 	struct ovni_ethread *th = emu->cur_thread; | ||||
| 	struct ovni_cpu *cpu = th->cpu; | ||||
| 
 | ||||
| 	if(!cpu || cpu->virtual) | ||||
| 	if (!cpu || cpu->virtual) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(th->state != TH_ST_RUNNING) | ||||
| 	if (th->state != TH_ST_RUNNING) | ||||
| 		return; | ||||
| 
 | ||||
| 	if(cpu->nrunning_threads > 1) | ||||
| 	{ | ||||
| 	if (cpu->nrunning_threads > 1) { | ||||
| 		edie(emu, "cpu %s has more than one thread running\n", | ||||
| 				cpu->name); | ||||
| 			cpu->name); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_nosv(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != 'V') | ||||
| 	if (emu->cur_ev->header.model != 'V') | ||||
| 		edie(emu, "hook_pre_nosv: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	if(!emu->cur_thread->is_active) | ||||
| 	if (!emu->cur_thread->is_active) | ||||
| 		edie(emu, "hook_pre_nosv: current thread %d not active\n", | ||||
| 				emu->cur_thread->tid); | ||||
| 			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_NOSV_SCHED_SUBMITTING); break; | ||||
| 		case 'M': pre_mem(emu); break; | ||||
| 		case 'H': pre_thread_type(emu); break; | ||||
| 		case 'A': pre_api(emu); break; | ||||
| 	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_NOSV_SCHED_SUBMITTING); | ||||
| 			break; | ||||
| 		case 'M': | ||||
| 			pre_mem(emu); | ||||
| 			break; | ||||
| 		case 'H': | ||||
| 			pre_thread_type(emu); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			pre_api(emu); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	if(emu->enable_linter) | ||||
| 	if (emu->enable_linter) | ||||
| 		check_affinity(emu); | ||||
| } | ||||
| 
 | ||||
| @ -470,17 +534,14 @@ void | ||||
| hook_end_nosv(struct ovni_emu *emu) | ||||
| { | ||||
| 	/* Emit types for all channel types and processes */ | ||||
| 	for(enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) | ||||
| 	{ | ||||
| 	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]; | ||||
| 		struct pcf_type *pcftype = pcf_find_type(pcf, typeid); | ||||
| 
 | ||||
| 		for(size_t i = 0; i < emu->trace.nlooms; i++) | ||||
| 		{ | ||||
| 		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++) | ||||
| 			{ | ||||
| 			for (size_t j = 0; j < loom->nprocs; j++) { | ||||
| 				struct ovni_eproc *proc = &loom->proc[j]; | ||||
| 				task_create_pcf_types(pcftype, proc->nosv_task_info.types); | ||||
| 			} | ||||
|  | ||||
							
								
								
									
										36
									
								
								emu_openmp.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								emu_openmp.c
									
									
									
									
									
								
							| @ -3,10 +3,10 @@ | ||||
| 
 | ||||
| #include "uthash.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| /* --------------------------- init ------------------------------- */ | ||||
| 
 | ||||
| @ -26,8 +26,7 @@ hook_init_openmp(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		row = th->gindex + 1; | ||||
| 		uth = &emu->th_chan; | ||||
| @ -36,8 +35,7 @@ hook_init_openmp(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_ncpus; i++) { | ||||
| 		cpu = emu->global_cpu[i]; | ||||
| 		row = cpu->gindex + 1; | ||||
| 		ucpu = &emu->cpu_chan; | ||||
| @ -57,8 +55,7 @@ pre_mode(struct ovni_emu *emu, int st) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan = &th->chan[CHAN_OPENMP_MODE]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan, st); | ||||
| 			break; | ||||
| @ -67,7 +64,7 @@ pre_mode(struct ovni_emu *emu, int st) | ||||
| 			break; | ||||
| 		default: | ||||
| 			err("unexpected value '%c' (expecting '[' or ']')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 			abort(); | ||||
| 	} | ||||
| } | ||||
| @ -75,18 +72,21 @@ pre_mode(struct ovni_emu *emu, int st) | ||||
| void | ||||
| hook_pre_openmp(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != 'M') | ||||
| 	if (emu->cur_ev->header.model != 'M') | ||||
| 		die("hook_pre_openmp: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	if(!emu->cur_thread->is_active) | ||||
| 	if (!emu->cur_thread->is_active) | ||||
| 		die("hook_pre_openmp: current thread %d not active\n", | ||||
| 				emu->cur_thread->tid); | ||||
| 			emu->cur_thread->tid); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 		case 'T': pre_mode(emu, ST_OPENMP_TASK); break; | ||||
| 		case 'P': pre_mode(emu, ST_OPENMP_PARALLEL); break; | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'T': | ||||
| 			pre_mode(emu, ST_OPENMP_TASK); | ||||
| 			break; | ||||
| 		case 'P': | ||||
| 			pre_mode(emu, ST_OPENMP_PARALLEL); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										283
									
								
								emu_ovni.c
									
									
									
									
									
								
							
							
						
						
									
										283
									
								
								emu_ovni.c
									
									
									
									
									
								
							| @ -1,10 +1,10 @@ | ||||
| /* Copyright (c) 2021 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| #include "utlist.h" | ||||
| 
 | ||||
| /* The emulator ovni module provides the execution model by tracking the thread
 | ||||
| @ -28,30 +28,28 @@ hook_init_ovni(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the ovni channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	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_OVNI_TID,   CHAN_TRACK_TH_RUNNING, th->tid,       0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_PID,   CHAN_TRACK_TH_RUNNING, th->proc->pid, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_CPU,   CHAN_TRACK_NONE,       -1,            0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_STATE, CHAN_TRACK_NONE,       TH_ST_UNKNOWN, 1, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_FLUSH, CHAN_TRACK_NONE,       ST_NULL,       1, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_TID, CHAN_TRACK_TH_RUNNING, th->tid, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_PID, CHAN_TRACK_TH_RUNNING, th->proc->pid, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_CPU, CHAN_TRACK_NONE, -1, 0, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_STATE, CHAN_TRACK_NONE, TH_ST_UNKNOWN, 1, 1, row, prv_th, clock); | ||||
| 		chan_th_init(th, uth, CHAN_OVNI_FLUSH, CHAN_TRACK_NONE, ST_NULL, 1, 1, row, prv_th, clock); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the ovni channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	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_OVNI_TID,       CHAN_TRACK_TH_RUNNING,   0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_PID,       CHAN_TRACK_TH_RUNNING,   0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_NRTHREADS, CHAN_TRACK_NONE,         0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_FLUSH,     CHAN_TRACK_TH_RUNNING,   0, 0, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_TID, CHAN_TRACK_TH_RUNNING, 0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_PID, CHAN_TRACK_TH_RUNNING, 0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_NRTHREADS, CHAN_TRACK_NONE, 0, 1, 1, row, prv_cpu, clock); | ||||
| 		chan_cpu_init(cpu, ucpu, CHAN_OVNI_FLUSH, CHAN_TRACK_TH_RUNNING, 0, 0, 1, row, prv_cpu, clock); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -63,11 +61,10 @@ chan_tracking_update(struct ovni_chan *chan, struct ovni_ethread *th) | ||||
| { | ||||
| 	int enabled; | ||||
| 
 | ||||
| 	if(th == NULL) | ||||
| 	if (th == NULL) | ||||
| 		die("chan_tracking_update: thread is NULL"); | ||||
| 
 | ||||
| 	switch (chan->track) | ||||
| 	{ | ||||
| 	switch (chan->track) { | ||||
| 		case CHAN_TRACK_TH_RUNNING: | ||||
| 			enabled = th->is_running; | ||||
| 			break; | ||||
| @ -81,11 +78,11 @@ chan_tracking_update(struct ovni_chan *chan, struct ovni_ethread *th) | ||||
| 	} | ||||
| 
 | ||||
| 	/* The channel is already in the proper state */ | ||||
| 	if(chan_is_enabled(chan) == enabled) | ||||
| 	if (chan_is_enabled(chan) == enabled) | ||||
| 		return; | ||||
| 
 | ||||
| 	dbg("thread %d changes state to %d: chan %d enabled=%d\n", | ||||
| 			th->tid, th->state, chan->id, enabled); | ||||
| 		th->tid, th->state, chan->id, enabled); | ||||
| 
 | ||||
| 	chan_enable(chan, enabled); | ||||
| } | ||||
| @ -97,25 +94,27 @@ thread_set_state(struct ovni_ethread *th, enum ethread_state state) | ||||
| 	int i; | ||||
| 
 | ||||
| 	/* The state must be updated when a cpu is set */ | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("thread_set_state: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	dbg("thread_set_state: setting thread %d state %d\n", | ||||
| 			th->tid, state); | ||||
| 		th->tid, state); | ||||
| 
 | ||||
| 	th->state = state; | ||||
| 
 | ||||
| 	th->is_running = (state == TH_ST_RUNNING) ? 1 : 0; | ||||
| 
 | ||||
| 	th->is_active = (state == TH_ST_RUNNING | ||||
| 			|| state == TH_ST_COOLING | ||||
| 			|| state == TH_ST_WARMING) ? 1 : 0; | ||||
| 				|| state == TH_ST_COOLING | ||||
| 				|| state == TH_ST_WARMING) | ||||
| 				? 1 | ||||
| 				: 0; | ||||
| 
 | ||||
| 	chan_set(&th->chan[CHAN_OVNI_STATE], th->state); | ||||
| 	 | ||||
| 
 | ||||
| 	/* Enable or disable the thread channels that track the thread state */ | ||||
| 	for(i=0; i<CHAN_MAX; i++) | ||||
| 	for (i = 0; i < CHAN_MAX; i++) | ||||
| 		chan_tracking_update(&th->chan[i], th); | ||||
| 
 | ||||
| 	dbg("thread_set_state: done\n"); | ||||
| @ -129,15 +128,12 @@ cpu_update_th_stats(struct ovni_cpu *cpu) | ||||
| 
 | ||||
| 	DL_FOREACH(cpu->thread, th) | ||||
| 	{ | ||||
| 		if(th->state == TH_ST_RUNNING) | ||||
| 		{ | ||||
| 		if (th->state == TH_ST_RUNNING) { | ||||
| 			th_running = th; | ||||
| 			running++; | ||||
| 			th_active = th; | ||||
| 			active++; | ||||
| 		} | ||||
| 		else if(th->state == TH_ST_COOLING || th->state == TH_ST_WARMING) | ||||
| 		{ | ||||
| 		} else if (th->state == TH_ST_COOLING || th->state == TH_ST_WARMING) { | ||||
| 			th_active = th; | ||||
| 			active++; | ||||
| 		} | ||||
| @ -161,11 +157,11 @@ update_cpu(struct ovni_cpu *cpu) | ||||
| 
 | ||||
| 	/* From the CPU channels we only need to manually update the number of
 | ||||
| 	 * threads running in the CPU */ | ||||
| 	if(chan_get_st(&cpu->chan[CHAN_OVNI_NRTHREADS]) != (int) cpu->nrunning_threads) | ||||
| 	if (chan_get_st(&cpu->chan[CHAN_OVNI_NRTHREADS]) != (int) cpu->nrunning_threads) | ||||
| 		chan_set(&cpu->chan[CHAN_OVNI_NRTHREADS], (int) cpu->nrunning_threads); | ||||
| 
 | ||||
| 	/* Update all tracking channels */ | ||||
| 	for(i=0; i<CHAN_MAX; i++) | ||||
| 	for (i = 0; i < CHAN_MAX; i++) | ||||
| 		emu_cpu_update_chan(cpu, &cpu->chan[i]); | ||||
| 
 | ||||
| 	dbg("updating cpu %s complete!\n", cpu->name); | ||||
| @ -174,10 +170,10 @@ update_cpu(struct ovni_cpu *cpu) | ||||
| struct ovni_cpu * | ||||
| emu_get_cpu(struct ovni_loom *loom, int cpuid) | ||||
| { | ||||
| 	if(cpuid >= (int) loom->ncpus) | ||||
| 	if (cpuid >= (int) loom->ncpus) | ||||
| 		die("emu_get_cpu: CPU index out of bounds\n"); | ||||
| 
 | ||||
| 	if(cpuid < 0) | ||||
| 	if (cpuid < 0) | ||||
| 		return &loom->vcpu; | ||||
| 
 | ||||
| 	return &loom->cpu[cpuid]; | ||||
| @ -190,7 +186,7 @@ emu_cpu_find_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||
| 
 | ||||
| 	DL_FOREACH(cpu->thread, p) | ||||
| 	{ | ||||
| 		if(p == thread) | ||||
| 		if (p == thread) | ||||
| 			return p; | ||||
| 	} | ||||
| 
 | ||||
| @ -202,10 +198,9 @@ static void | ||||
| cpu_add_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||
| { | ||||
| 	/* Found, abort */ | ||||
| 	if(emu_cpu_find_thread(cpu, thread) != NULL) | ||||
| 	{ | ||||
| 	if (emu_cpu_find_thread(cpu, thread) != NULL) { | ||||
| 		err("The thread %d is already assigned to %s\n", | ||||
| 				thread->tid, cpu->name); | ||||
| 			thread->tid, cpu->name); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| @ -223,10 +218,9 @@ cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||
| 	p = emu_cpu_find_thread(cpu, thread); | ||||
| 
 | ||||
| 	/* Not found, abort */ | ||||
| 	if(p == NULL) | ||||
| 	{ | ||||
| 	if (p == NULL) { | ||||
| 		err("cannot remove missing thread %d from cpu %s\n", | ||||
| 				thread->tid, cpu->name); | ||||
| 			thread->tid, cpu->name); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| @ -238,10 +232,9 @@ cpu_remove_thread(struct ovni_cpu *cpu, struct ovni_ethread *thread) | ||||
| 
 | ||||
| static void | ||||
| cpu_migrate_thread(struct ovni_cpu *cpu, | ||||
| 		struct ovni_ethread *thread, | ||||
| 		struct ovni_cpu *newcpu) | ||||
| 	struct ovni_ethread *thread, | ||||
| 	struct ovni_cpu *newcpu) | ||||
| { | ||||
| 
 | ||||
| 	cpu_remove_thread(cpu, thread); | ||||
| 	cpu_add_thread(newcpu, thread); | ||||
| } | ||||
| @ -251,12 +244,12 @@ cpu_migrate_thread(struct ovni_cpu *cpu, | ||||
| static void | ||||
| thread_set_cpu(struct ovni_ethread *th, struct ovni_cpu *cpu) | ||||
| { | ||||
| 	if(th->cpu != NULL) | ||||
| 	if (th->cpu != NULL) | ||||
| 		die("thread_set_cpu: thread %d already has a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	dbg("thread_set_cpu: setting thread %d cpu to %s\n", | ||||
| 			th->tid, cpu->name); | ||||
| 		th->tid, cpu->name); | ||||
| 	th->cpu = cpu; | ||||
| 
 | ||||
| 	chan_enable(&th->chan[CHAN_OVNI_CPU], 1); | ||||
| @ -268,9 +261,9 @@ thread_set_cpu(struct ovni_ethread *th, struct ovni_cpu *cpu) | ||||
| static void | ||||
| thread_unset_cpu(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("thread_unset_cpu: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	th->cpu = NULL; | ||||
| 
 | ||||
| @ -282,9 +275,9 @@ thread_unset_cpu(struct ovni_ethread *th) | ||||
| static void | ||||
| thread_migrate_cpu(struct ovni_ethread *th, struct ovni_cpu *cpu) | ||||
| { | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("thread_migrate_cpu: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 	th->cpu = cpu; | ||||
| 
 | ||||
| 	chan_set(&th->chan[CHAN_OVNI_CPU], cpu->gindex + 1); | ||||
| @ -297,9 +290,9 @@ pre_thread_execute(struct ovni_emu *emu, struct ovni_ethread *th) | ||||
| 	int cpuid; | ||||
| 
 | ||||
| 	/* The thread cannot be already running */ | ||||
| 	if(th->state == TH_ST_RUNNING) | ||||
| 	if (th->state == TH_ST_RUNNING) | ||||
| 		edie(emu, "pre_thread_execute: thread %d already running\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	cpuid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| @ -320,13 +313,13 @@ pre_thread_execute(struct ovni_emu *emu, struct ovni_ethread *th) | ||||
| static void | ||||
| pre_thread_end(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->state != TH_ST_RUNNING && th->state != TH_ST_COOLING) | ||||
| 	if (th->state != TH_ST_RUNNING && th->state != TH_ST_COOLING) | ||||
| 		die("pre_thread_end: thread %d not running or cooling\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("pre_thread_end: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	/* First update the thread state */ | ||||
| 	thread_set_state(th, TH_ST_DEAD); | ||||
| @ -340,13 +333,13 @@ pre_thread_end(struct ovni_ethread *th) | ||||
| static void | ||||
| pre_thread_pause(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->state != TH_ST_RUNNING && th->state != TH_ST_COOLING) | ||||
| 	if (th->state != TH_ST_RUNNING && th->state != TH_ST_COOLING) | ||||
| 		die("pre_thread_pause: thread %d not running or cooling\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("pre_thread_pause: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	thread_set_state(th, TH_ST_PAUSED); | ||||
| 	update_cpu(th->cpu); | ||||
| @ -355,13 +348,13 @@ pre_thread_pause(struct ovni_ethread *th) | ||||
| static void | ||||
| pre_thread_resume(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->state != TH_ST_PAUSED && th->state != TH_ST_WARMING) | ||||
| 	if (th->state != TH_ST_PAUSED && th->state != TH_ST_WARMING) | ||||
| 		die("pre_thread_resume: thread %d not paused or warming\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("pre_thread_resume: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	thread_set_state(th, TH_ST_RUNNING); | ||||
| 	update_cpu(th->cpu); | ||||
| @ -370,13 +363,13 @@ pre_thread_resume(struct ovni_ethread *th) | ||||
| static void | ||||
| pre_thread_cool(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->state != TH_ST_RUNNING) | ||||
| 	if (th->state != TH_ST_RUNNING) | ||||
| 		die("pre_thread_cool: thread %d not running\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("pre_thread_cool: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	thread_set_state(th, TH_ST_COOLING); | ||||
| 	update_cpu(th->cpu); | ||||
| @ -385,13 +378,13 @@ pre_thread_cool(struct ovni_ethread *th) | ||||
| static void | ||||
| pre_thread_warm(struct ovni_ethread *th) | ||||
| { | ||||
| 	if(th->state != TH_ST_PAUSED) | ||||
| 	if (th->state != TH_ST_PAUSED) | ||||
| 		die("pre_thread_warm: thread %d not paused\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		die("pre_thread_warm: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	thread_set_state(th, TH_ST_WARMING); | ||||
| 	update_cpu(th->cpu); | ||||
| @ -403,31 +396,42 @@ pre_thread(struct ovni_emu *emu) | ||||
| 	struct ovni_ev *ev; | ||||
| 	struct ovni_ethread *th; | ||||
| 
 | ||||
| 	//emu_emit(emu);
 | ||||
| 	// emu_emit(emu);
 | ||||
| 
 | ||||
| 	th = emu->cur_thread; | ||||
| 	ev = emu->cur_ev; | ||||
| 
 | ||||
| 	switch(ev->header.value) | ||||
| 	{ | ||||
| 	switch (ev->header.value) { | ||||
| 		case 'C': /* create */ | ||||
| 			dbg("thread %d creates a new thread at cpu=%d with args=%x %x\n", | ||||
| 					th->tid, | ||||
| 					ev->payload.u32[0], | ||||
| 					ev->payload.u32[1], | ||||
| 					ev->payload.u32[2]); | ||||
| 				th->tid, | ||||
| 				ev->payload.u32[0], | ||||
| 				ev->payload.u32[1], | ||||
| 				ev->payload.u32[2]); | ||||
| 
 | ||||
| 			break; | ||||
| 		case 'x': pre_thread_execute(emu, th); break; | ||||
| 		case 'e': pre_thread_end(th); break; | ||||
| 		case 'p': pre_thread_pause(th); break; | ||||
| 		case 'r': pre_thread_resume(th); break; | ||||
| 		case 'c': pre_thread_cool(th); break; | ||||
| 		case 'w': pre_thread_warm(th); break; | ||||
| 		case 'x': | ||||
| 			pre_thread_execute(emu, th); | ||||
| 			break; | ||||
| 		case 'e': | ||||
| 			pre_thread_end(th); | ||||
| 			break; | ||||
| 		case 'p': | ||||
| 			pre_thread_pause(th); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			pre_thread_resume(th); | ||||
| 			break; | ||||
| 		case 'c': | ||||
| 			pre_thread_cool(th); | ||||
| 			break; | ||||
| 		case 'w': | ||||
| 			pre_thread_warm(th); | ||||
| 			break; | ||||
| 		default: | ||||
| 			  err("unknown thread event value %c\n", | ||||
| 					  ev->header.value); | ||||
| 			  exit(EXIT_FAILURE); | ||||
| 			err("unknown thread event value %c\n", | ||||
| 				ev->header.value); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -441,25 +445,25 @@ pre_affinity_set(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	cpuid = emu->cur_ev->payload.i32[0]; | ||||
| 
 | ||||
| 	if(th->cpu == NULL) | ||||
| 	if (th->cpu == NULL) | ||||
| 		edie(emu, "pre_affinity_set: thread %d doesn't have a CPU\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	if(!th->is_active) | ||||
| 	if (!th->is_active) | ||||
| 		edie(emu, "pre_affinity_set: thread %d is not active\n", | ||||
| 				th->tid); | ||||
| 			th->tid); | ||||
| 
 | ||||
| 	/* Migrate current cpu to the one at cpuid */ | ||||
| 	newcpu = emu_get_cpu(emu->cur_loom, cpuid); | ||||
| 
 | ||||
| 	/* The CPU is already properly set, return */ | ||||
| 	if(th->cpu == newcpu) | ||||
| 	if (th->cpu == newcpu) | ||||
| 		return; | ||||
| 
 | ||||
| 	cpu_migrate_thread(th->cpu, th, newcpu); | ||||
| 	thread_migrate_cpu(th, newcpu); | ||||
| 
 | ||||
| 	//dbg("cpu %d now runs %d\n", cpuid, th->tid);
 | ||||
| 	// dbg("cpu %d now runs %d\n", cpuid, th->tid);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -477,47 +481,44 @@ pre_affinity_remote(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	remote_th = emu_get_thread(emu->cur_proc, tid); | ||||
| 
 | ||||
| 	if(remote_th == NULL) | ||||
| 	{ | ||||
| 	if (remote_th == NULL) { | ||||
| 		/* Search the thread in other processes of the loom if
 | ||||
| 		 * not found in the current one */ | ||||
| 		loom = emu->cur_loom; | ||||
| 
 | ||||
| 		for(i=0; i<loom->nprocs; i++) | ||||
| 		{ | ||||
| 		for (i = 0; i < loom->nprocs; i++) { | ||||
| 			proc = &loom->proc[i]; | ||||
| 
 | ||||
| 			/* Skip the current process */ | ||||
| 			if(proc == emu->cur_proc) | ||||
| 			if (proc == emu->cur_proc) | ||||
| 				continue; | ||||
| 
 | ||||
| 			remote_th = emu_get_thread(proc, tid); | ||||
| 
 | ||||
| 			if(remote_th) | ||||
| 			if (remote_th) | ||||
| 				break; | ||||
| 		} | ||||
| 
 | ||||
| 		if(remote_th == NULL) | ||||
| 		{ | ||||
| 		if (remote_th == NULL) { | ||||
| 			err("thread tid %d not found: cannot set affinity remotely\n", | ||||
| 					tid); | ||||
| 				tid); | ||||
| 			abort(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* The remote_th cannot be in states dead or unknown */ | ||||
| 	if(remote_th->state == TH_ST_DEAD) | ||||
| 	if (remote_th->state == TH_ST_DEAD) | ||||
| 		edie(emu, "pre_affinity_remote: remote thread %d in state DEAD\n", | ||||
| 				remote_th->tid); | ||||
| 			remote_th->tid); | ||||
| 
 | ||||
| 	if(remote_th->state == TH_ST_UNKNOWN) | ||||
| 	if (remote_th->state == TH_ST_UNKNOWN) | ||||
| 		edie(emu, "pre_affinity_remote: remote thread %d in state UNKNOWN\n", | ||||
| 				remote_th->tid); | ||||
| 			remote_th->tid); | ||||
| 
 | ||||
| 	/* It must have an assigned CPU */ | ||||
| 	if(remote_th->cpu == NULL) | ||||
| 	if (remote_th->cpu == NULL) | ||||
| 		edie(emu, "pre_affinity_remote: remote thread %d has no CPU\n", | ||||
| 				remote_th->tid); | ||||
| 			remote_th->tid); | ||||
| 
 | ||||
| 	/* Migrate current cpu to the one at cpuid */ | ||||
| 	newcpu = emu_get_cpu(emu->cur_loom, cpuid); | ||||
| @ -525,21 +526,24 @@ pre_affinity_remote(struct ovni_emu *emu) | ||||
| 	cpu_migrate_thread(remote_th->cpu, remote_th, newcpu); | ||||
| 	thread_migrate_cpu(remote_th, newcpu); | ||||
| 
 | ||||
| 	//dbg("remote_th %d switches to cpu %d by remote petition\n", tid,
 | ||||
| 	// dbg("remote_th %d switches to cpu %d by remote petition\n", tid,
 | ||||
| 	//		cpuid);
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| pre_affinity(struct ovni_emu *emu) | ||||
| { | ||||
| 	//emu_emit(emu);
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 		case 's': pre_affinity_set(emu); break; | ||||
| 		case 'r': pre_affinity_remote(emu); break; | ||||
| 	// emu_emit(emu);
 | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case 's': | ||||
| 			pre_affinity_set(emu); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			pre_affinity_remote(emu); | ||||
| 			break; | ||||
| 		default: | ||||
| 			dbg("unknown affinity event value %c\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
| @ -554,17 +558,14 @@ pre_burst(struct ovni_emu *emu) | ||||
| 
 | ||||
| 	th = emu->cur_thread; | ||||
| 
 | ||||
| 	if(th->nbursts >= MAX_BURSTS) | ||||
| 	{ | ||||
| 	if (th->nbursts >= MAX_BURSTS) { | ||||
| 		err("too many bursts: ignored\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	th->burst_time[th->nbursts] = emu->delta_time; | ||||
| 	if(th->nbursts > 0) | ||||
| 	{ | ||||
| 		dt = th->burst_time[th->nbursts] - | ||||
| 			th->burst_time[th->nbursts - 1]; | ||||
| 	if (th->nbursts > 0) { | ||||
| 		dt = th->burst_time[th->nbursts] - th->burst_time[th->nbursts - 1]; | ||||
| 
 | ||||
| 		dbg("burst delta time %ld ns\n", dt); | ||||
| 	} | ||||
| @ -581,8 +582,7 @@ pre_flush(struct ovni_emu *emu) | ||||
| 	th = emu->cur_thread; | ||||
| 	chan_th = &th->chan[CHAN_OVNI_FLUSH]; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(chan_th, ST_OVNI_FLUSHING); | ||||
| 			break; | ||||
| @ -591,7 +591,7 @@ pre_flush(struct ovni_emu *emu) | ||||
| 			break; | ||||
| 		default: | ||||
| 			err("unexpected value '%c' (expecting '[' or ']')\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 			abort(); | ||||
| 	} | ||||
| } | ||||
| @ -599,20 +599,27 @@ pre_flush(struct ovni_emu *emu) | ||||
| void | ||||
| hook_pre_ovni(struct ovni_emu *emu) | ||||
| { | ||||
| 	//emu_emit(emu);
 | ||||
| 	// emu_emit(emu);
 | ||||
| 
 | ||||
| 	if(emu->cur_ev->header.model != 'O') | ||||
| 	if (emu->cur_ev->header.model != 'O') | ||||
| 		return; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 		case 'H': pre_thread(emu); break; | ||||
| 		case 'A': pre_affinity(emu); break; | ||||
| 		case 'B': pre_burst(emu); break; | ||||
| 		case 'F': pre_flush(emu); break; | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'H': | ||||
| 			pre_thread(emu); | ||||
| 			break; | ||||
| 		case 'A': | ||||
| 			pre_affinity(emu); | ||||
| 			break; | ||||
| 		case 'B': | ||||
| 			pre_burst(emu); | ||||
| 			break; | ||||
| 		case 'F': | ||||
| 			pre_flush(emu); | ||||
| 			break; | ||||
| 		default: | ||||
| 			dbg("unknown ovni event category %c\n", | ||||
| 					emu->cur_ev->header.category); | ||||
| 				emu->cur_ev->header.category); | ||||
| 			break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										48
									
								
								emu_tampi.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								emu_tampi.c
									
									
									
									
									
								
							| @ -3,10 +3,10 @@ | ||||
| 
 | ||||
| #include "uthash.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| /* --------------------------- init ------------------------------- */ | ||||
| 
 | ||||
| @ -26,8 +26,7 @@ hook_init_tampi(struct ovni_emu *emu) | ||||
| 	prv_cpu = emu->prv_cpu; | ||||
| 
 | ||||
| 	/* Init the channels in all threads */ | ||||
| 	for(i=0; i<emu->total_nthreads; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_nthreads; i++) { | ||||
| 		th = emu->global_thread[i]; | ||||
| 		row = th->gindex + 1; | ||||
| 		uth = &emu->th_chan; | ||||
| @ -36,8 +35,7 @@ hook_init_tampi(struct ovni_emu *emu) | ||||
| 	} | ||||
| 
 | ||||
| 	/* Init the channels in all cpus */ | ||||
| 	for(i=0; i<emu->total_ncpus; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < emu->total_ncpus; i++) { | ||||
| 		cpu = emu->global_cpu[i]; | ||||
| 		row = cpu->gindex + 1; | ||||
| 		ucpu = &emu->cpu_chan; | ||||
| @ -55,8 +53,7 @@ pre_tampi_mode(struct ovni_emu *emu, int state) | ||||
| 
 | ||||
| 	th = emu->cur_thread; | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.value) | ||||
| 	{ | ||||
| 	switch (emu->cur_ev->header.value) { | ||||
| 		case '[': | ||||
| 			chan_push(&th->chan[CHAN_TAMPI_MODE], state); | ||||
| 			break; | ||||
| @ -65,25 +62,36 @@ pre_tampi_mode(struct ovni_emu *emu, int state) | ||||
| 			break; | ||||
| 		default: | ||||
| 			edie(emu, "unexpected event value %c for tampi mode\n", | ||||
| 					emu->cur_ev->header.value); | ||||
| 				emu->cur_ev->header.value); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void | ||||
| hook_pre_tampi(struct ovni_emu *emu) | ||||
| { | ||||
| 	if(emu->cur_ev->header.model != 'T') | ||||
| 	if (emu->cur_ev->header.model != 'T') | ||||
| 		edie(emu, "hook_pre_tampi: unexpected event with model %c\n", | ||||
| 				emu->cur_ev->header.model); | ||||
| 			emu->cur_ev->header.model); | ||||
| 
 | ||||
| 	switch(emu->cur_ev->header.category) | ||||
| 	{ | ||||
| 		case 'S': pre_tampi_mode(emu, ST_TAMPI_SEND); break; | ||||
| 		case 'R': pre_tampi_mode(emu, ST_TAMPI_RECV); break; | ||||
| 		case 's': pre_tampi_mode(emu, ST_TAMPI_ISEND); break; | ||||
| 		case 'r': pre_tampi_mode(emu, ST_TAMPI_IRECV); break; | ||||
| 		case 'V': pre_tampi_mode(emu, ST_TAMPI_WAIT); break; | ||||
| 		case 'W': pre_tampi_mode(emu, ST_TAMPI_WAITALL); break; | ||||
| 	switch (emu->cur_ev->header.category) { | ||||
| 		case 'S': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_SEND); | ||||
| 			break; | ||||
| 		case 'R': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_RECV); | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_ISEND); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_IRECV); | ||||
| 			break; | ||||
| 		case 'V': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_WAIT); | ||||
| 			break; | ||||
| 		case 'W': | ||||
| 			pre_tampi_mode(emu, ST_TAMPI_WAITALL); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										92
									
								
								emu_task.c
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								emu_task.c
									
									
									
									
									
								
							| @ -4,11 +4,11 @@ | ||||
| #include "uthash.h" | ||||
| #include "utlist.h" | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "chan.h" | ||||
| #include "emu.h" | ||||
| #include "emu_task.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| #include "chan.h" | ||||
| 
 | ||||
| struct task * | ||||
| task_find(struct task *tasks, uint32_t task_id) | ||||
| @ -30,21 +30,21 @@ task_type_find(struct task_type *types, uint32_t type_id) | ||||
| 
 | ||||
| void | ||||
| task_create(struct ovni_emu *emu, struct task_info *info, | ||||
| 		uint32_t type_id, uint32_t task_id) | ||||
| 	uint32_t type_id, uint32_t task_id) | ||||
| { | ||||
| 	/* Ensure the task id is new */ | ||||
| 	if(task_find(info->tasks, task_id) != NULL) | ||||
| 	if (task_find(info->tasks, task_id) != NULL) | ||||
| 		edie(emu, "cannot create task: task_id %u already exists\n", | ||||
| 				task_id); | ||||
| 			task_id); | ||||
| 
 | ||||
| 	/* Ensure the type exists */ | ||||
| 	struct task_type *type = task_type_find(info->types, type_id); | ||||
| 	if(type == NULL) | ||||
| 	if (type == NULL) | ||||
| 		edie(emu, "cannot create task: unknown type id %u\n", type_id); | ||||
| 
 | ||||
| 	struct task *task = calloc(1, sizeof(struct task)); | ||||
| 
 | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		die("calloc failed\n"); | ||||
| 
 | ||||
| 	task->id = task_id; | ||||
| @ -60,24 +60,24 @@ task_create(struct ovni_emu *emu, struct task_info *info, | ||||
| 
 | ||||
| void | ||||
| task_execute(struct ovni_emu *emu, | ||||
| 		struct task_stack *stack, struct task *task) | ||||
| 	struct task_stack *stack, struct task *task) | ||||
| { | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot execute: task is NULL\n"); | ||||
| 
 | ||||
| 	if(task->state != TASK_ST_CREATED) | ||||
| 	if (task->state != TASK_ST_CREATED) | ||||
| 		edie(emu, "cannot execute task %u: state is not created\n", task->id); | ||||
| 
 | ||||
| 	if(task->thread != NULL) | ||||
| 	if (task->thread != NULL) | ||||
| 		edie(emu, "task already has a thread assigned\n"); | ||||
| 
 | ||||
| 	if(stack->thread->state != TH_ST_RUNNING) | ||||
| 	if (stack->thread->state != TH_ST_RUNNING) | ||||
| 		edie(emu, "thread state is not running\n"); | ||||
| 
 | ||||
| 	if(stack->top == task) | ||||
| 	if (stack->top == task) | ||||
| 		edie(emu, "thread already has assigned task %u\n", task->id); | ||||
| 
 | ||||
| 	if(stack->top && stack->top->state != TASK_ST_RUNNING) | ||||
| 	if (stack->top && stack->top->state != TASK_ST_RUNNING) | ||||
| 		edie(emu, "cannot execute a nested task from a non-running task\n"); | ||||
| 
 | ||||
| 	task->state = TASK_ST_RUNNING; | ||||
| @ -90,24 +90,24 @@ task_execute(struct ovni_emu *emu, | ||||
| 
 | ||||
| void | ||||
| task_pause(struct ovni_emu *emu, | ||||
| 		struct task_stack *stack, struct task *task) | ||||
| 	struct task_stack *stack, struct task *task) | ||||
| { | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot pause: task is NULL\n"); | ||||
| 
 | ||||
| 	if(task->state != TASK_ST_RUNNING) | ||||
| 	if (task->state != TASK_ST_RUNNING) | ||||
| 		edie(emu, "cannot pause: task state is not running\n"); | ||||
| 
 | ||||
| 	if(task->thread == NULL) | ||||
| 	if (task->thread == NULL) | ||||
| 		edie(emu, "cannot pause: task has no thread assigned\n"); | ||||
| 
 | ||||
| 	if(stack->thread->state != TH_ST_RUNNING) | ||||
| 	if (stack->thread->state != TH_ST_RUNNING) | ||||
| 		edie(emu, "cannot pause: thread state is not running\n"); | ||||
| 
 | ||||
| 	if(stack->top != task) | ||||
| 	if (stack->top != task) | ||||
| 		edie(emu, "thread has assigned a different task\n"); | ||||
| 
 | ||||
| 	if(stack->thread != task->thread) | ||||
| 	if (stack->thread != task->thread) | ||||
| 		edie(emu, "task is assigned to a different thread\n"); | ||||
| 
 | ||||
| 	task->state = TASK_ST_PAUSED; | ||||
| @ -117,24 +117,24 @@ task_pause(struct ovni_emu *emu, | ||||
| 
 | ||||
| void | ||||
| task_resume(struct ovni_emu *emu, | ||||
| 		struct task_stack *stack, struct task *task) | ||||
| 	struct task_stack *stack, struct task *task) | ||||
| { | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot resume: task is NULL\n"); | ||||
| 
 | ||||
| 	if(task->state != TASK_ST_PAUSED) | ||||
| 	if (task->state != TASK_ST_PAUSED) | ||||
| 		edie(emu, "task state is not paused\n"); | ||||
| 
 | ||||
| 	if(task->thread == NULL) | ||||
| 	if (task->thread == NULL) | ||||
| 		edie(emu, "cannot resume: task has no thread assigned\n"); | ||||
| 
 | ||||
| 	if(stack->thread->state != TH_ST_RUNNING) | ||||
| 	if (stack->thread->state != TH_ST_RUNNING) | ||||
| 		edie(emu, "thread is not running\n"); | ||||
| 
 | ||||
| 	if(stack->top != task) | ||||
| 	if (stack->top != task) | ||||
| 		edie(emu, "thread has assigned a different task\n"); | ||||
| 
 | ||||
| 	if(stack->thread != task->thread) | ||||
| 	if (stack->thread != task->thread) | ||||
| 		edie(emu, "task is assigned to a different thread\n"); | ||||
| 
 | ||||
| 	task->state = TASK_ST_RUNNING; | ||||
| @ -144,24 +144,24 @@ task_resume(struct ovni_emu *emu, | ||||
| 
 | ||||
| void | ||||
| task_end(struct ovni_emu *emu, | ||||
| 		struct task_stack *stack, struct task *task) | ||||
| 	struct task_stack *stack, struct task *task) | ||||
| { | ||||
| 	if(task == NULL) | ||||
| 	if (task == NULL) | ||||
| 		edie(emu, "cannot end: task is NULL\n"); | ||||
| 
 | ||||
| 	if(task->state != TASK_ST_RUNNING) | ||||
| 	if (task->state != TASK_ST_RUNNING) | ||||
| 		edie(emu, "task state is not running\n"); | ||||
| 
 | ||||
| 	if(task->thread == NULL) | ||||
| 	if (task->thread == NULL) | ||||
| 		edie(emu, "cannot end: task has no thread assigned\n"); | ||||
| 
 | ||||
| 	if(stack->thread->state != TH_ST_RUNNING) | ||||
| 	if (stack->thread->state != TH_ST_RUNNING) | ||||
| 		edie(emu, "cannot end task: thread is not running\n"); | ||||
| 
 | ||||
| 	if(stack->top != task) | ||||
| 	if (stack->top != task) | ||||
| 		edie(emu, "thread has assigned a different task\n"); | ||||
| 
 | ||||
| 	if(stack->thread != task->thread) | ||||
| 	if (stack->thread != task->thread) | ||||
| 		edie(emu, "task is assigned to a different thread\n"); | ||||
| 
 | ||||
| 	task->state = TASK_ST_DEAD; | ||||
| @ -187,7 +187,7 @@ get_task_type_gid(const char *label) | ||||
| 	/* Avoid bad colors for "Unlabeled0" */ | ||||
| 	gid += 123; | ||||
| 
 | ||||
| 	if(gid == 0) | ||||
| 	if (gid == 0) | ||||
| 		gid++; | ||||
| 
 | ||||
| 	return gid; | ||||
| @ -200,29 +200,29 @@ task_type_create(struct task_info *info, uint32_t type_id, const char *label) | ||||
| 	/* Ensure the type id is new */ | ||||
| 	HASH_FIND_INT(info->types, &type_id, type); | ||||
| 
 | ||||
| 	if(type != NULL) | ||||
| 	if (type != NULL) | ||||
| 		die("a task type with id %u already exists\n", type_id); | ||||
| 
 | ||||
| 	type = calloc(1, sizeof(*type)); | ||||
| 
 | ||||
| 	if(type == NULL) | ||||
| 	if (type == NULL) | ||||
| 		die("calloc failed"); | ||||
| 
 | ||||
| 	type->id = type_id; | ||||
| 
 | ||||
| 	if(type->id == 0) | ||||
| 	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) | ||||
| 	if (n >= MAX_PCF_LABEL) | ||||
| 		die("task type label too long: %s\n", label); | ||||
| 
 | ||||
| 	/* Add the new task type to the hash table */ | ||||
| 	HASH_ADD_INT(info->types, id, type); | ||||
| 
 | ||||
| 	dbg("new task type created id=%d label=%s\n", type->id, | ||||
| 			type->label); | ||||
| 		type->label); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| @ -230,14 +230,12 @@ task_create_pcf_types(struct pcf_type *pcftype, struct task_type *types) | ||||
| { | ||||
| 	/* Emit types for all task types */ | ||||
| 	struct task_type *tt; | ||||
| 	for(tt = types; tt != NULL; tt = tt->hh.next) | ||||
| 	{ | ||||
| 	for (tt = types; tt != NULL; tt = tt->hh.next) { | ||||
| 		struct pcf_value *pcfvalue = pcf_find_value(pcftype, tt->gid); | ||||
| 		if(pcfvalue != NULL) | ||||
| 		{ | ||||
| 		if (pcfvalue != NULL) { | ||||
| 			/* Ensure the label is the same, so we know that
 | ||||
| 			 * no collision occurred */ | ||||
| 			if(strcmp(pcfvalue->label, tt->label) != 0) | ||||
| 			if (strcmp(pcfvalue->label, tt->label) != 0) | ||||
| 				die("collision occurred in task type labels\n"); | ||||
| 			else | ||||
| 				continue; | ||||
| @ -251,7 +249,7 @@ struct task * | ||||
| task_get_running(struct task_stack *stack) | ||||
| { | ||||
| 	struct task *task = stack->top; | ||||
| 	if(task && task->state == TASK_ST_RUNNING) | ||||
| 	if (task && task->state == TASK_ST_RUNNING) | ||||
| 		return task; | ||||
| 
 | ||||
| 	return NULL; | ||||
|  | ||||
							
								
								
									
										26
									
								
								heap.h
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								heap.h
									
									
									
									
									
								
							| @ -7,8 +7,8 @@ | ||||
| #ifndef HEAP_H | ||||
| #define HEAP_H | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| #include "common.h" | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| typedef struct heap_node { | ||||
| 	struct heap_node *parent; | ||||
| @ -24,15 +24,19 @@ typedef struct head_head { | ||||
| #define heap_elem(head, type, name) \ | ||||
| 	((type *) (((char *) head) - offsetof(type, name))) | ||||
| 
 | ||||
| #define heap_swap(a, b) \ | ||||
| 	do { heap_node_t *aux = (a); (a) = (b); (b) = aux; } while(0) | ||||
| #define heap_swap(a, b)                 \ | ||||
| 	do {                            \ | ||||
| 		heap_node_t *aux = (a); \ | ||||
| 		(a) = (b);              \ | ||||
| 		(b) = aux;              \ | ||||
| 	} while (0) | ||||
| 
 | ||||
| /* heap_node_compare_t - comparison function.
 | ||||
|  * The comparison function cmp(a, b) shall return an integer: | ||||
|  *  > 0 if a > b | ||||
|  *  < 0 if a < b | ||||
|  *  = 0 if a == b | ||||
|  *  | ||||
|  * | ||||
|  * Invert the comparison function to get a min-heap instead */ | ||||
| typedef int (*heap_node_compare_t)(heap_node_t *a, heap_node_t *b); | ||||
| 
 | ||||
| @ -116,7 +120,7 @@ heap_get_move(size_t *node /*out*/) | ||||
| 
 | ||||
| 	// Round to previous po2
 | ||||
| 	size_t base = (1ULL) << (sizeof(size_t) * 8 | ||||
| 			- __builtin_clzll(aux_node) - 1); | ||||
| 				 - __builtin_clzll(aux_node) - 1); | ||||
| 
 | ||||
| 	aux_node -= base / 2; | ||||
| 
 | ||||
| @ -157,7 +161,7 @@ heap_pop_max(heap_head_t *head, heap_node_compare_t cmp) | ||||
| 
 | ||||
| 	size_t size = head->size; | ||||
| 	heap_node_t *change = heap_get(head, size); | ||||
| 	if(change == NULL) | ||||
| 	if (change == NULL) | ||||
| 		die("heap_pop_max: heap_get() failed\n"); | ||||
| 
 | ||||
| 	head->size--; | ||||
| @ -189,10 +193,10 @@ heap_pop_max(heap_head_t *head, heap_node_compare_t cmp) | ||||
| 		else | ||||
| 			change->parent->left = NULL; | ||||
| 
 | ||||
| 		if(change->left) | ||||
| 		if (change->left) | ||||
| 			die("heap_pop_max: change->left not NULL\n"); | ||||
| 
 | ||||
| 		if(change->right) | ||||
| 		if (change->right) | ||||
| 			die("heap_pop_max: change->right not NULL\n"); | ||||
| 
 | ||||
| 		change->left = max->left; | ||||
| @ -230,11 +234,11 @@ heap_insert(heap_head_t *head, heap_node_t *node, heap_node_compare_t cmp) | ||||
| 
 | ||||
| 	// Right child
 | ||||
| 	if (head->size % 2) { | ||||
| 		if(parent->right) | ||||
| 		if (parent->right) | ||||
| 			die("heap_insert: parent->right already set\n"); | ||||
| 		parent->right = node; | ||||
| 	} else { | ||||
| 		if(parent->left) | ||||
| 		if (parent->left) | ||||
| 			die("heap_insert: parent->left already set\n"); | ||||
| 		parent->left = node; | ||||
| 	} | ||||
| @ -286,4 +290,4 @@ heap_insert(heap_head_t *head, heap_node_t *node, heap_node_compare_t cmp) | ||||
| 		head->root = node; | ||||
| } | ||||
| 
 | ||||
| #endif // HEAP_H
 | ||||
| #endif// HEAP_H
 | ||||
|  | ||||
							
								
								
									
										202
									
								
								ovni.c
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								ovni.c
									
									
									
									
									
								
							| @ -6,7 +6,6 @@ | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <sys/mman.h> | ||||
| @ -14,10 +13,10 @@ | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "common.h" | ||||
| #include "parson.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| #include "parson.h" | ||||
| 
 | ||||
| /* Data per process */ | ||||
| struct ovni_rproc rproc = {0}; | ||||
| @ -31,15 +30,15 @@ create_trace_stream(void) | ||||
| 	char path[PATH_MAX]; | ||||
| 
 | ||||
| 	int written = snprintf(path, PATH_MAX, "%s/thread.%d", | ||||
| 			rproc.procdir, rthread.tid); | ||||
| 		rproc.procdir, rthread.tid); | ||||
| 
 | ||||
| 	if(written >= PATH_MAX) | ||||
| 	if (written >= PATH_MAX) | ||||
| 		die("thread trace path too long: %s/thread.%d\n", | ||||
| 				rproc.procdir, rthread.tid); | ||||
| 			rproc.procdir, rthread.tid); | ||||
| 
 | ||||
| 	rthread.streamfd = open(path, O_WRONLY | O_CREAT, 0644); | ||||
| 
 | ||||
| 	if(rthread.streamfd == -1) | ||||
| 	if (rthread.streamfd == -1) | ||||
| 		die("open %s failed: %s\n", path, strerror(errno)); | ||||
| } | ||||
| 
 | ||||
| @ -48,7 +47,7 @@ proc_metadata_init(struct ovni_rproc *proc) | ||||
| { | ||||
| 	proc->meta = json_value_init_object(); | ||||
| 
 | ||||
| 	if(proc->meta == NULL) | ||||
| 	if (proc->meta == NULL) | ||||
| 		die("failed to create metadata JSON object\n"); | ||||
| } | ||||
| 
 | ||||
| @ -57,35 +56,35 @@ proc_metadata_store(JSON_Value *meta, const char *procdir) | ||||
| { | ||||
| 	char path[PATH_MAX]; | ||||
| 
 | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("process metadata not initialized\n"); | ||||
| 
 | ||||
| 	if(snprintf(path, PATH_MAX, "%s/metadata.json", procdir) >= PATH_MAX) | ||||
| 	if (snprintf(path, PATH_MAX, "%s/metadata.json", procdir) >= PATH_MAX) | ||||
| 		die("metadata path too long: %s/metadata.json\n", | ||||
| 				procdir); | ||||
| 			procdir); | ||||
| 
 | ||||
| 	if(json_serialize_to_file_pretty(meta, path) != JSONSuccess) | ||||
| 	if (json_serialize_to_file_pretty(meta, path) != JSONSuccess) | ||||
| 		die("failed to write process metadata\n"); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ovni_add_cpu(int index, int phyid) | ||||
| { | ||||
| 	if(index < 0) | ||||
| 	if (index < 0) | ||||
| 		die("ovni_add_cpu: cannot use negative index %d\n", index); | ||||
| 
 | ||||
| 	if(phyid < 0) | ||||
| 	if (phyid < 0) | ||||
| 		die("ovni_add_cpu: cannot use negative CPU id %d\n", phyid); | ||||
| 
 | ||||
| 	if(!rproc.ready) | ||||
| 	if (!rproc.ready) | ||||
| 		die("ovni_add_cpu: process not yet initialized\n"); | ||||
| 
 | ||||
| 	if(rproc.meta == NULL) | ||||
| 	if (rproc.meta == NULL) | ||||
| 		die("ovni_add_cpu: metadata not initialized\n"); | ||||
| 
 | ||||
| 	JSON_Object *meta = json_value_get_object(rproc.meta); | ||||
| 
 | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("ovni_add_cpu: json_value_get_object() failed\n"); | ||||
| 
 | ||||
| 	int first_time = 0; | ||||
| @ -93,43 +92,41 @@ ovni_add_cpu(int index, int phyid) | ||||
| 	/* Find the CPU array and create it if needed */ | ||||
| 	JSON_Array *cpuarray = json_object_dotget_array(meta, "cpus"); | ||||
| 
 | ||||
| 	if(cpuarray == NULL) | ||||
| 	{ | ||||
| 	if (cpuarray == NULL) { | ||||
| 		JSON_Value *value = json_value_init_array(); | ||||
| 		if(value == NULL) | ||||
| 		if (value == NULL) | ||||
| 			die("ovni_add_cpu: json_value_init_array() failed\n"); | ||||
| 
 | ||||
| 		cpuarray = json_array(value); | ||||
| 		if(cpuarray == NULL) | ||||
| 		if (cpuarray == NULL) | ||||
| 			die("ovni_add_cpu: json_array() failed\n"); | ||||
| 
 | ||||
| 		first_time = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	JSON_Value *valcpu = json_value_init_object(); | ||||
| 	if(valcpu == NULL) | ||||
| 	if (valcpu == NULL) | ||||
| 		die("ovni_add_cpu: json_value_init_object() failed\n"); | ||||
| 
 | ||||
| 	JSON_Object *cpu = json_object(valcpu); | ||||
| 	if(cpu == NULL) | ||||
| 	if (cpu == NULL) | ||||
| 		die("ovni_add_cpu: json_object() failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(cpu, "index", index) != 0) | ||||
| 	if (json_object_set_number(cpu, "index", index) != 0) | ||||
| 		die("ovni_add_cpu: json_object_set_number() failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(cpu, "phyid", phyid) != 0) | ||||
| 	if (json_object_set_number(cpu, "phyid", phyid) != 0) | ||||
| 		die("ovni_add_cpu: json_object_set_number() failed\n"); | ||||
| 
 | ||||
| 	if(json_array_append_value(cpuarray, valcpu) != 0) | ||||
| 	if (json_array_append_value(cpuarray, valcpu) != 0) | ||||
| 		die("ovni_add_cpu: json_array_append_value() failed\n"); | ||||
| 
 | ||||
| 	if(first_time) | ||||
| 	{ | ||||
| 	if (first_time) { | ||||
| 		JSON_Value *value = json_array_get_wrapping_value(cpuarray); | ||||
| 		if(value == NULL) | ||||
| 		if (value == NULL) | ||||
| 			die("ovni_add_cpu: json_array_get_wrapping_value() failed\n"); | ||||
| 
 | ||||
| 		if(json_object_set_value(meta, "cpus", value) != 0) | ||||
| 		if (json_object_set_value(meta, "cpus", value) != 0) | ||||
| 			die("ovni_add_cpu: json_object_set_value failed\n"); | ||||
| 	} | ||||
| } | ||||
| @ -139,10 +136,10 @@ proc_set_app(int appid) | ||||
| { | ||||
| 	JSON_Object *meta = json_value_get_object(rproc.meta); | ||||
| 
 | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("json_value_get_object failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(meta, "app_id", appid) != 0) | ||||
| 	if (json_object_set_number(meta, "app_id", appid) != 0) | ||||
| 		die("json_object_set_number for app_id failed\n"); | ||||
| } | ||||
| 
 | ||||
| @ -151,13 +148,13 @@ proc_set_version(void) | ||||
| { | ||||
| 	JSON_Object *meta = json_value_get_object(rproc.meta); | ||||
| 
 | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("json_value_get_object failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(meta, "version", OVNI_METADATA_VERSION) != 0) | ||||
| 	if (json_object_set_number(meta, "version", OVNI_METADATA_VERSION) != 0) | ||||
| 		die("json_object_set_number for version failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_string(meta, "model_version", OVNI_MODEL_VERSION) != 0) | ||||
| 	if (json_object_set_string(meta, "model_version", OVNI_MODEL_VERSION) != 0) | ||||
| 		die("json_object_set_string for model_version failed\n"); | ||||
| } | ||||
| 
 | ||||
| @ -165,18 +162,18 @@ proc_set_version(void) | ||||
| void | ||||
| ovni_proc_set_rank(int rank, int nranks) | ||||
| { | ||||
| 	if(!rproc.ready) | ||||
| 	if (!rproc.ready) | ||||
| 		die("ovni_proc_set_rank: process not yet initialized\n"); | ||||
| 
 | ||||
| 	JSON_Object *meta = json_value_get_object(rproc.meta); | ||||
| 
 | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("json_value_get_object failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(meta, "rank", rank) != 0) | ||||
| 	if (json_object_set_number(meta, "rank", rank) != 0) | ||||
| 		die("json_object_set_number for rank failed\n"); | ||||
| 
 | ||||
| 	if(json_object_set_number(meta, "nranks", nranks) != 0) | ||||
| 	if (json_object_set_number(meta, "nranks", nranks) != 0) | ||||
| 		die("json_object_set_number for nranks failed\n"); | ||||
| } | ||||
| 
 | ||||
| @ -197,7 +194,7 @@ mkdir_proc(char *path, const char *tracedir, const char *loom, int pid) | ||||
| 	snprintf(path, PATH_MAX, "%s/loom.%s/proc.%d", tracedir, loom, pid); | ||||
| 
 | ||||
| 	/* But this one shall not fail */ | ||||
| 	if(mkdir(path, 0755)) | ||||
| 	if (mkdir(path, 0755)) | ||||
| 		die("mkdir %s failed: %s\n", path, strerror(errno)); | ||||
| } | ||||
| 
 | ||||
| @ -206,14 +203,11 @@ create_proc_dir(const char *loom, int pid) | ||||
| { | ||||
| 	char *tmpdir = getenv("OVNI_TMPDIR"); | ||||
| 
 | ||||
| 	if(tmpdir != NULL) | ||||
| 	{ | ||||
| 	if (tmpdir != NULL) { | ||||
| 		rproc.move_to_final = 1; | ||||
| 		mkdir_proc(rproc.procdir, tmpdir, loom, pid); | ||||
| 		mkdir_proc(rproc.procdir_final, OVNI_TRACEDIR, loom, pid); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		rproc.move_to_final = 0; | ||||
| 		mkdir_proc(rproc.procdir, OVNI_TRACEDIR, loom, pid); | ||||
| 	} | ||||
| @ -222,12 +216,12 @@ create_proc_dir(const char *loom, int pid) | ||||
| void | ||||
| ovni_proc_init(int app, const char *loom, int pid) | ||||
| { | ||||
| 	if(rproc.ready) | ||||
| 	if (rproc.ready) | ||||
| 		die("ovni_proc_init: pid %d already initialized\n", pid); | ||||
| 
 | ||||
| 	memset(&rproc, 0, sizeof(rproc)); | ||||
| 
 | ||||
| 	if(strlen(loom) >= OVNI_MAX_HOSTNAME) | ||||
| 	if (strlen(loom) >= OVNI_MAX_HOSTNAME) | ||||
| 		die("ovni_proc_init: loom name too long: %s\n", loom); | ||||
| 
 | ||||
| 	strcpy(rproc.loom, loom); | ||||
| @ -253,28 +247,25 @@ move_thread_to_final(const char *src, const char *dst) | ||||
| 
 | ||||
| 	FILE *infile = fopen(src, "r"); | ||||
| 
 | ||||
| 	if(infile == NULL) | ||||
| 	{ | ||||
| 	if (infile == NULL) { | ||||
| 		err("fopen(%s) failed: %s\n", src, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	FILE *outfile = fopen(dst, "w"); | ||||
| 
 | ||||
| 	if(outfile == NULL) | ||||
| 	{ | ||||
| 	if (outfile == NULL) { | ||||
| 		err("fopen(%s) failed: %s\n", src, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	while((bytes = fread(buffer, 1, sizeof(buffer), infile)) > 0) | ||||
| 	while ((bytes = fread(buffer, 1, sizeof(buffer), infile)) > 0) | ||||
| 		fwrite(buffer, 1, bytes, outfile); | ||||
| 
 | ||||
| 	fclose(outfile); | ||||
| 	fclose(infile); | ||||
| 
 | ||||
| 	if(remove(src) != 0) | ||||
| 	{ | ||||
| 	if (remove(src) != 0) { | ||||
| 		err("remove(%s) failed: %s\n", src, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -291,71 +282,65 @@ move_procdir_to_final(const char *procdir, const char *procdir_final) | ||||
| 	char thread_final[PATH_MAX]; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	if((dir = opendir(procdir)) == NULL) | ||||
| 	{ | ||||
| 	if ((dir = opendir(procdir)) == NULL) { | ||||
| 		err("opendir %s failed: %s\n", procdir, strerror(errno)); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	const char *prefix = "thread."; | ||||
| 	while((dirent = readdir(dir)) != NULL) | ||||
| 	{ | ||||
| 	while ((dirent = readdir(dir)) != NULL) { | ||||
| 		/* It should only contain thread.* directories, skip others */ | ||||
| 		if(strncmp(dirent->d_name, prefix, strlen(prefix)) != 0) | ||||
| 		if (strncmp(dirent->d_name, prefix, strlen(prefix)) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if(snprintf(thread, PATH_MAX, "%s/%s", procdir, | ||||
| 				dirent->d_name) >= PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(thread, PATH_MAX, "%s/%s", procdir, | ||||
| 			    dirent->d_name) | ||||
| 			>= PATH_MAX) { | ||||
| 			err("snprintf: path too large: %s/%s\n", procdir, | ||||
| 					dirent->d_name); | ||||
| 				dirent->d_name); | ||||
| 			err = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(snprintf(thread_final, PATH_MAX, "%s/%s", procdir_final, | ||||
| 				dirent->d_name) >= PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(thread_final, PATH_MAX, "%s/%s", procdir_final, | ||||
| 			    dirent->d_name) | ||||
| 			>= PATH_MAX) { | ||||
| 			err("snprintf: path too large: %s/%s\n", procdir_final, | ||||
| 					dirent->d_name); | ||||
| 				dirent->d_name); | ||||
| 			err = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(move_thread_to_final(thread, thread_final) != 0) | ||||
| 		if (move_thread_to_final(thread, thread_final) != 0) | ||||
| 			err = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	closedir(dir); | ||||
| 
 | ||||
| 	if(rmdir(procdir) != 0) | ||||
| 	{ | ||||
| 	if (rmdir(procdir) != 0) { | ||||
| 		err("rmdir(%s) failed: %s\n", procdir, strerror(errno)); | ||||
| 		err = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Warn the user, but we cannot do much at this point */ | ||||
| 	if(err) | ||||
| 	if (err) | ||||
| 		err("errors occurred when moving the trace to %s\n", procdir_final); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| ovni_proc_fini(void) | ||||
| { | ||||
| 	if(!rproc.ready) | ||||
| 	if (!rproc.ready) | ||||
| 		die("ovni_proc_fini: process not initialized\n"); | ||||
| 
 | ||||
| 	/* Mark the process no longer ready */ | ||||
| 	rproc.ready = 0; | ||||
| 
 | ||||
| 
 | ||||
| 	if(rproc.move_to_final) | ||||
| 	{ | ||||
| 	if (rproc.move_to_final) { | ||||
| 		proc_metadata_store(rproc.meta, rproc.procdir_final); | ||||
| 		move_procdir_to_final(rproc.procdir, rproc.procdir_final); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		proc_metadata_store(rproc.meta, rproc.procdir); | ||||
| 	} | ||||
| } | ||||
| @ -363,16 +348,15 @@ ovni_proc_fini(void) | ||||
| static void | ||||
| write_evbuf(uint8_t *buf, size_t size) | ||||
| { | ||||
| 	do | ||||
| 	{ | ||||
| 	do { | ||||
| 		ssize_t written = write(rthread.streamfd, buf, size); | ||||
| 
 | ||||
| 		if(written < 0) | ||||
| 		if (written < 0) | ||||
| 			die("failed to write buffer to disk: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 		size -= written; | ||||
| 		buf += written; | ||||
| 	} while(size > 0); | ||||
| 	} while (size > 0); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -399,16 +383,15 @@ write_stream_header(void) | ||||
| void | ||||
| ovni_thread_init(pid_t tid) | ||||
| { | ||||
| 	if(rthread.ready) | ||||
| 	{ | ||||
| 	if (rthread.ready) { | ||||
| 		err("warning: thread %d already initialized, ignored\n", tid); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if(tid == 0) | ||||
| 	if (tid == 0) | ||||
| 		die("ovni_thread_init: cannot use tid=%d\n", tid); | ||||
| 
 | ||||
| 	if(!rproc.ready) | ||||
| 	if (!rproc.ready) | ||||
| 		die("ovni_thread_init: process not yet initialized\n"); | ||||
| 
 | ||||
| 	memset(&rthread, 0, sizeof(rthread)); | ||||
| @ -417,7 +400,7 @@ ovni_thread_init(pid_t tid) | ||||
| 	rthread.evlen = 0; | ||||
| 	rthread.evbuf = malloc(OVNI_MAX_EV_BUF); | ||||
| 
 | ||||
| 	if(rthread.evbuf == NULL) | ||||
| 	if (rthread.evbuf == NULL) | ||||
| 		die("ovni_thread_init: malloc failed: %s", strerror(errno)); | ||||
| 
 | ||||
| 	create_trace_stream(); | ||||
| @ -429,7 +412,7 @@ ovni_thread_init(pid_t tid) | ||||
| void | ||||
| ovni_thread_free(void) | ||||
| { | ||||
| 	if(!rthread.ready) | ||||
| 	if (!rthread.ready) | ||||
| 		die("ovni_thread_free: thread not initialized\n"); | ||||
| 
 | ||||
| 	free(rthread.evbuf); | ||||
| @ -442,13 +425,14 @@ ovni_thread_isready(void) | ||||
| } | ||||
| 
 | ||||
| #ifdef USE_TSC | ||||
| static inline | ||||
| uint64_t clock_tsc_now(void) | ||||
| static inline uint64_t | ||||
| clock_tsc_now(void) | ||||
| { | ||||
| 	uint32_t lo, hi; | ||||
| 
 | ||||
| 	/* RDTSC copies contents of 64-bit TSC into EDX:EAX */ | ||||
| 	__asm__ volatile("rdtsc" : "=a" (lo), "=d" (hi)); | ||||
| 	__asm__ volatile("rdtsc" | ||||
| 			 : "=a"(lo), "=d"(hi)); | ||||
| 	return (uint64_t) hi << 32 | lo; | ||||
| } | ||||
| #endif | ||||
| @ -459,7 +443,7 @@ clock_monotonic_now(void) | ||||
| 	uint64_t ns = 1000ULL * 1000ULL * 1000ULL; | ||||
| 	struct timespec tp; | ||||
| 
 | ||||
| 	if(clock_gettime(rproc.clockid, &tp)) | ||||
| 	if (clock_gettime(rproc.clockid, &tp)) | ||||
| 		die("clock_gettime() failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	return tp.tv_sec * ns + tp.tv_nsec; | ||||
| @ -506,12 +490,12 @@ ovni_payload_size(const struct ovni_ev *ev) | ||||
| { | ||||
| 	int size; | ||||
| 
 | ||||
| 	if(ev->header.flags & OVNI_EV_JUMBO) | ||||
| 	if (ev->header.flags & OVNI_EV_JUMBO) | ||||
| 		return get_jumbo_payload_size(ev); | ||||
| 
 | ||||
| 	size = ev->header.flags & 0x0f; | ||||
| 
 | ||||
| 	if(size == 0) | ||||
| 	if (size == 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* The minimum size is 2 bytes, so we can encode a length of 16
 | ||||
| @ -524,22 +508,22 @@ ovni_payload_size(const struct ovni_ev *ev) | ||||
| void | ||||
| ovni_payload_add(struct ovni_ev *ev, const uint8_t *buf, int size) | ||||
| { | ||||
| 	if(ev->header.flags & OVNI_EV_JUMBO) | ||||
| 	if (ev->header.flags & OVNI_EV_JUMBO) | ||||
| 		die("ovni_payload_add: event is marked as jumbo\n"); | ||||
| 
 | ||||
| 	if(size < 2) | ||||
| 	if (size < 2) | ||||
| 		die("ovni_payload_add: payload size %d too small\n", size); | ||||
| 
 | ||||
| 	size_t payload_size = ovni_payload_size(ev); | ||||
| 
 | ||||
| 	/* Ensure we have room */ | ||||
| 	if(payload_size + size > sizeof(ev->payload)) | ||||
| 	if (payload_size + size > sizeof(ev->payload)) | ||||
| 		die("ovni_payload_add: no space left for %d bytes\n", size); | ||||
| 
 | ||||
| 	memcpy(&ev->payload.u8[payload_size], buf, size); | ||||
| 	payload_size += size; | ||||
| 
 | ||||
| 	ev->header.flags = (ev->header.flags & 0xf0) | ((payload_size-1) & 0x0f); | ||||
| 	ev->header.flags = (ev->header.flags & 0xf0) | ((payload_size - 1) & 0x0f); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| @ -554,12 +538,12 @@ ovni_ev_add(struct ovni_ev *ev); | ||||
| void | ||||
| ovni_flush(void) | ||||
| { | ||||
| 	struct ovni_ev pre={0}, post={0}; | ||||
| 	struct ovni_ev pre = {0}, post = {0}; | ||||
| 
 | ||||
| 	if(!rthread.ready) | ||||
| 	if (!rthread.ready) | ||||
| 		die("ovni_flush: thread is not initialized\n"); | ||||
| 
 | ||||
| 	if(!rproc.ready) | ||||
| 	if (!rproc.ready) | ||||
| 		die("ovni_flush: process is not initialized\n"); | ||||
| 
 | ||||
| 	ovni_ev_set_clock(&pre, ovni_clock_now()); | ||||
| @ -578,7 +562,7 @@ ovni_flush(void) | ||||
| static void | ||||
| add_flush_events(uint64_t t0, uint64_t t1) | ||||
| { | ||||
| 	struct ovni_ev pre={0}, post={0}; | ||||
| 	struct ovni_ev pre = {0}, post = {0}; | ||||
| 
 | ||||
| 	pre.header.clock = t0; | ||||
| 	ovni_ev_set_mcv(&pre, "OF["); | ||||
| @ -597,7 +581,7 @@ ovni_ev_add_jumbo(struct ovni_ev *ev, const uint8_t *buf, uint32_t bufsize) | ||||
| 	int flushed = 0; | ||||
| 	uint64_t t0, t1; | ||||
| 
 | ||||
| 	if(ovni_payload_size(ev) != 0) | ||||
| 	if (ovni_payload_size(ev) != 0) | ||||
| 		die("ovni_ev_add_jumbo: the event payload must be empty\n"); | ||||
| 
 | ||||
| 	ovni_payload_add(ev, (uint8_t *) &bufsize, sizeof(bufsize)); | ||||
| @ -605,12 +589,11 @@ ovni_ev_add_jumbo(struct ovni_ev *ev, const uint8_t *buf, uint32_t bufsize) | ||||
| 
 | ||||
| 	size_t totalsize = evsize + bufsize; | ||||
| 
 | ||||
| 	if(totalsize >= OVNI_MAX_EV_BUF) | ||||
| 	if (totalsize >= OVNI_MAX_EV_BUF) | ||||
| 		die("ovni_ev_add_jumbo: event too large\n"); | ||||
| 
 | ||||
| 	/* Check if the event fits or flush first otherwise */ | ||||
| 	if(rthread.evlen + totalsize >= OVNI_MAX_EV_BUF) | ||||
| 	{ | ||||
| 	if (rthread.evlen + totalsize >= OVNI_MAX_EV_BUF) { | ||||
| 		/* Measure the flush times */ | ||||
| 		t0 = ovni_clock_now(); | ||||
| 		flush_evbuf(); | ||||
| @ -627,8 +610,7 @@ ovni_ev_add_jumbo(struct ovni_ev *ev, const uint8_t *buf, uint32_t bufsize) | ||||
| 	memcpy(&rthread.evbuf[rthread.evlen], buf, bufsize); | ||||
| 	rthread.evlen += bufsize; | ||||
| 
 | ||||
| 	if(flushed) | ||||
| 	{ | ||||
| 	if (flushed) { | ||||
| 		/* Emit the flush events *after* the user event */ | ||||
| 		add_flush_events(t0, t1); | ||||
| 	} | ||||
| @ -643,8 +625,7 @@ ovni_ev_add(struct ovni_ev *ev) | ||||
| 	int size = ovni_ev_size(ev); | ||||
| 
 | ||||
| 	/* Check if the event fits or flush first otherwise */ | ||||
| 	if(rthread.evlen + size >= OVNI_MAX_EV_BUF) | ||||
| 	{ | ||||
| 	if (rthread.evlen + size >= OVNI_MAX_EV_BUF) { | ||||
| 		/* Measure the flush times */ | ||||
| 		t0 = ovni_clock_now(); | ||||
| 		flush_evbuf(); | ||||
| @ -655,8 +636,7 @@ ovni_ev_add(struct ovni_ev *ev) | ||||
| 	memcpy(&rthread.evbuf[rthread.evlen], ev, size); | ||||
| 	rthread.evlen += size; | ||||
| 
 | ||||
| 	if(flushed) | ||||
| 	{ | ||||
| 	if (flushed) { | ||||
| 		/* Emit the flush events *after* the user event */ | ||||
| 		add_flush_events(t0, t1); | ||||
| 	} | ||||
|  | ||||
							
								
								
									
										9
									
								
								ovni.h
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								ovni.h
									
									
									
									
									
								
							| @ -8,16 +8,16 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <linux/limits.h> | ||||
| #include <sys/types.h> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| /* Hardcode the JSON_Value to avoid a dependency with janson */ | ||||
| typedef struct json_value_t  JSON_Value; | ||||
| typedef struct json_value_t JSON_Value; | ||||
| 
 | ||||
| #define OVNI_METADATA_VERSION 1 | ||||
| 
 | ||||
| @ -43,7 +43,6 @@ struct __attribute__((__packed__)) ovni_jumbo_payload { | ||||
| }; | ||||
| 
 | ||||
| union __attribute__((__packed__)) ovni_ev_payload { | ||||
| 
 | ||||
| 	int8_t i8[16]; | ||||
| 	int16_t i16[8]; | ||||
| 	int32_t i32[4]; | ||||
|  | ||||
							
								
								
									
										63
									
								
								ovni2prv.c
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								ovni2prv.c
									
									
									
									
									
								
							| @ -1,15 +1,15 @@ | ||||
| /* Copyright (c) 2021 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdatomic.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <linux/limits.h> | ||||
| #include <errno.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdatomic.h> | ||||
| #include <dirent.h>  | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "trace.h" | ||||
| @ -20,19 +20,19 @@ emit(struct ovni_ev *ev, int row) | ||||
| 	static uint64_t firstclock = 0; | ||||
| 	int64_t delta; | ||||
| 
 | ||||
| 	if(firstclock == 0) | ||||
| 	if (firstclock == 0) | ||||
| 		firstclock = ovni_ev_get_clock(ev); | ||||
| 
 | ||||
| 	delta = ovni_ev_get_clock(ev) - firstclock; | ||||
| 
 | ||||
| 	//#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(00000000000000000008:1)
 | ||||
| 	//2:0:1:1:7:1540663:6400010:1
 | ||||
| 	//2:0:1:1:7:1540663:6400015:1
 | ||||
| 	//2:0:1:1:7:1540663:6400017:0
 | ||||
| 	//2:0:1:1:7:1542091:6400010:1
 | ||||
| 	//2:0:1:1:7:1542091:6400015:1
 | ||||
| 	//2:0:1:1:7:1542091:6400025:1
 | ||||
| 	//2:0:1:1:7:1542091:6400017:0
 | ||||
| 	// 2:0:1:1:7:1540663:6400010:1
 | ||||
| 	// 2:0:1:1:7:1540663:6400015:1
 | ||||
| 	// 2:0:1:1:7:1540663:6400017:0
 | ||||
| 	// 2:0:1:1:7:1542091:6400010:1
 | ||||
| 	// 2:0:1:1:7:1542091:6400015:1
 | ||||
| 	// 2:0:1:1:7:1542091:6400025:1
 | ||||
| 	// 2:0:1:1:7:1542091:6400017:0
 | ||||
| 
 | ||||
| 	printf("2:0:1:1:%d:%ld:%d:%d\n", row, delta, ev->header.category, ev->header.value); | ||||
| } | ||||
| @ -47,44 +47,39 @@ dump_events(struct ovni_trace *trace) | ||||
| 	struct ovni_stream *stream; | ||||
| 
 | ||||
| 	/* Load events */ | ||||
| 	for(i=0; i<trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nstreams; i++) { | ||||
| 		stream = &trace->stream[i]; | ||||
| 		ovni_load_next_event(stream); | ||||
| 	} | ||||
| 
 | ||||
| 	lastclock = 0; | ||||
| 
 | ||||
| 	while(1) | ||||
| 	{ | ||||
| 	while (1) { | ||||
| 		f = -1; | ||||
| 		minclock = 0; | ||||
| 
 | ||||
| 		/* Select next event based on the clock */ | ||||
| 		for(i=0; i<trace->nstreams; i++) | ||||
| 		{ | ||||
| 		for (i = 0; i < trace->nstreams; i++) { | ||||
| 			stream = &trace->stream[i]; | ||||
| 
 | ||||
| 			if(!stream->active) | ||||
| 			if (!stream->active) | ||||
| 				continue; | ||||
| 
 | ||||
| 			ev = stream->cur_ev; | ||||
| 			if(f < 0 || ovni_ev_get_clock(ev) < minclock) | ||||
| 			{ | ||||
| 			if (f < 0 || ovni_ev_get_clock(ev) < minclock) { | ||||
| 				f = i; | ||||
| 				minclock = ovni_ev_get_clock(ev); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
 | ||||
| 		// fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
 | ||||
| 
 | ||||
| 		if(f < 0) | ||||
| 		if (f < 0) | ||||
| 			break; | ||||
| 
 | ||||
| 		stream = &trace->stream[f]; | ||||
| 
 | ||||
| 		if(lastclock >= ovni_ev_get_clock(stream->cur_ev)) | ||||
| 		{ | ||||
| 		if (lastclock >= ovni_ev_get_clock(stream->cur_ev)) { | ||||
| 			fprintf(stderr, "warning: backwards jump in time\n"); | ||||
| 		} | ||||
| 
 | ||||
| @ -100,37 +95,35 @@ dump_events(struct ovni_trace *trace) | ||||
| 		/* Unset the index */ | ||||
| 		f = -1; | ||||
| 		minclock = 0; | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	char *tracedir; | ||||
| 	struct ovni_trace *trace = calloc(1, sizeof(struct ovni_trace)); | ||||
| 
 | ||||
| 	if(trace == NULL) | ||||
| 	{ | ||||
| 	if (trace == NULL) { | ||||
| 		perror("calloc"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	if(argc != 2) | ||||
| 	{ | ||||
| 	if (argc != 2) { | ||||
| 		fprintf(stderr, "missing tracedir\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	tracedir = argv[1]; | ||||
| 
 | ||||
| 	if(ovni_load_trace(trace, tracedir)) | ||||
| 	if (ovni_load_trace(trace, tracedir)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if(ovni_load_streams(trace)) | ||||
| 	if (ovni_load_streams(trace)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	printf("#Paraver (19/01/38 at 03:14):00000000000000000000_ns:0:1:1(%ld:1)\n", | ||||
| 			trace->nstreams); | ||||
| 		trace->nstreams); | ||||
| 
 | ||||
| 	dump_events(trace); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										145
									
								
								ovnisync.c
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								ovnisync.c
									
									
									
									
									
								
							| @ -60,18 +60,15 @@ static double | ||||
| get_time(clockid_t clock, int use_ns) | ||||
| { | ||||
| 	struct timespec tv; | ||||
| 	if(clock_gettime(clock, &tv) != 0) | ||||
| 	{ | ||||
| 	if (clock_gettime(clock, &tv) != 0) { | ||||
| 		perror("clock_gettime failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	if(use_ns) | ||||
| 		return (double)(tv.tv_sec) * 1.0e9 + | ||||
| 			(double)tv.tv_nsec; | ||||
| 	if (use_ns) | ||||
| 		return (double) (tv.tv_sec) * 1.0e9 + (double) tv.tv_nsec; | ||||
| 
 | ||||
| 	return (double)(tv.tv_sec) + | ||||
| 		(double)tv.tv_nsec * 1.0e-9; | ||||
| 	return (double) (tv.tv_sec) + (double) tv.tv_nsec * 1.0e-9; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| @ -82,9 +79,9 @@ cmp_double(const void *pa, const void *pb) | ||||
| 	a = *(const double *) pa; | ||||
| 	b = *(const double *) pb; | ||||
| 
 | ||||
| 	if(a < b) | ||||
| 	if (a < b) | ||||
| 		return -1; | ||||
| 	else if(a > b) | ||||
| 	else if (a > b) | ||||
| 		return 1; | ||||
| 	else | ||||
| 		return 0; | ||||
| @ -96,7 +93,7 @@ usage(void) | ||||
| 	fprintf(stderr, "%s: clock synchronization utility\n", progname); | ||||
| 	fprintf(stderr, "\n"); | ||||
| 	fprintf(stderr, "Usage: %s [-o outfile] [-d ndrift_samples] [-v] [-n nsamples] [-w drift_delay]\n", | ||||
| 			progname); | ||||
| 		progname); | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
| 
 | ||||
| @ -105,13 +102,10 @@ try_mkdir(const char *path, mode_t mode) | ||||
| { | ||||
| 	struct stat st; | ||||
| 
 | ||||
| 	if(stat(path, &st) != 0) | ||||
| 	{ | ||||
| 	if (stat(path, &st) != 0) { | ||||
| 		/* Directory does not exist */ | ||||
| 		return mkdir(path, mode); | ||||
| 	} | ||||
| 	else if(!S_ISDIR(st.st_mode)) | ||||
| 	{ | ||||
| 	} else if (!S_ISDIR(st.st_mode)) { | ||||
| 		errno = ENOTDIR; | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -183,8 +177,7 @@ parse_options(struct options *options, int argc, char *argv[]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (optind < argc) | ||||
| 	{ | ||||
| 	if (optind < argc) { | ||||
| 		fprintf(stderr, "error: unexpected extra arguments\n"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -200,8 +193,7 @@ get_clock_samples(struct offset *offset, int nsamples) | ||||
| 
 | ||||
| 	offset->nsamples = nsamples; | ||||
| 
 | ||||
| 	for(i=0; i<nsamples; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < nsamples; i++) { | ||||
| 		MPI_Barrier(MPI_COMM_WORLD); | ||||
| 		offset->clock_sample[i] = get_time(CLOCK_MONOTONIC, 1); | ||||
| 	} | ||||
| @ -218,13 +210,12 @@ fill_offset(struct offset *offset, int nsamples) | ||||
| 	MPI_Comm_rank(MPI_COMM_WORLD, &offset->rank); | ||||
| 
 | ||||
| 	/* Fill the host name */ | ||||
| 	if(gethostname(offset->hostname, OVNI_MAX_HOSTNAME) != 0) | ||||
| 	{ | ||||
| 	if (gethostname(offset->hostname, OVNI_MAX_HOSTNAME) != 0) { | ||||
| 		perror("gethostname"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	//printf("rank=%d hostname=%s\n", offset->rank, offset->hostname);
 | ||||
| 	// printf("rank=%d hostname=%s\n", offset->rank, offset->hostname);
 | ||||
| 
 | ||||
| 	/* Warm up iterations */ | ||||
| 	warmup_nsamples = nsamples >= 20 ? 20 : nsamples; | ||||
| @ -241,21 +232,18 @@ offset_compute_delta(struct offset *ref, struct offset *cur, int nsamples, int v | ||||
| 
 | ||||
| 	delta = malloc(sizeof(double) * nsamples); | ||||
| 
 | ||||
| 	if(delta == NULL) | ||||
| 	{ | ||||
| 	if (delta == NULL) { | ||||
| 		perror("malloc"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	for(i=0; i<nsamples; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < nsamples; i++) { | ||||
| 		delta[i] = ref->clock_sample[i] - cur->clock_sample[i]; | ||||
| 		if(verbose) | ||||
| 		{ | ||||
| 		if (verbose) { | ||||
| 			printf("rank=%d  sample=%d  delta=%f  ref=%f  cur=%f\n", | ||||
| 					cur->rank, i, delta[i], | ||||
| 					ref->clock_sample[i], | ||||
| 					cur->clock_sample[i]); | ||||
| 				cur->rank, i, delta[i], | ||||
| 				ref->clock_sample[i], | ||||
| 				cur->clock_sample[i]); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @ -263,14 +251,13 @@ offset_compute_delta(struct offset *ref, struct offset *cur, int nsamples, int v | ||||
| 
 | ||||
| 	cur->delta_median = delta[nsamples / 2]; | ||||
| 
 | ||||
| 	for(cur->delta_mean=0, i=0; i<nsamples; i++) | ||||
| 	for (cur->delta_mean = 0, i = 0; i < nsamples; i++) | ||||
| 		cur->delta_mean += delta[i]; | ||||
| 
 | ||||
| 	cur->delta_mean /= nsamples; | ||||
| 
 | ||||
| 	for(cur->delta_var=0, i=0; i<nsamples; i++) | ||||
| 		cur->delta_var += (delta[i] - cur->delta_mean) * | ||||
| 			(delta[i] - cur->delta_mean); | ||||
| 	for (cur->delta_var = 0, i = 0; i < nsamples; i++) | ||||
| 		cur->delta_var += (delta[i] - cur->delta_mean) * (delta[i] - cur->delta_mean); | ||||
| 
 | ||||
| 	cur->delta_var /= (double) (nsamples - 1); | ||||
| 	cur->delta_std = sqrt(cur->delta_var); | ||||
| @ -307,12 +294,10 @@ build_offset_table(int nsamples, int rank, int verbose) | ||||
| 	void *sendbuf; | ||||
| 
 | ||||
| 	/* The rank 0 must build the table */ | ||||
| 	if(rank == 0) | ||||
| 	{ | ||||
| 	if (rank == 0) { | ||||
| 		table = malloc(sizeof(*table)); | ||||
| 
 | ||||
| 		if(table == NULL) | ||||
| 		{ | ||||
| 		if (table == NULL) { | ||||
| 			perror("malloc"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| @ -321,33 +306,27 @@ build_offset_table(int nsamples, int rank, int verbose) | ||||
| 
 | ||||
| 		table->_offset = calloc(table->nprocs, offset_size(nsamples)); | ||||
| 
 | ||||
| 		if(table->_offset == NULL) | ||||
| 		{ | ||||
| 		if (table->_offset == NULL) { | ||||
| 			perror("malloc"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 
 | ||||
| 		table->offset = malloc(sizeof(struct offset *) * | ||||
| 				table->nprocs); | ||||
| 		table->offset = malloc(sizeof(struct offset *) * table->nprocs); | ||||
| 
 | ||||
| 		if(table->offset == NULL) | ||||
| 		{ | ||||
| 		if (table->offset == NULL) { | ||||
| 			perror("malloc"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 
 | ||||
| 		for(i=0; i<table->nprocs; i++) | ||||
| 		for (i = 0; i < table->nprocs; i++) | ||||
| 			table->offset[i] = table_get_offset(table, i, nsamples); | ||||
| 
 | ||||
| 		offset = table->offset[0]; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		/* Otherwise just allocate one offset */ | ||||
| 		offset = calloc(1, offset_size(nsamples)); | ||||
| 
 | ||||
| 		if(offset == NULL) | ||||
| 		{ | ||||
| 		if (offset == NULL) { | ||||
| 			perror("malloc"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| @ -362,21 +341,19 @@ build_offset_table(int nsamples, int rank, int verbose) | ||||
| 
 | ||||
| 	/* Then collect all the offsets into the rank 0 */ | ||||
| 	MPI_Gather(sendbuf, offset_size(nsamples), MPI_CHAR, | ||||
| 			offset, offset_size(nsamples), MPI_CHAR, | ||||
| 			0, MPI_COMM_WORLD); | ||||
| 		offset, offset_size(nsamples), MPI_CHAR, | ||||
| 		0, MPI_COMM_WORLD); | ||||
| 
 | ||||
| 	/* Finish the offsets by computing the deltas on rank 0 */ | ||||
| 	if(rank == 0) | ||||
| 	{ | ||||
| 		for(i=0; i<table->nprocs; i++) | ||||
| 		{ | ||||
| 	if (rank == 0) { | ||||
| 		for (i = 0; i < table->nprocs; i++) { | ||||
| 			offset_compute_delta(offset, table->offset[i], | ||||
| 					nsamples, verbose); | ||||
| 				nsamples, verbose); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* Cleanup for non-zero ranks */ | ||||
| 	if(rank != 0) | ||||
| 	if (rank != 0) | ||||
| 		free(offset); | ||||
| 
 | ||||
| 	return table; | ||||
| @ -386,13 +363,12 @@ static void | ||||
| print_drift_header(FILE *out, struct offset_table *table) | ||||
| { | ||||
| 	int i; | ||||
| 	//char buf[64];
 | ||||
| 	// char buf[64];
 | ||||
| 
 | ||||
| 	fprintf(out, "%-20s", "wallclock"); | ||||
| 
 | ||||
| 	for(i=0; i<table->nprocs; i++) | ||||
| 	{ | ||||
| 		//sprintf(buf, "rank%d", i);
 | ||||
| 	for (i = 0; i < table->nprocs; i++) { | ||||
| 		// sprintf(buf, "rank%d", i);
 | ||||
| 		fprintf(out, " %-20s", table->offset[i]->hostname); | ||||
| 	} | ||||
| 
 | ||||
| @ -406,7 +382,7 @@ print_drift_row(FILE *out, struct offset_table *table) | ||||
| 
 | ||||
| 	fprintf(out, "%-20f", table->offset[0]->wall_t1); | ||||
| 
 | ||||
| 	for(i=0; i<table->nprocs; i++) | ||||
| 	for (i = 0; i < table->nprocs; i++) | ||||
| 		fprintf(out, " %-20ld", table->offset[i]->offset); | ||||
| 
 | ||||
| 	fprintf(out, "\n"); | ||||
| @ -419,14 +395,13 @@ print_table_detailed(FILE *out, struct offset_table *table) | ||||
| 	struct offset *offset; | ||||
| 
 | ||||
| 	fprintf(out, "%-10s %-20s %-20s %-20s %-20s\n", | ||||
| 			"rank", "hostname", "offset_median", "offset_mean", "offset_std"); | ||||
| 		"rank", "hostname", "offset_median", "offset_mean", "offset_std"); | ||||
| 
 | ||||
| 	for(i=0; i<table->nprocs; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < table->nprocs; i++) { | ||||
| 		offset = table->offset[i]; | ||||
| 		fprintf(out, "%-10d %-20s %-20ld %-20f %-20f\n", | ||||
| 				i, offset->hostname, offset->offset, | ||||
| 				offset->delta_mean, offset->delta_std); | ||||
| 			i, offset->hostname, offset->offset, | ||||
| 			offset->delta_mean, offset->delta_std); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -440,39 +415,31 @@ do_work(struct options *options, int rank) | ||||
| 
 | ||||
| 	drift_mode = options->ndrift_samples > 1 ? 1 : 0; | ||||
| 
 | ||||
| 	if(rank == 0) | ||||
| 	{ | ||||
| 		if(mkpath(options->outpath, 0755) != 0) | ||||
| 		{ | ||||
| 	if (rank == 0) { | ||||
| 		if (mkpath(options->outpath, 0755) != 0) { | ||||
| 			fprintf(stderr, "mkpath(%s) failed: %s\n", | ||||
| 					options->outpath, strerror(errno)); | ||||
| 				options->outpath, strerror(errno)); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 
 | ||||
| 		out = fopen(options->outpath, "w"); | ||||
| 		if(out == NULL) | ||||
| 		{ | ||||
| 		if (out == NULL) { | ||||
| 			fprintf(stderr, "fopen(%s) failed: %s\n", | ||||
| 					options->outpath, strerror(errno)); | ||||
| 				options->outpath, strerror(errno)); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for(i=0; i<options->ndrift_samples; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < options->ndrift_samples; i++) { | ||||
| 		table = build_offset_table(options->nsamples, rank, options->verbose); | ||||
| 
 | ||||
| 		if(rank == 0) | ||||
| 		{ | ||||
| 			if(drift_mode) | ||||
| 			{ | ||||
| 				if(i == 0) | ||||
| 		if (rank == 0) { | ||||
| 			if (drift_mode) { | ||||
| 				if (i == 0) | ||||
| 					print_drift_header(out, table); | ||||
| 
 | ||||
| 				print_drift_row(out, table); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 			} else { | ||||
| 				print_table_detailed(out, table); | ||||
| 			} | ||||
| 
 | ||||
| @ -481,11 +448,11 @@ do_work(struct options *options, int rank) | ||||
| 			free(table); | ||||
| 		} | ||||
| 
 | ||||
| 		if(drift_mode) | ||||
| 		if (drift_mode) | ||||
| 			sleep(options->drift_wait); | ||||
| 	} | ||||
| 
 | ||||
| 	if(rank == 0) | ||||
| 	if (rank == 0) | ||||
| 		fclose(out); | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										161
									
								
								parson.h
									
									
									
									
									
								
							
							
						
						
									
										161
									
								
								parson.h
									
									
									
									
									
								
							| @ -27,36 +27,35 @@ | ||||
| #define parson_parson_h | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include <stddef.h>   /* size_t */ | ||||
| #include <stddef.h> /* size_t */ | ||||
| 
 | ||||
| /* Types and enums */ | ||||
| typedef struct json_object_t JSON_Object; | ||||
| typedef struct json_array_t  JSON_Array; | ||||
| typedef struct json_value_t  JSON_Value; | ||||
| typedef struct json_array_t JSON_Array; | ||||
| typedef struct json_value_t JSON_Value; | ||||
| 
 | ||||
| enum json_value_type { | ||||
|     JSONError   = -1, | ||||
|     JSONNull    = 1, | ||||
|     JSONString  = 2, | ||||
|     JSONNumber  = 3, | ||||
|     JSONObject  = 4, | ||||
|     JSONArray   = 5, | ||||
|     JSONBoolean = 6 | ||||
| 	JSONError = -1, | ||||
| 	JSONNull = 1, | ||||
| 	JSONString = 2, | ||||
| 	JSONNumber = 3, | ||||
| 	JSONObject = 4, | ||||
| 	JSONArray = 5, | ||||
| 	JSONBoolean = 6 | ||||
| }; | ||||
| typedef int JSON_Value_Type; | ||||
| 
 | ||||
| enum json_result_t { | ||||
|     JSONSuccess = 0, | ||||
|     JSONFailure = -1 | ||||
| 	JSONSuccess = 0, | ||||
| 	JSONFailure = -1 | ||||
| }; | ||||
| typedef int JSON_Status; | ||||
| 
 | ||||
| typedef void * (*JSON_Malloc_Function)(size_t); | ||||
| typedef void   (*JSON_Free_Function)(void *); | ||||
| typedef void *(*JSON_Malloc_Function)(size_t); | ||||
| typedef void (*JSON_Free_Function)(void *); | ||||
| 
 | ||||
| /* Call only once, before calling any other function from parson API. If not called, malloc and free
 | ||||
|    from stdlib will be used for all allocations */ | ||||
| @ -67,35 +66,35 @@ void json_set_allocation_functions(JSON_Malloc_Function malloc_fun, JSON_Free_Fu | ||||
| void json_set_escape_slashes(int escape_slashes); | ||||
| 
 | ||||
| /* Parses first JSON value in a file, returns NULL in case of error */ | ||||
| JSON_Value * json_parse_file(const char *filename); | ||||
| JSON_Value *json_parse_file(const char *filename); | ||||
| 
 | ||||
| /* Parses first JSON value in a file and ignores comments (/ * * / and //),
 | ||||
|    returns NULL in case of error */ | ||||
| JSON_Value * json_parse_file_with_comments(const char *filename); | ||||
| JSON_Value *json_parse_file_with_comments(const char *filename); | ||||
| 
 | ||||
| /*  Parses first JSON value in a string, returns NULL in case of error */ | ||||
| JSON_Value * json_parse_string(const char *string); | ||||
| JSON_Value *json_parse_string(const char *string); | ||||
| 
 | ||||
| /*  Parses first JSON value in a string and ignores comments (/ * * / and //),
 | ||||
|     returns NULL in case of error */ | ||||
| JSON_Value * json_parse_string_with_comments(const char *string); | ||||
| JSON_Value *json_parse_string_with_comments(const char *string); | ||||
| 
 | ||||
| /* Serialization */ | ||||
| size_t      json_serialization_size(const JSON_Value *value); /* returns 0 on fail */ | ||||
| size_t json_serialization_size(const JSON_Value *value); /* returns 0 on fail */ | ||||
| JSON_Status json_serialize_to_buffer(const JSON_Value *value, char *buf, size_t buf_size_in_bytes); | ||||
| JSON_Status json_serialize_to_file(const JSON_Value *value, const char *filename); | ||||
| char *      json_serialize_to_string(const JSON_Value *value); | ||||
| char *json_serialize_to_string(const JSON_Value *value); | ||||
| 
 | ||||
| /* Pretty serialization */ | ||||
| size_t      json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */ | ||||
| size_t json_serialization_size_pretty(const JSON_Value *value); /* returns 0 on fail */ | ||||
| JSON_Status json_serialize_to_buffer_pretty(const JSON_Value *value, char *buf, size_t buf_size_in_bytes); | ||||
| JSON_Status json_serialize_to_file_pretty(const JSON_Value *value, const char *filename); | ||||
| char *      json_serialize_to_string_pretty(const JSON_Value *value); | ||||
| char *json_serialize_to_string_pretty(const JSON_Value *value); | ||||
| 
 | ||||
| void        json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */ | ||||
| void json_free_serialized_string(char *string); /* frees string from json_serialize_to_string and json_serialize_to_string_pretty */ | ||||
| 
 | ||||
| /* Comparing */ | ||||
| int  json_value_equals(const JSON_Value *a, const JSON_Value *b); | ||||
| int json_value_equals(const JSON_Value *a, const JSON_Value *b); | ||||
| 
 | ||||
| /* Validation
 | ||||
|    This is *NOT* JSON Schema. It validates json by checking if object have identically | ||||
| @ -112,45 +111,45 @@ JSON_Status json_validate(const JSON_Value *schema, const JSON_Value *value); | ||||
| /*
 | ||||
|  * JSON Object | ||||
|  */ | ||||
| JSON_Value  * json_object_get_value  (const JSON_Object *object, const char *name); | ||||
| const char  * json_object_get_string (const JSON_Object *object, const char *name); | ||||
| size_t        json_object_get_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */ | ||||
| JSON_Object * json_object_get_object (const JSON_Object *object, const char *name); | ||||
| JSON_Array  * json_object_get_array  (const JSON_Object *object, const char *name); | ||||
| double        json_object_get_number (const JSON_Object *object, const char *name); /* returns 0 on fail */ | ||||
| int           json_object_get_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */ | ||||
| JSON_Value *json_object_get_value(const JSON_Object *object, const char *name); | ||||
| const char *json_object_get_string(const JSON_Object *object, const char *name); | ||||
| size_t json_object_get_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */ | ||||
| JSON_Object *json_object_get_object(const JSON_Object *object, const char *name); | ||||
| JSON_Array *json_object_get_array(const JSON_Object *object, const char *name); | ||||
| double json_object_get_number(const JSON_Object *object, const char *name); /* returns 0 on fail */ | ||||
| int json_object_get_boolean(const JSON_Object *object, const char *name);   /* returns -1 on fail */ | ||||
| 
 | ||||
| /* dotget functions enable addressing values with dot notation in nested objects,
 | ||||
|  just like in structs or c++/java/c# objects (e.g. objectA.objectB.value). | ||||
|  Because valid names in JSON can contain dots, some values may be inaccessible | ||||
|  this way. */ | ||||
| JSON_Value  * json_object_dotget_value  (const JSON_Object *object, const char *name); | ||||
| const char  * json_object_dotget_string (const JSON_Object *object, const char *name); | ||||
| size_t        json_object_dotget_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */ | ||||
| JSON_Object * json_object_dotget_object (const JSON_Object *object, const char *name); | ||||
| JSON_Array  * json_object_dotget_array  (const JSON_Object *object, const char *name); | ||||
| double        json_object_dotget_number (const JSON_Object *object, const char *name); /* returns 0 on fail */ | ||||
| int           json_object_dotget_boolean(const JSON_Object *object, const char *name); /* returns -1 on fail */ | ||||
| JSON_Value *json_object_dotget_value(const JSON_Object *object, const char *name); | ||||
| const char *json_object_dotget_string(const JSON_Object *object, const char *name); | ||||
| size_t json_object_dotget_string_len(const JSON_Object *object, const char *name); /* doesn't account for last null character */ | ||||
| JSON_Object *json_object_dotget_object(const JSON_Object *object, const char *name); | ||||
| JSON_Array *json_object_dotget_array(const JSON_Object *object, const char *name); | ||||
| double json_object_dotget_number(const JSON_Object *object, const char *name); /* returns 0 on fail */ | ||||
| int json_object_dotget_boolean(const JSON_Object *object, const char *name);   /* returns -1 on fail */ | ||||
| 
 | ||||
| /* Functions to get available names */ | ||||
| size_t        json_object_get_count   (const JSON_Object *object); | ||||
| const char  * json_object_get_name    (const JSON_Object *object, size_t index); | ||||
| JSON_Value  * json_object_get_value_at(const JSON_Object *object, size_t index); | ||||
| JSON_Value  * json_object_get_wrapping_value(const JSON_Object *object); | ||||
| size_t json_object_get_count(const JSON_Object *object); | ||||
| const char *json_object_get_name(const JSON_Object *object, size_t index); | ||||
| JSON_Value *json_object_get_value_at(const JSON_Object *object, size_t index); | ||||
| JSON_Value *json_object_get_wrapping_value(const JSON_Object *object); | ||||
| 
 | ||||
| /* Functions to check if object has a value with a specific name. Returned value is 1 if object has
 | ||||
|  * a value and 0 if it doesn't. dothas functions behave exactly like dotget functions. */ | ||||
| int json_object_has_value        (const JSON_Object *object, const char *name); | ||||
| int json_object_has_value(const JSON_Object *object, const char *name); | ||||
| int json_object_has_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type); | ||||
| 
 | ||||
| int json_object_dothas_value        (const JSON_Object *object, const char *name); | ||||
| int json_object_dothas_value(const JSON_Object *object, const char *name); | ||||
| int json_object_dothas_value_of_type(const JSON_Object *object, const char *name, JSON_Value_Type type); | ||||
| 
 | ||||
| /* Creates new name-value pair or frees and replaces old value with a new one.
 | ||||
|  * json_object_set_value does not copy passed value so it shouldn't be freed afterwards. */ | ||||
| JSON_Status json_object_set_value(JSON_Object *object, const char *name, JSON_Value *value); | ||||
| JSON_Status json_object_set_string(JSON_Object *object, const char *name, const char *string); | ||||
| JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len);  /* length shouldn't include last null character */ | ||||
| JSON_Status json_object_set_string_with_len(JSON_Object *object, const char *name, const char *string, size_t len); /* length shouldn't include last null character */ | ||||
| JSON_Status json_object_set_number(JSON_Object *object, const char *name, double number); | ||||
| JSON_Status json_object_set_boolean(JSON_Object *object, const char *name, int boolean); | ||||
| JSON_Status json_object_set_null(JSON_Object *object, const char *name); | ||||
| @ -176,15 +175,15 @@ JSON_Status json_object_clear(JSON_Object *object); | ||||
| /*
 | ||||
|  *JSON Array | ||||
|  */ | ||||
| JSON_Value  * json_array_get_value  (const JSON_Array *array, size_t index); | ||||
| const char  * json_array_get_string (const JSON_Array *array, size_t index); | ||||
| size_t        json_array_get_string_len(const JSON_Array *array, size_t index); /* doesn't account for last null character */ | ||||
| JSON_Object * json_array_get_object (const JSON_Array *array, size_t index); | ||||
| JSON_Array  * json_array_get_array  (const JSON_Array *array, size_t index); | ||||
| double        json_array_get_number (const JSON_Array *array, size_t index); /* returns 0 on fail */ | ||||
| int           json_array_get_boolean(const JSON_Array *array, size_t index); /* returns -1 on fail */ | ||||
| size_t        json_array_get_count  (const JSON_Array *array); | ||||
| JSON_Value  * json_array_get_wrapping_value(const JSON_Array *array); | ||||
| JSON_Value *json_array_get_value(const JSON_Array *array, size_t index); | ||||
| const char *json_array_get_string(const JSON_Array *array, size_t index); | ||||
| size_t json_array_get_string_len(const JSON_Array *array, size_t index); /* doesn't account for last null character */ | ||||
| JSON_Object *json_array_get_object(const JSON_Array *array, size_t index); | ||||
| JSON_Array *json_array_get_array(const JSON_Array *array, size_t index); | ||||
| double json_array_get_number(const JSON_Array *array, size_t index); /* returns 0 on fail */ | ||||
| int json_array_get_boolean(const JSON_Array *array, size_t index);   /* returns -1 on fail */ | ||||
| size_t json_array_get_count(const JSON_Array *array); | ||||
| JSON_Value *json_array_get_wrapping_value(const JSON_Array *array); | ||||
| 
 | ||||
| /* Frees and removes value at given index, does nothing and returns JSONFailure if index doesn't exist.
 | ||||
|  * Order of values in array may change during execution.  */ | ||||
| @ -194,7 +193,7 @@ JSON_Status json_array_remove(JSON_Array *array, size_t i); | ||||
|  * Does nothing and returns JSONFailure if index doesn't exist. | ||||
|  * json_array_replace_value does not copy passed value so it shouldn't be freed afterwards. */ | ||||
| JSON_Status json_array_replace_value(JSON_Array *array, size_t i, JSON_Value *value); | ||||
| JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char* string); | ||||
| JSON_Status json_array_replace_string(JSON_Array *array, size_t i, const char *string); | ||||
| JSON_Status json_array_replace_string_with_len(JSON_Array *array, size_t i, const char *string, size_t len); /* length shouldn't include last null character */ | ||||
| JSON_Status json_array_replace_number(JSON_Array *array, size_t i, double number); | ||||
| JSON_Status json_array_replace_boolean(JSON_Array *array, size_t i, int boolean); | ||||
| @ -215,33 +214,33 @@ JSON_Status json_array_append_null(JSON_Array *array); | ||||
| /*
 | ||||
|  *JSON Value | ||||
|  */ | ||||
| JSON_Value * json_value_init_object (void); | ||||
| JSON_Value * json_value_init_array  (void); | ||||
| JSON_Value * json_value_init_string (const char *string); /* copies passed string */ | ||||
| JSON_Value * json_value_init_string_with_len(const char *string, size_t length); /* copies passed string, length shouldn't include last null character */ | ||||
| JSON_Value * json_value_init_number (double number); | ||||
| JSON_Value * json_value_init_boolean(int boolean); | ||||
| JSON_Value * json_value_init_null   (void); | ||||
| JSON_Value * json_value_deep_copy   (const JSON_Value *value); | ||||
| void         json_value_free        (JSON_Value *value); | ||||
| JSON_Value *json_value_init_object(void); | ||||
| JSON_Value *json_value_init_array(void); | ||||
| JSON_Value *json_value_init_string(const char *string);				/* copies passed string */ | ||||
| JSON_Value *json_value_init_string_with_len(const char *string, size_t length); /* copies passed string, length shouldn't include last null character */ | ||||
| JSON_Value *json_value_init_number(double number); | ||||
| JSON_Value *json_value_init_boolean(int boolean); | ||||
| JSON_Value *json_value_init_null(void); | ||||
| JSON_Value *json_value_deep_copy(const JSON_Value *value); | ||||
| void json_value_free(JSON_Value *value); | ||||
| 
 | ||||
| JSON_Value_Type json_value_get_type   (const JSON_Value *value); | ||||
| JSON_Object *   json_value_get_object (const JSON_Value *value); | ||||
| JSON_Array  *   json_value_get_array  (const JSON_Value *value); | ||||
| const char  *   json_value_get_string (const JSON_Value *value); | ||||
| size_t          json_value_get_string_len(const JSON_Value *value); /* doesn't account for last null character */ | ||||
| double          json_value_get_number (const JSON_Value *value); | ||||
| int             json_value_get_boolean(const JSON_Value *value); | ||||
| JSON_Value  *   json_value_get_parent (const JSON_Value *value); | ||||
| JSON_Value_Type json_value_get_type(const JSON_Value *value); | ||||
| JSON_Object *json_value_get_object(const JSON_Value *value); | ||||
| JSON_Array *json_value_get_array(const JSON_Value *value); | ||||
| const char *json_value_get_string(const JSON_Value *value); | ||||
| size_t json_value_get_string_len(const JSON_Value *value); /* doesn't account for last null character */ | ||||
| double json_value_get_number(const JSON_Value *value); | ||||
| int json_value_get_boolean(const JSON_Value *value); | ||||
| JSON_Value *json_value_get_parent(const JSON_Value *value); | ||||
| 
 | ||||
| /* Same as above, but shorter */ | ||||
| JSON_Value_Type json_type   (const JSON_Value *value); | ||||
| JSON_Object *   json_object (const JSON_Value *value); | ||||
| JSON_Array  *   json_array  (const JSON_Value *value); | ||||
| const char  *   json_string (const JSON_Value *value); | ||||
| size_t          json_string_len(const JSON_Value *value); /* doesn't account for last null character */ | ||||
| double          json_number (const JSON_Value *value); | ||||
| int             json_boolean(const JSON_Value *value); | ||||
| JSON_Value_Type json_type(const JSON_Value *value); | ||||
| JSON_Object *json_object(const JSON_Value *value); | ||||
| JSON_Array *json_array(const JSON_Value *value); | ||||
| const char *json_string(const JSON_Value *value); | ||||
| size_t json_string_len(const JSON_Value *value); /* doesn't account for last null character */ | ||||
| double json_number(const JSON_Value *value); | ||||
| int json_boolean(const JSON_Value *value); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
|  | ||||
							
								
								
									
										441
									
								
								pcf.c
									
									
									
									
									
								
							
							
						
						
									
										441
									
								
								pcf.c
									
									
									
									
									
								
							| @ -2,12 +2,12 @@ | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| #include "pcf.h" | ||||
| #include "prv.h" | ||||
| #include "emu.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <errno.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| const char *pcf_def_header = | ||||
| 	"DEFAULT_OPTIONS\n" | ||||
| @ -25,44 +25,43 @@ const char *pcf_def_header = | ||||
| 	"\n" | ||||
| 	"THREAD_FUNC         State As Is\n"; | ||||
| 
 | ||||
| #define RGB(r, g, b) (r<<16 | g<<8 | b) | ||||
| #define ARRAY_LEN(x)  (sizeof(x) / sizeof((x)[0])) | ||||
| #define RGB(r, g, b) (r << 16 | g << 8 | b) | ||||
| #define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0])) | ||||
| 
 | ||||
| /* Define colors for the trace */ | ||||
| #define DEEPBLUE  RGB(  0,   0, 255) | ||||
| #define DEEPBLUE RGB(0, 0, 255) | ||||
| #define LIGHTGREY RGB(217, 217, 217) | ||||
| #define RED       RGB(230,  25,  75) | ||||
| #define GREEN     RGB(60,  180,  75) | ||||
| #define YELLOW    RGB(255, 225,  25) | ||||
| #define ORANGE    RGB(245, 130,  48) | ||||
| #define PURPLE    RGB(145,  30, 180) | ||||
| #define CYAN      RGB( 70, 240, 240) | ||||
| #define MAGENTA   RGB(240, 50,  230) | ||||
| #define LIME      RGB(210, 245,  60) | ||||
| #define PINK      RGB(250, 190, 212) | ||||
| #define TEAL      RGB(  0, 128, 128) | ||||
| #define LAVENDER  RGB(220, 190, 255) | ||||
| #define BROWN     RGB(170, 110,  40) | ||||
| #define BEIGE     RGB(255, 250, 200) | ||||
| #define MAROON    RGB(128,   0,   0) | ||||
| #define MINT      RGB(170, 255, 195) | ||||
| #define OLIVE     RGB(128, 128,   0) | ||||
| #define APRICOT   RGB(255, 215, 180) | ||||
| #define NAVY      RGB(  0,   0, 128) | ||||
| #define BLUE      RGB(  0, 130, 200) | ||||
| #define GREY      RGB(128, 128, 128) | ||||
| #define BLACK     RGB(  0,   0,   0) | ||||
| #define RED RGB(230, 25, 75) | ||||
| #define GREEN RGB(60, 180, 75) | ||||
| #define YELLOW RGB(255, 225, 25) | ||||
| #define ORANGE RGB(245, 130, 48) | ||||
| #define PURPLE RGB(145, 30, 180) | ||||
| #define CYAN RGB(70, 240, 240) | ||||
| #define MAGENTA RGB(240, 50, 230) | ||||
| #define LIME RGB(210, 245, 60) | ||||
| #define PINK RGB(250, 190, 212) | ||||
| #define TEAL RGB(0, 128, 128) | ||||
| #define LAVENDER RGB(220, 190, 255) | ||||
| #define BROWN RGB(170, 110, 40) | ||||
| #define BEIGE RGB(255, 250, 200) | ||||
| #define MAROON RGB(128, 0, 0) | ||||
| #define MINT RGB(170, 255, 195) | ||||
| #define OLIVE RGB(128, 128, 0) | ||||
| #define APRICOT RGB(255, 215, 180) | ||||
| #define NAVY RGB(0, 0, 128) | ||||
| #define BLUE RGB(0, 130, 200) | ||||
| #define GREY RGB(128, 128, 128) | ||||
| #define BLACK RGB(0, 0, 0) | ||||
| 
 | ||||
| const uint32_t pcf_def_palette[] = { | ||||
| 	BLACK,		/* (never shown anyways) */ | ||||
| 	BLUE,		/* runtime */ | ||||
| 	LIGHTGREY,	/* busy wait */ | ||||
| 	RED,		/* task */ | ||||
| 	BLACK,	   /* (never shown anyways) */ | ||||
| 	BLUE,	   /* runtime */ | ||||
| 	LIGHTGREY, /* busy wait */ | ||||
| 	RED,	   /* task */ | ||||
| 	GREEN, | ||||
| 	YELLOW, ORANGE, PURPLE, CYAN, MAGENTA, LIME, PINK, | ||||
| 	TEAL, GREY, LAVENDER, BROWN, BEIGE, MAROON, MINT, | ||||
| 	OLIVE, APRICOT, NAVY, DEEPBLUE | ||||
| }; | ||||
| 	OLIVE, APRICOT, NAVY, DEEPBLUE}; | ||||
| 
 | ||||
| const uint32_t *pcf_palette = pcf_def_palette; | ||||
| const int pcf_palette_len = ARRAY_LEN(pcf_def_palette); | ||||
| @ -70,197 +69,201 @@ 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 }, | ||||
| 	{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 }, | ||||
| 	{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 }, | ||||
| 	{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" }, | ||||
| 	{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 }, | ||||
| 	{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 tampi_mode_values[] = { | ||||
| 	{ ST_NULL,              "NULL" }, | ||||
| 	{ ST_TOO_MANY_TH,       "TAMPI: Unknown, multiple threads running" }, | ||||
| 	{ ST_TAMPI_SEND,        "TAMPI: Send" }, | ||||
| 	{ ST_TAMPI_RECV,        "TAMPI: Recv" }, | ||||
| 	{ ST_TAMPI_ISEND,       "TAMPI: Isend" }, | ||||
| 	{ ST_TAMPI_IRECV,       "TAMPI: Irecv" }, | ||||
| 	{ ST_TAMPI_WAIT,        "TAMPI: Wait" }, | ||||
| 	{ ST_TAMPI_WAITALL,     "TAMPI: Waitall" }, | ||||
| 	{ -1, NULL }, | ||||
| 	{ST_NULL, "NULL"}, | ||||
| 	{ST_TOO_MANY_TH, "TAMPI: Unknown, multiple threads running"}, | ||||
| 	{ST_TAMPI_SEND, "TAMPI: Send"}, | ||||
| 	{ST_TAMPI_RECV, "TAMPI: Recv"}, | ||||
| 	{ST_TAMPI_ISEND, "TAMPI: Isend"}, | ||||
| 	{ST_TAMPI_IRECV, "TAMPI: Irecv"}, | ||||
| 	{ST_TAMPI_WAIT, "TAMPI: Wait"}, | ||||
| 	{ST_TAMPI_WAITALL, "TAMPI: Waitall"}, | ||||
| 	{-1, NULL}, | ||||
| }; | ||||
| 
 | ||||
| struct pcf_value_label openmp_mode_values[] = { | ||||
| 	{ ST_NULL,              "NULL" }, | ||||
| 	{ ST_TOO_MANY_TH,       "OpenMP: Unknown, multiple threads running" }, | ||||
| 	{ ST_OPENMP_TASK,       "OpenMP: Task" }, | ||||
| 	{ ST_OPENMP_PARALLEL,   "OpenMP: Parallel" }, | ||||
| 	{ -1, NULL }, | ||||
| 	{ST_NULL, "NULL"}, | ||||
| 	{ST_TOO_MANY_TH, "OpenMP: Unknown, multiple threads running"}, | ||||
| 	{ST_OPENMP_TASK, "OpenMP: Task"}, | ||||
| 	{ST_OPENMP_PARALLEL, "OpenMP: Parallel"}, | ||||
| 	{-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 }, | ||||
| 	{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 }, | ||||
| 	{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 }, | ||||
| 	{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 }, | ||||
| 	{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_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_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_TAMPI_MODE]       = &tampi_mode_values, | ||||
| 	[CHAN_OPENMP_MODE]      = &openmp_mode_values, | ||||
| 	[CHAN_NODES_SUBSYSTEM]  = &nodes_mode_values, | ||||
| 	[CHAN_TAMPI_MODE] = &tampi_mode_values, | ||||
| 	[CHAN_OPENMP_MODE] = &openmp_mode_values, | ||||
| 	[CHAN_NODES_SUBSYSTEM] = &nodes_mode_values, | ||||
| 
 | ||||
| 	[CHAN_NANOS6_TASKID]    = &default_values, | ||||
| 	[CHAN_NANOS6_TYPE]  	= &default_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_NANOS6_RANK] = &default_values, | ||||
| 	[CHAN_NANOS6_THREAD] = &nanos6_thread_type, | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = &kernel_cs_values, | ||||
| 	[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_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_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_TAMPI_MODE]       = "TAMPI mode", | ||||
| 	[CHAN_OPENMP_MODE]      = "OpenMP mode", | ||||
| 	[CHAN_NODES_SUBSYSTEM]  = "NODES subsystem", | ||||
| 	[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_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_NANOS6_RANK] = "Nanos6 task MPI rank", | ||||
| 	[CHAN_NANOS6_THREAD] = "Nanos6 thread type", | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = "Context switches", | ||||
| 	[CHAN_KERNEL_CS] = "Context switches", | ||||
| }; | ||||
| 
 | ||||
| enum pcf_suffix { NONE = 0, CUR_TH, RUN_TH, ACT_TH, SUFFIX_MAX }; | ||||
| enum pcf_suffix { NONE = 0, | ||||
| 	CUR_TH, | ||||
| 	RUN_TH, | ||||
| 	ACT_TH, | ||||
| 	SUFFIX_MAX }; | ||||
| 
 | ||||
| char *pcf_suffix_name[SUFFIX_MAX] = { | ||||
| 	[NONE] = "", | ||||
| @ -270,32 +273,32 @@ char *pcf_suffix_name[SUFFIX_MAX] = { | ||||
| }; | ||||
| 
 | ||||
| int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = { | ||||
| 	                        /*  Thread  CPU  */ | ||||
| 	[CHAN_OVNI_PID]         = { CUR_TH, CUR_TH }, | ||||
| 	[CHAN_OVNI_TID]         = { CUR_TH, CUR_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 }, | ||||
| 	/*  Thread  CPU  */ | ||||
| 	[CHAN_OVNI_PID] = {CUR_TH, CUR_TH}, | ||||
| 	[CHAN_OVNI_TID] = {CUR_TH, CUR_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_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_TAMPI_MODE]       = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_OPENMP_MODE]      = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_NODES_SUBSYSTEM]  = { RUN_TH, RUN_TH }, | ||||
| 	[CHAN_TAMPI_MODE] = {RUN_TH, RUN_TH}, | ||||
| 	[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_NANOS6_THREAD]   	= { ACT_TH, NONE }, | ||||
| 	[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] = {ACT_TH, NONE}, | ||||
| 
 | ||||
| 	[CHAN_KERNEL_CS]        = { RUN_TH, ACT_TH }, | ||||
| 	[CHAN_KERNEL_CS] = {RUN_TH, ACT_TH}, | ||||
| }; | ||||
| 
 | ||||
| /* ----------------------------------------------- */ | ||||
| @ -303,9 +306,9 @@ int pcf_chan_suffix[CHAN_MAX][CHAN_MAXTYPE] = { | ||||
| static void | ||||
| decompose_rgb(uint32_t col, uint8_t *r, uint8_t *g, uint8_t *b) | ||||
| { | ||||
| 	*r = (col>>16) & 0xff; | ||||
| 	*g = (col>>8) & 0xff; | ||||
| 	*b = (col>>0) & 0xff; | ||||
| 	*r = (col >> 16) & 0xff; | ||||
| 	*g = (col >> 8) & 0xff; | ||||
| 	*b = (col >> 0) & 0xff; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -323,8 +326,7 @@ write_colors(FILE *f, const uint32_t *palette, int n) | ||||
| 	fprintf(f, "\n\n"); | ||||
| 	fprintf(f, "STATES_COLOR\n"); | ||||
| 
 | ||||
| 	for(i=0; i<n; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < n; i++) { | ||||
| 		decompose_rgb(palette[i], &r, &g, &b); | ||||
| 		fprintf(f, "%-3d {%3d, %3d, %3d}\n", i, r, g, b); | ||||
| 	} | ||||
| @ -338,7 +340,7 @@ write_type(FILE *f, struct pcf_type *type) | ||||
| 	fprintf(f, "0 %-10d %s\n", type->id, type->label); | ||||
| 	fprintf(f, "VALUES\n"); | ||||
| 
 | ||||
| 	for(struct pcf_value *v = type->values; v != NULL; v = v->hh.next) | ||||
| 	for (struct pcf_value *v = type->values; v != NULL; v = v->hh.next) | ||||
| 		fprintf(f, "%-4d %s\n", v->value, v->label); | ||||
| } | ||||
| 
 | ||||
| @ -347,19 +349,19 @@ write_types(struct pcf_file *pcf) | ||||
| { | ||||
| 	struct pcf_type *t; | ||||
| 
 | ||||
| 	for(t = pcf->types; t != NULL; t = t->hh.next) | ||||
| 	for (t = pcf->types; t != NULL; t = t->hh.next) | ||||
| 		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]; | ||||
| 	struct pcf_value_label(*q)[] = pcf_chan_value_labels[c]; | ||||
| 
 | ||||
| 	if(q == NULL) | ||||
| 	if (q == NULL) | ||||
| 		return; | ||||
| 
 | ||||
| 	for(struct pcf_value_label *p = *q; p->label != NULL; p++) | ||||
| 	for (struct pcf_value_label *p = *q; p->label != NULL; p++) | ||||
| 		pcf_add_value(t, p->value, p->label); | ||||
| } | ||||
| 
 | ||||
| @ -370,7 +372,7 @@ create_type(struct pcf_file *pcf, enum chan c) | ||||
| 	enum chan_type ct = pcf->chantype; | ||||
| 	int prv_type = chan_to_prvtype[c]; | ||||
| 
 | ||||
| 	if(prv_type == -1) | ||||
| 	if (prv_type == -1) | ||||
| 		return; | ||||
| 
 | ||||
| 	/* Compute the label by joining the two parts */ | ||||
| @ -379,9 +381,9 @@ create_type(struct pcf_file *pcf, enum chan c) | ||||
| 	char *suffix = pcf_suffix_name[isuffix]; | ||||
| 
 | ||||
| 	int ret = snprintf(label, MAX_PCF_LABEL, "%s %s", | ||||
| 			prefix, suffix); | ||||
| 		prefix, suffix); | ||||
| 
 | ||||
| 	if(ret >= MAX_PCF_LABEL) | ||||
| 	if (ret >= MAX_PCF_LABEL) | ||||
| 		die("computed type label too long\n"); | ||||
| 
 | ||||
| 	struct pcf_type *t = pcf_add_type(pcf, prv_type, label); | ||||
| @ -398,14 +400,13 @@ pcf_open(struct pcf_file *pcf, char *path, int chantype) | ||||
| 	pcf->f = fopen(path, "w"); | ||||
| 	pcf->chantype = chantype; | ||||
| 
 | ||||
| 	if(pcf->f == NULL) | ||||
| 	{ | ||||
| 	if (pcf->f == NULL) { | ||||
| 		die("cannot open PCF file '%s': %s\n", | ||||
| 				path, strerror(errno)); | ||||
| 			path, strerror(errno)); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Create default types and values */ | ||||
| 	for(enum chan c = 0; c < CHAN_MAX; c++) | ||||
| 	for (enum chan c = 0; c < CHAN_MAX; c++) | ||||
| 		create_type(pcf, c); | ||||
| } | ||||
| 
 | ||||
| @ -431,11 +432,11 @@ pcf_add_type(struct pcf_file *pcf, int type_id, const char *label) | ||||
| 
 | ||||
| 	pcftype = pcf_find_type(pcf, type_id); | ||||
| 
 | ||||
| 	if(pcftype != NULL) | ||||
| 	if (pcftype != NULL) | ||||
| 		die("PCF type %d already defined\n", type_id); | ||||
| 
 | ||||
| 	pcftype = calloc(1, sizeof(struct pcf_type)); | ||||
| 	if(pcftype == NULL) | ||||
| 	if (pcftype == NULL) | ||||
| 		die("calloc failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	pcftype->id = type_id; | ||||
| @ -443,7 +444,7 @@ pcf_add_type(struct pcf_file *pcf, int type_id, const char *label) | ||||
| 	pcftype->nvalues = 0; | ||||
| 
 | ||||
| 	int len = snprintf(pcftype->label, MAX_PCF_LABEL, "%s", label); | ||||
| 	if(len >= MAX_PCF_LABEL) | ||||
| 	if (len >= MAX_PCF_LABEL) | ||||
| 		die("PCF type label too long\n"); | ||||
| 
 | ||||
| 	HASH_ADD_INT(pcf->types, id, pcftype); | ||||
| @ -471,17 +472,17 @@ pcf_add_value(struct pcf_type *type, int value, const char *label) | ||||
| { | ||||
| 	struct pcf_value *pcfvalue = pcf_find_value(type, value); | ||||
| 
 | ||||
| 	if(pcfvalue != NULL) | ||||
| 	if (pcfvalue != NULL) | ||||
| 		die("PCF value %d already in type %d\n", value, type->id); | ||||
| 
 | ||||
| 	pcfvalue = calloc(1, sizeof(struct pcf_value)); | ||||
| 	if(pcfvalue == NULL) | ||||
| 	if (pcfvalue == NULL) | ||||
| 		die("calloc failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	pcfvalue->value = value; | ||||
| 
 | ||||
| 	int len = snprintf(pcfvalue->label, MAX_PCF_LABEL, "%s", label); | ||||
| 	if(len >= MAX_PCF_LABEL) | ||||
| 	if (len >= MAX_PCF_LABEL) | ||||
| 		die("PCF value label too long\n"); | ||||
| 
 | ||||
| 	HASH_ADD_INT(type->values, value, pcfvalue); | ||||
|  | ||||
							
								
								
									
										6
									
								
								pcf.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								pcf.h
									
									
									
									
									
								
							| @ -4,8 +4,8 @@ | ||||
| #ifndef OVNI_PCF_H | ||||
| #define OVNI_PCF_H | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include "uthash.h" | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #define MAX_PCF_LABEL 512 | ||||
| 
 | ||||
| @ -53,10 +53,10 @@ void pcf_close(struct pcf_file *pcf); | ||||
| struct pcf_type *pcf_find_type(struct pcf_file *pcf, int type_id); | ||||
| 
 | ||||
| struct pcf_type *pcf_add_type(struct pcf_file *pcf, int type_id, | ||||
| 		const char *label); | ||||
| 	const char *label); | ||||
| 
 | ||||
| struct pcf_value *pcf_add_value(struct pcf_type *type, int value, | ||||
| 		const char *label); | ||||
| 	const char *label); | ||||
| 
 | ||||
| struct pcf_value *pcf_find_value(struct pcf_type *type, int value); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										8
									
								
								prv.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								prv.c
									
									
									
									
									
								
							| @ -3,8 +3,8 @@ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "prv.h" | ||||
| 
 | ||||
| void | ||||
| @ -41,16 +41,16 @@ prv_ev_cpu(struct ovni_emu *emu, int row, int type, int val) | ||||
| void | ||||
| prv_ev_autocpu_raw(struct ovni_emu *emu, int64_t time, int type, int val) | ||||
| { | ||||
| 	if(emu->cur_thread == NULL) | ||||
| 	if (emu->cur_thread == NULL) | ||||
| 		die("prv_ev_autocpu_raw: current thread is NULL\n"); | ||||
| 
 | ||||
| 	struct ovni_cpu *cpu = emu->cur_thread->cpu; | ||||
| 
 | ||||
| 	if(cpu == NULL) | ||||
| 	if (cpu == NULL) | ||||
| 		die("prv_ev_autocpu_raw: current thread CPU is NULL\n"); | ||||
| 
 | ||||
| 	/* FIXME: Use the global index of the CPUs */ | ||||
| 	if(cpu->i < 0) | ||||
| 	if (cpu->i < 0) | ||||
| 		die("prv_ev_autocpu_raw: CPU index is negative\n"); | ||||
| 
 | ||||
| 	/* Begin at 1 */ | ||||
|  | ||||
							
								
								
									
										4
									
								
								prv.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								prv.h
									
									
									
									
									
								
							| @ -4,9 +4,9 @@ | ||||
| #ifndef OVNI_PRV_H | ||||
| #define OVNI_PRV_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| void | ||||
| prv_ev(FILE *f, int row, int64_t time, int type, int val); | ||||
|  | ||||
							
								
								
									
										160
									
								
								sort.c
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								sort.c
									
									
									
									
									
								
							| @ -27,9 +27,9 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| #include "trace.h" | ||||
| #include "emu.h" | ||||
| 
 | ||||
| struct ring { | ||||
| 	ssize_t head; | ||||
| @ -54,7 +54,8 @@ struct sortplan { | ||||
| 	int fd; | ||||
| }; | ||||
| 
 | ||||
| enum operation_mode { SORT, CHECK }; | ||||
| enum operation_mode { SORT, | ||||
| 	CHECK }; | ||||
| 
 | ||||
| static char *tracedir = NULL; | ||||
| static enum operation_mode operation_mode = SORT; | ||||
| @ -72,13 +73,13 @@ ring_add(struct ring *r, struct ovni_ev *ev) | ||||
| 	r->ev[r->tail] = ev; | ||||
| 	r->tail++; | ||||
| 
 | ||||
| 	if(r->tail >= r->size) | ||||
| 	if (r->tail >= r->size) | ||||
| 		r->tail = 0; | ||||
| 
 | ||||
| 	if(r->head == r->tail) | ||||
| 	if (r->head == r->tail) | ||||
| 		r->head = r->tail + 1; | ||||
| 
 | ||||
| 	if(r->head >= r->size) | ||||
| 	if (r->head >= r->size) | ||||
| 		r->head = 0; | ||||
| } | ||||
| 
 | ||||
| @ -92,12 +93,10 @@ find_destination(struct ring *r, uint64_t clock) | ||||
| 	start = r->tail - 1 >= 0 ? r->tail - 1 : r->size - 1; | ||||
| 	end = r->head - 1 >= 0 ? r->head - 1 : r->size - 1; | ||||
| 
 | ||||
| 	for(i=start; i != end; i = i-1 < 0 ? r->size - 1: i-1) | ||||
| 	{ | ||||
| 		if(r->ev[i]->header.clock < clock) | ||||
| 		{ | ||||
| 	for (i = start; i != end; i = i - 1 < 0 ? r->size - 1 : i - 1) { | ||||
| 		if (r->ev[i]->header.clock < clock) { | ||||
| 			dbg("found suitable position %ld events backwards\n", | ||||
| 					nback); | ||||
| 				nback); | ||||
| 			return i; | ||||
| 		} | ||||
| 		nback++; | ||||
| @ -111,17 +110,13 @@ find_destination(struct ring *r, uint64_t clock) | ||||
| static int | ||||
| starts_unsorted_region(struct ovni_ev *ev) | ||||
| { | ||||
| 	return ev->header.model == 'O' && | ||||
| 		ev->header.category == 'U' && | ||||
| 		ev->header.value == '['; | ||||
| 	return ev->header.model == 'O' && ev->header.category == 'U' && ev->header.value == '['; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| ends_unsorted_region(struct ovni_ev *ev) | ||||
| { | ||||
| 	return ev->header.model == 'O' && | ||||
| 		ev->header.category == 'U' && | ||||
| 		ev->header.value == ']'; | ||||
| 	return ev->header.model == 'O' && ev->header.category == 'U' && ev->header.value == ']'; | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| @ -168,7 +163,7 @@ hexdump(uint8_t *buf, size_t size) | ||||
| 
 | ||||
| static void | ||||
| sort_buf(uint8_t *src, uint8_t *buf, int64_t bufsize, | ||||
| 		uint8_t *srcbad, uint8_t *srcnext) | ||||
| 	uint8_t *srcbad, uint8_t *srcnext) | ||||
| { | ||||
| 	uint8_t *p, *q; | ||||
| 	int64_t evsize, injected = 0; | ||||
| @ -179,31 +174,27 @@ sort_buf(uint8_t *src, uint8_t *buf, int64_t bufsize, | ||||
| 	p = src; | ||||
| 	q = srcbad; | ||||
| 
 | ||||
| 	while(1) | ||||
| 	{ | ||||
| 	while (1) { | ||||
| 		ep = (struct ovni_ev *) p; | ||||
| 		eq = (struct ovni_ev *) q; | ||||
| 
 | ||||
| 		if(p < srcbad && ep->header.clock < eq->header.clock) | ||||
| 		{ | ||||
| 		if (p < srcbad && ep->header.clock < eq->header.clock) { | ||||
| 			ev = ep; | ||||
| 			evsize = ovni_ev_size(ev); | ||||
| 			p += evsize; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 		} else { | ||||
| 			ev = eq; | ||||
| 			evsize = ovni_ev_size(ev); | ||||
| 			q += evsize; | ||||
| 		} | ||||
| 
 | ||||
| 		if((uint8_t *) ev == srcnext) | ||||
| 		if ((uint8_t *) ev == srcnext) | ||||
| 			break; | ||||
| 
 | ||||
| 		if((uint8_t *) ev > srcnext) | ||||
| 		if ((uint8_t *) ev > srcnext) | ||||
| 			die("exceeded srcnext while sorting\n"); | ||||
| 
 | ||||
| 		if(bufsize < evsize) | ||||
| 		if (bufsize < evsize) | ||||
| 			die("no space left in the sort buffer\n"); | ||||
| 
 | ||||
| 		memcpy(buf, ev, evsize); | ||||
| @ -218,11 +209,11 @@ sort_buf(uint8_t *src, uint8_t *buf, int64_t bufsize, | ||||
| static void | ||||
| write_stream(int fd, void *base, void *dst, const void *src, size_t size) | ||||
| { | ||||
| 	while(size > 0) { | ||||
| 	while (size > 0) { | ||||
| 		off_t offset = (off_t) ((int64_t) dst - (int64_t) base); | ||||
| 		ssize_t written = pwrite(fd, src, size, offset); | ||||
| 
 | ||||
| 		if(written < 0) | ||||
| 		if (written < 0) | ||||
| 			die("pwrite failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 		size -= written; | ||||
| @ -243,10 +234,9 @@ execute_sort_plan(struct sortplan *sp) | ||||
| 	dbg("attempt to sort: start clock %ld\n", sp->bad0->header.clock); | ||||
| 
 | ||||
| 	/* Cannot sort in one pass; just fail for now */ | ||||
| 	if((i0 = find_destination(sp->r, sp->bad0->header.clock)) < 0) | ||||
| 	{ | ||||
| 	if ((i0 = find_destination(sp->r, sp->bad0->header.clock)) < 0) { | ||||
| 		err("cannot find destination for region starting at clock %ld\n", | ||||
| 				sp->bad0->header.clock); | ||||
| 			sp->bad0->header.clock); | ||||
| 
 | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -257,15 +247,15 @@ execute_sort_plan(struct sortplan *sp) | ||||
| 	/* Allocate a working buffer */ | ||||
| 	bufsize = ((int64_t) sp->next) - ((int64_t) first); | ||||
| 
 | ||||
| 	if(bufsize <= 0) | ||||
| 	if (bufsize <= 0) | ||||
| 		die("bufsize is non-positive\n"); | ||||
| 
 | ||||
| 	buf = malloc(bufsize); | ||||
| 	if(!buf) | ||||
| 	if (!buf) | ||||
| 		die("malloc failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	sort_buf((uint8_t *) first, buf, bufsize, | ||||
| 			(uint8_t *) sp->bad0, (uint8_t *) sp->next); | ||||
| 		(uint8_t *) sp->bad0, (uint8_t *) sp->next); | ||||
| 
 | ||||
| 	/* Copy the sorted events back into the stream buffer */ | ||||
| 	memcpy(first, buf, bufsize); | ||||
| @ -282,13 +272,13 @@ stream_winsort(struct ovni_stream *stream, struct ring *r) | ||||
| { | ||||
| 	struct ovni_ev *ev; | ||||
| 	struct sortplan sp = {0}; | ||||
| 	//uint64_t lastclock = 0;
 | ||||
| 	// uint64_t lastclock = 0;
 | ||||
| 	char st = 'S'; | ||||
| 
 | ||||
| 	char *fn = stream->thread->tracefile; | ||||
| 	int fd = open(fn, O_WRONLY); | ||||
| 
 | ||||
| 	if(fd < 0) | ||||
| 	if (fd < 0) | ||||
| 		die("open %s failed: %s\n", fn, strerror(errno)); | ||||
| 
 | ||||
| 	ring_reset(r); | ||||
| @ -299,41 +289,30 @@ stream_winsort(struct ovni_stream *stream, struct ring *r) | ||||
| 	size_t empty_regions = 0; | ||||
| 	size_t updated = 0; | ||||
| 
 | ||||
| 	while(stream->active) | ||||
| 	{ | ||||
| 	while (stream->active) { | ||||
| 		ovni_load_next_event(stream); | ||||
| 		ev = stream->cur_ev; | ||||
| 
 | ||||
| 		if(st == 'S' && starts_unsorted_region(ev)) | ||||
| 		{ | ||||
| 		if (st == 'S' && starts_unsorted_region(ev)) { | ||||
| 			st = 'U'; | ||||
| 		} | ||||
| 		else if(st == 'U') | ||||
| 		{ | ||||
| 		} else if (st == 'U') { | ||||
| 			/* Ensure that we have at least one unsorted
 | ||||
| 			 * event inside the section */ | ||||
| 			if(ends_unsorted_region(ev)) | ||||
| 			{ | ||||
| 			if (ends_unsorted_region(ev)) { | ||||
| 				empty_regions++; | ||||
| 				st = 'S'; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 			} else { | ||||
| 				st = 'X'; | ||||
| 				sp.bad0 = ev; | ||||
| 			} | ||||
| 		} | ||||
| 		else if(st == 'X') | ||||
| 		{ | ||||
| 			if(ends_unsorted_region(ev)) | ||||
| 			{ | ||||
| 		} else if (st == 'X') { | ||||
| 			if (ends_unsorted_region(ev)) { | ||||
| 				updated = 1; | ||||
| 				sp.next = ev; | ||||
| 				dbg("executing sort plan for stream tid=%d\n", stream->tid); | ||||
| 				if(execute_sort_plan(&sp) < 0) | ||||
| 				{ | ||||
| 				if (execute_sort_plan(&sp) < 0) { | ||||
| 					err("sort failed for stream tid=%d\n", | ||||
| 							stream->tid); | ||||
| 						stream->tid); | ||||
| 					return -1; | ||||
| 				} | ||||
| 
 | ||||
| @ -348,14 +327,14 @@ stream_winsort(struct ovni_stream *stream, struct ring *r) | ||||
| 		ring_add(r, ev); | ||||
| 	} | ||||
| 
 | ||||
| 	if(empty_regions > 0) | ||||
| 	if (empty_regions > 0) | ||||
| 		err("warning: stream %d contains %ld empty sort regions\n", | ||||
| 				stream->tid, empty_regions); | ||||
| 			stream->tid, empty_regions); | ||||
| 
 | ||||
| 	if(updated && fdatasync(fd) < 0) | ||||
| 	if (updated && fdatasync(fd) < 0) | ||||
| 		die("fdatasync %s failed: %s\n", fn, strerror(errno)); | ||||
| 
 | ||||
| 	if(close(fd) < 0) | ||||
| 	if (close(fd) < 0) | ||||
| 		die("close %s failed: %s\n", fn, strerror(errno)); | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -370,16 +349,14 @@ stream_check(struct ovni_stream *stream) | ||||
| 	uint64_t last_clock = ev->header.clock; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	while(stream->active) | ||||
| 	{ | ||||
| 	while (stream->active) { | ||||
| 		ovni_load_next_event(stream); | ||||
| 		ev = stream->cur_ev; | ||||
| 		uint64_t cur_clock = ovni_ev_get_clock(ev); | ||||
| 
 | ||||
| 		if(cur_clock < last_clock) | ||||
| 		{ | ||||
| 		if (cur_clock < last_clock) { | ||||
| 			err("backwards jump in time %ld -> %ld for stream tid=%d\n", | ||||
| 					last_clock, cur_clock, stream->tid); | ||||
| 				last_clock, cur_clock, stream->tid); | ||||
| 			ret = -1; | ||||
| 		} | ||||
| 
 | ||||
| @ -400,27 +377,21 @@ process_trace(struct ovni_trace *trace) | ||||
| 	ring.size = max_look_back; | ||||
| 	ring.ev = malloc(ring.size * sizeof(struct ovni_ev *)); | ||||
| 
 | ||||
| 	if(ring.ev == NULL) | ||||
| 	if (ring.ev == NULL) | ||||
| 		die("malloc failed: %s\n", strerror(errno)); | ||||
| 
 | ||||
| 	for(i=0; i<trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nstreams; i++) { | ||||
| 		stream = &trace->stream[i]; | ||||
| 		if(operation_mode == SORT) | ||||
| 		{ | ||||
| 		if (operation_mode == SORT) { | ||||
| 			dbg("sorting stream tid=%d\n", stream->tid); | ||||
| 			if(stream_winsort(stream, &ring) != 0) | ||||
| 			{ | ||||
| 			if (stream_winsort(stream, &ring) != 0) { | ||||
| 				err("sort stream tid=%d failed\n", stream->tid); | ||||
| 				/* When sorting, return at the first
 | ||||
| 				 * attempt */ | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			if(stream_check(stream) != 0) | ||||
| 			{ | ||||
| 		} else { | ||||
| 			if (stream_check(stream) != 0) { | ||||
| 				err("stream tid=%d is not sorted\n", stream->tid); | ||||
| 				/* When checking, report all errors and
 | ||||
| 				 * then fail */ | ||||
| @ -431,14 +402,10 @@ process_trace(struct ovni_trace *trace) | ||||
| 
 | ||||
| 	free(ring.ev); | ||||
| 
 | ||||
| 	if(operation_mode == CHECK) | ||||
| 	{ | ||||
| 		if(ret == 0) | ||||
| 		{ | ||||
| 	if (operation_mode == CHECK) { | ||||
| 		if (ret == 0) { | ||||
| 			err("all streams sorted\n"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 		} else { | ||||
| 			err("streams NOT sorted\n"); | ||||
| 		} | ||||
| 	} | ||||
| @ -458,7 +425,7 @@ usage(int argc, char *argv[]) | ||||
| 	err("tracedir, so they are suitable for the emulator ovniemu.\n"); | ||||
| 	err("Only the events enclosed by OU[ OU] are sorted. At most a\n"); | ||||
| 	err("total of %ld events are looked back to insert the unsorted\n", | ||||
| 			max_look_back); | ||||
| 		max_look_back); | ||||
| 	err("events, so the sort procedure can fail with an error.\n"); | ||||
| 	err("\n"); | ||||
| 	err("Options:\n"); | ||||
| @ -476,10 +443,8 @@ parse_args(int argc, char *argv[]) | ||||
| { | ||||
| 	int opt; | ||||
| 
 | ||||
| 	while((opt = getopt(argc, argv, "c")) != -1) | ||||
| 	{ | ||||
| 		switch(opt) | ||||
| 		{ | ||||
| 	while ((opt = getopt(argc, argv, "c")) != -1) { | ||||
| 		switch (opt) { | ||||
| 			case 'c': | ||||
| 				operation_mode = CHECK; | ||||
| 				break; | ||||
| @ -488,8 +453,7 @@ parse_args(int argc, char *argv[]) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(optind >= argc) | ||||
| 	{ | ||||
| 	if (optind >= argc) { | ||||
| 		err("missing tracedir\n"); | ||||
| 		usage(argc, argv); | ||||
| 	} | ||||
| @ -497,7 +461,8 @@ parse_args(int argc, char *argv[]) | ||||
| 	tracedir = argv[optind]; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| int | ||||
| main(int argc, char *argv[]) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct ovni_trace *trace; | ||||
| @ -506,19 +471,18 @@ int main(int argc, char *argv[]) | ||||
| 
 | ||||
| 	trace = calloc(1, sizeof(struct ovni_trace)); | ||||
| 
 | ||||
| 	if(trace == NULL) | ||||
| 	{ | ||||
| 	if (trace == NULL) { | ||||
| 		perror("calloc"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	if(ovni_load_trace(trace, tracedir)) | ||||
| 	if (ovni_load_trace(trace, tracedir)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if(ovni_load_streams(trace)) | ||||
| 	if (ovni_load_streams(trace)) | ||||
| 		return 1; | ||||
| 
 | ||||
| 	if(process_trace(trace)) | ||||
| 	if (process_trace(trace)) | ||||
| 		ret = 1; | ||||
| 
 | ||||
| 	ovni_free_streams(trace); | ||||
|  | ||||
| @ -18,46 +18,46 @@ | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #define INSTR_0ARG(name, mcv) \ | ||||
| 	static inline void name(void) \ | ||||
| 	{ \ | ||||
| 		struct ovni_ev ev = {0}; \ | ||||
| #define INSTR_0ARG(name, mcv)                             \ | ||||
| 	static inline void name(void)                     \ | ||||
| 	{                                                 \ | ||||
| 		struct ovni_ev ev = {0};                  \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now()); \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv); \ | ||||
| 		ovni_ev_emit(&ev); \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                \ | ||||
| 		ovni_ev_emit(&ev);                        \ | ||||
| 	} | ||||
| 
 | ||||
| #define INSTR_1ARG(name, mcv, ta, a) \ | ||||
| 	static inline void name(ta a) \ | ||||
| 	{ \ | ||||
| 		struct ovni_ev ev = {0}; \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now()); \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv); \ | ||||
| #define INSTR_1ARG(name, mcv, ta, a)                              \ | ||||
| 	static inline void name(ta a)                             \ | ||||
| 	{                                                         \ | ||||
| 		struct ovni_ev ev = {0};                          \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());         \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                        \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \ | ||||
| 		ovni_ev_emit(&ev); \ | ||||
| 		ovni_ev_emit(&ev);                                \ | ||||
| 	} | ||||
| 
 | ||||
| #define INSTR_2ARG(name, mcv, ta, a, tb, b) \ | ||||
| 	static inline void name(ta a, tb b) \ | ||||
| 	{ \ | ||||
| 		struct ovni_ev ev = {0}; \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now()); \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv); \ | ||||
| #define INSTR_2ARG(name, mcv, ta, a, tb, b)                       \ | ||||
| 	static inline void name(ta a, tb b)                       \ | ||||
| 	{                                                         \ | ||||
| 		struct ovni_ev ev = {0};                          \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());         \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                        \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &b, sizeof(b)); \ | ||||
| 		ovni_ev_emit(&ev); \ | ||||
| 		ovni_ev_emit(&ev);                                \ | ||||
| 	} | ||||
| 
 | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c) \ | ||||
| 	static inline void name(ta a, tb b, tc c) \ | ||||
| 	{ \ | ||||
| 		struct ovni_ev ev = {0}; \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv); \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now()); \ | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c)                \ | ||||
| 	static inline void name(ta a, tb b, tc c)                 \ | ||||
| 	{                                                         \ | ||||
| 		struct ovni_ev ev = {0};                          \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                        \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());         \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &b, sizeof(b)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &c, sizeof(c)); \ | ||||
| 		ovni_ev_emit(&ev); \ | ||||
| 		ovni_ev_emit(&ev);                                \ | ||||
| 	} | ||||
| 
 | ||||
| INSTR_3ARG(instr_thread_execute, "OHx", int32_t, cpu, int32_t, creator_tid, uint64_t, tag) | ||||
| @ -81,7 +81,7 @@ instr_start(int rank, int nranks) | ||||
| 	char hostname[OVNI_MAX_HOSTNAME]; | ||||
| 	char rankname[OVNI_MAX_HOSTNAME + 64]; | ||||
| 
 | ||||
| 	if(gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 	if (gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 		die("gethostname failed"); | ||||
| 
 | ||||
| 	sprintf(rankname, "%s.%d", hostname, rank); | ||||
| @ -91,13 +91,13 @@ instr_start(int rank, int nranks) | ||||
| 	ovni_thread_init(gettid()); | ||||
| 
 | ||||
| 	/* All ranks inform CPUs */ | ||||
| 	for(int i=0; i < nranks; i++) | ||||
| 	for (int i = 0; i < nranks; i++) | ||||
| 		ovni_add_cpu(i, i); | ||||
| 
 | ||||
| 	int curcpu = rank; | ||||
| 
 | ||||
| 	dbg("thread %d has cpu %d (ncpus=%d)\n", | ||||
| 			gettid(), curcpu, nranks); | ||||
| 		gettid(), curcpu, nranks); | ||||
| 
 | ||||
| 	instr_thread_execute(curcpu, -1, 0); | ||||
| } | ||||
|  | ||||
| @ -34,72 +34,72 @@ INSTR_1ARG(instr_nanos6_task_pause, "6Tp", int32_t, id) | ||||
| INSTR_1ARG(instr_nanos6_task_resume, "6Tr", int32_t, id) | ||||
| INSTR_1ARG(instr_nanos6_task_end, "6Te", int32_t, id) | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_task_create_begin,       "6C[") | ||||
| INSTR_0ARG(instr_nanos6_task_create_end,         "6C]") | ||||
| INSTR_0ARG(instr_nanos6_task_create_begin, "6C[") | ||||
| INSTR_0ARG(instr_nanos6_task_create_end, "6C]") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_sched_server_enter,      "6S[") | ||||
| INSTR_0ARG(instr_nanos6_sched_server_exit,       "6S]") | ||||
| INSTR_0ARG(instr_nanos6_add_ready_enter,         "6Sa") | ||||
| INSTR_0ARG(instr_nanos6_add_ready_exit,          "6SA") | ||||
| INSTR_0ARG(instr_nanos6_process_ready_enter,     "6Sp") | ||||
| INSTR_0ARG(instr_nanos6_process_ready_exit,      "6SP") | ||||
| INSTR_0ARG(instr_nanos6_sched_receive,           "6Sr") | ||||
| INSTR_0ARG(instr_nanos6_sched_assign,            "6Ss") | ||||
| INSTR_0ARG(instr_nanos6_sched_self_assign,       "6S@") | ||||
| INSTR_0ARG(instr_nanos6_sched_server_enter, "6S[") | ||||
| INSTR_0ARG(instr_nanos6_sched_server_exit, "6S]") | ||||
| INSTR_0ARG(instr_nanos6_add_ready_enter, "6Sa") | ||||
| INSTR_0ARG(instr_nanos6_add_ready_exit, "6SA") | ||||
| INSTR_0ARG(instr_nanos6_process_ready_enter, "6Sp") | ||||
| INSTR_0ARG(instr_nanos6_process_ready_exit, "6SP") | ||||
| INSTR_0ARG(instr_nanos6_sched_receive, "6Sr") | ||||
| INSTR_0ARG(instr_nanos6_sched_assign, "6Ss") | ||||
| INSTR_0ARG(instr_nanos6_sched_self_assign, "6S@") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_worker_loop_enter,       "6W[") | ||||
| INSTR_0ARG(instr_nanos6_worker_loop_exit,        "6W]") | ||||
| INSTR_0ARG(instr_nanos6_handle_task_enter,       "6Wt") | ||||
| INSTR_0ARG(instr_nanos6_handle_task_exit,        "6WT") | ||||
| INSTR_0ARG(instr_nanos6_switch_to_enter,         "6Ww") | ||||
| INSTR_0ARG(instr_nanos6_switch_to_exit,          "6WW") | ||||
| INSTR_0ARG(instr_nanos6_migrate_enter,           "6Wm") | ||||
| INSTR_0ARG(instr_nanos6_migrate_exit,            "6WM") | ||||
| INSTR_0ARG(instr_nanos6_suspend_enter,           "6Ws") | ||||
| INSTR_0ARG(instr_nanos6_suspend_exit,            "6WS") | ||||
| INSTR_0ARG(instr_nanos6_resume_enter,            "6Wr") | ||||
| INSTR_0ARG(instr_nanos6_resume_exit,             "6WR") | ||||
| INSTR_0ARG(instr_nanos6_signal,                  "6W*") | ||||
| INSTR_0ARG(instr_nanos6_worker_loop_enter, "6W[") | ||||
| INSTR_0ARG(instr_nanos6_worker_loop_exit, "6W]") | ||||
| INSTR_0ARG(instr_nanos6_handle_task_enter, "6Wt") | ||||
| INSTR_0ARG(instr_nanos6_handle_task_exit, "6WT") | ||||
| INSTR_0ARG(instr_nanos6_switch_to_enter, "6Ww") | ||||
| INSTR_0ARG(instr_nanos6_switch_to_exit, "6WW") | ||||
| INSTR_0ARG(instr_nanos6_migrate_enter, "6Wm") | ||||
| INSTR_0ARG(instr_nanos6_migrate_exit, "6WM") | ||||
| INSTR_0ARG(instr_nanos6_suspend_enter, "6Ws") | ||||
| INSTR_0ARG(instr_nanos6_suspend_exit, "6WS") | ||||
| INSTR_0ARG(instr_nanos6_resume_enter, "6Wr") | ||||
| INSTR_0ARG(instr_nanos6_resume_exit, "6WR") | ||||
| INSTR_0ARG(instr_nanos6_signal, "6W*") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_submit_task_enter,       "6U[") | ||||
| INSTR_0ARG(instr_nanos6_submit_task_exit,        "6U]") | ||||
| INSTR_0ARG(instr_nanos6_submit_task_enter, "6U[") | ||||
| INSTR_0ARG(instr_nanos6_submit_task_exit, "6U]") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_spawn_function_enter,    "6F[") | ||||
| INSTR_0ARG(instr_nanos6_spawn_function_exit,     "6F]") | ||||
| INSTR_0ARG(instr_nanos6_spawn_function_enter, "6F[") | ||||
| INSTR_0ARG(instr_nanos6_spawn_function_exit, "6F]") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_taskfor_start,           "6O[") | ||||
| INSTR_0ARG(instr_nanos6_taskfor_stop,            "6O]") | ||||
| INSTR_0ARG(instr_nanos6_taskfor_start, "6O[") | ||||
| INSTR_0ARG(instr_nanos6_taskfor_stop, "6O]") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_task_body_enter,         "6t[") | ||||
| INSTR_0ARG(instr_nanos6_task_body_exit,          "6t]") | ||||
| INSTR_0ARG(instr_nanos6_task_body_enter, "6t[") | ||||
| INSTR_0ARG(instr_nanos6_task_body_exit, "6t]") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_register_enter,          "6Dr") | ||||
| INSTR_0ARG(instr_nanos6_register_exit,           "6DR") | ||||
| INSTR_0ARG(instr_nanos6_unregister_enter,        "6Du") | ||||
| INSTR_0ARG(instr_nanos6_unregister_exit,         "6DU") | ||||
| INSTR_0ARG(instr_nanos6_register_enter, "6Dr") | ||||
| INSTR_0ARG(instr_nanos6_register_exit, "6DR") | ||||
| INSTR_0ARG(instr_nanos6_unregister_enter, "6Du") | ||||
| INSTR_0ARG(instr_nanos6_unregister_exit, "6DU") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_block_enter,             "6Bb") | ||||
| INSTR_0ARG(instr_nanos6_block_exit,              "6BB") | ||||
| INSTR_0ARG(instr_nanos6_unblock_enter,           "6Bb") | ||||
| INSTR_0ARG(instr_nanos6_unblock_exit,            "6BB") | ||||
| INSTR_0ARG(instr_nanos6_taskwait_enter,          "6Bw") | ||||
| INSTR_0ARG(instr_nanos6_taskwait_exit,           "6BW") | ||||
| INSTR_0ARG(instr_nanos6_waitfor_enter,           "6Bf") | ||||
| INSTR_0ARG(instr_nanos6_waitfor_exit,            "6BF") | ||||
| INSTR_0ARG(instr_nanos6_block_enter, "6Bb") | ||||
| INSTR_0ARG(instr_nanos6_block_exit, "6BB") | ||||
| INSTR_0ARG(instr_nanos6_unblock_enter, "6Bb") | ||||
| INSTR_0ARG(instr_nanos6_unblock_exit, "6BB") | ||||
| INSTR_0ARG(instr_nanos6_taskwait_enter, "6Bw") | ||||
| INSTR_0ARG(instr_nanos6_taskwait_exit, "6BW") | ||||
| INSTR_0ARG(instr_nanos6_waitfor_enter, "6Bf") | ||||
| INSTR_0ARG(instr_nanos6_waitfor_exit, "6BF") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_external_set,            "6He") | ||||
| INSTR_0ARG(instr_nanos6_external_unset,          "6HE") | ||||
| INSTR_0ARG(instr_nanos6_worker_set,              "6Hw") | ||||
| INSTR_0ARG(instr_nanos6_worker_unset,            "6HW") | ||||
| INSTR_0ARG(instr_nanos6_leader_set,              "6Hl") | ||||
| INSTR_0ARG(instr_nanos6_leader_unset,            "6HL") | ||||
| INSTR_0ARG(instr_nanos6_main_set,                "6Hm") | ||||
| INSTR_0ARG(instr_nanos6_main_unset,              "6HM") | ||||
| INSTR_0ARG(instr_nanos6_external_set, "6He") | ||||
| INSTR_0ARG(instr_nanos6_external_unset, "6HE") | ||||
| INSTR_0ARG(instr_nanos6_worker_set, "6Hw") | ||||
| INSTR_0ARG(instr_nanos6_worker_unset, "6HW") | ||||
| INSTR_0ARG(instr_nanos6_leader_set, "6Hl") | ||||
| INSTR_0ARG(instr_nanos6_leader_unset, "6HL") | ||||
| INSTR_0ARG(instr_nanos6_main_set, "6Hm") | ||||
| INSTR_0ARG(instr_nanos6_main_unset, "6HM") | ||||
| 
 | ||||
| INSTR_0ARG(instr_nanos6_alloc_enter,             "6Ma") | ||||
| INSTR_0ARG(instr_nanos6_alloc_exit,              "6MA") | ||||
| INSTR_0ARG(instr_nanos6_free_enter,              "6Mf") | ||||
| INSTR_0ARG(instr_nanos6_free_exit,               "6MF") | ||||
| INSTR_0ARG(instr_nanos6_alloc_enter, "6Ma") | ||||
| INSTR_0ARG(instr_nanos6_alloc_exit, "6MA") | ||||
| INSTR_0ARG(instr_nanos6_free_enter, "6Mf") | ||||
| INSTR_0ARG(instr_nanos6_free_exit, "6MF") | ||||
| 
 | ||||
| static inline void | ||||
| instr_nanos6_task_create_and_execute(int32_t id, uint32_t typeid) | ||||
|  | ||||
| @ -14,16 +14,14 @@ main(void) | ||||
| 	instr_nanos6_type_create(typeid); | ||||
| 
 | ||||
| 	/* Create and run the tasks, one nested into another */ | ||||
| 	for(int i = 0; i < ntasks; i++) | ||||
| 	{ | ||||
| 	for (int i = 0; i < ntasks; i++) { | ||||
| 		instr_nanos6_handle_task_enter(); | ||||
| 		instr_nanos6_task_create_and_execute(i + 1, typeid); | ||||
| 		usleep(500); | ||||
| 	} | ||||
| 
 | ||||
| 	/* End the tasks in the opposite order */ | ||||
| 	for(int i = ntasks - 1; i >= 0; i--) | ||||
| 	{ | ||||
| 	for (int i = ntasks - 1; i >= 0; i--) { | ||||
| 		instr_nanos6_task_end(i + 1); | ||||
| 		instr_nanos6_task_body_exit(); | ||||
| 		instr_nanos6_handle_task_exit(); | ||||
|  | ||||
| @ -14,11 +14,10 @@ main(void) | ||||
| 	int ntasks = 100; | ||||
| 	int ntypes = 10; | ||||
| 
 | ||||
| 	for(int i = 0; i < ntypes; i++) | ||||
| 	for (int i = 0; i < ntypes; i++) | ||||
| 		instr_nanos6_type_create(i + 1); | ||||
| 
 | ||||
| 	for(int i = 0; i < ntasks; i++) | ||||
| 	{ | ||||
| 	for (int i = 0; i < ntasks; i++) { | ||||
| 		instr_nanos6_task_create_and_execute(i + 1, (i % ntypes) + 1); | ||||
| 		usleep(500); | ||||
| 		instr_nanos6_task_end(i + 1); | ||||
|  | ||||
| @ -22,15 +22,14 @@ main(void) | ||||
| 	instr_nosv_type_create(typeid); | ||||
| 
 | ||||
| 	/* Create and run the tasks, one nested into another */ | ||||
| 	for(int i = 0; i < ntasks; i++) | ||||
| 	for (int i = 0; i < ntasks; i++) | ||||
| 		create_and_run(i + 1, typeid, 500); | ||||
| 
 | ||||
| 	/* End the tasks in the opposite order */ | ||||
| 	for(int i = ntasks - 1; i >= 0; i--) | ||||
| 	for (int i = ntasks - 1; i >= 0; i--) | ||||
| 		instr_nosv_task_end(i + 1); | ||||
| 
 | ||||
| 	instr_end(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -27,4 +27,3 @@ main(void) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -14,11 +14,10 @@ main(void) | ||||
| 	int ntasks = 100; | ||||
| 	int ntypes = 10; | ||||
| 
 | ||||
| 	for(int i=0; i<ntypes; i++) | ||||
| 	for (int i = 0; i < ntypes; i++) | ||||
| 		instr_nosv_type_create(i + 1); | ||||
| 
 | ||||
| 	for(int i=0; i<ntasks; i++) | ||||
| 	{ | ||||
| 	for (int i = 0; i < ntasks; i++) { | ||||
| 		instr_nosv_task_create(i + 1, (i % ntypes) + 1); | ||||
| 		instr_nosv_task_execute(i + 1); | ||||
| 		usleep(500); | ||||
| @ -29,4 +28,3 @@ main(void) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -4,25 +4,24 @@ | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <limits.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <sys/types.h> | ||||
| #include <linux/limits.h> | ||||
| #include <limits.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| static inline void | ||||
| init(void) | ||||
| { | ||||
| 	char hostname[HOST_NAME_MAX]; | ||||
| 
 | ||||
| 	if(gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 	{ | ||||
| 	if (gethostname(hostname, HOST_NAME_MAX) != 0) { | ||||
| 		perror("gethostname failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -32,7 +31,8 @@ init(void) | ||||
| 	ovni_add_cpu(0, 0); | ||||
| } | ||||
| 
 | ||||
| static void emit(uint8_t *buf, size_t size) | ||||
| static void | ||||
| emit(uint8_t *buf, size_t size) | ||||
| { | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 	ovni_ev_set_mcv(&ev, "O$$"); | ||||
| @ -42,13 +42,13 @@ static void emit(uint8_t *buf, size_t size) | ||||
| 
 | ||||
| #define NRUNS 50 | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	size_t payload_size; | ||||
| 	uint8_t *payload_buf; | ||||
| 
 | ||||
| 	if(setenv("OVNI_TMPDIR", "/dev/shm/ovni-flush-overhead", 1) != 0) | ||||
| 	{ | ||||
| 	if (setenv("OVNI_TMPDIR", "/dev/shm/ovni-flush-overhead", 1) != 0) { | ||||
| 		perror("setenv failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -59,21 +59,18 @@ int main(void) | ||||
| 	payload_size = 1024 * 1024; | ||||
| 	payload_buf = calloc(1, payload_size); | ||||
| 
 | ||||
| 	if(!payload_buf) | ||||
| 	{ | ||||
| 	if (!payload_buf) { | ||||
| 		perror("calloc failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	double *times = calloc(sizeof(double), NRUNS); | ||||
| 	if(times == NULL) | ||||
| 	{ | ||||
| 	if (times == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	for(int i=0; i < NRUNS; i++) | ||||
| 	{ | ||||
| 	for (int i = 0; i < NRUNS; i++) { | ||||
| 		emit(payload_buf, payload_size); | ||||
| 		double t0 = (double) ovni_clock_now(); | ||||
| 		ovni_flush(); | ||||
| @ -83,10 +80,10 @@ int main(void) | ||||
| 	} | ||||
| 
 | ||||
| 	double mean = 0.0; | ||||
| 	for(int i=0; i < NRUNS; i++) | ||||
| 	for (int i = 0; i < NRUNS; i++) | ||||
| 		mean += times[i]; | ||||
| 	mean /= (double) NRUNS; | ||||
| 	 | ||||
| 
 | ||||
| 	fprintf(stderr, "mean %f ms\n", mean); | ||||
| 
 | ||||
| 	/* It should be able to write 1 MiB in less than 1 ms */ | ||||
| @ -94,8 +91,8 @@ int main(void) | ||||
| 		fprintf(stderr, "took too much time to flush: %f ms\n", mean); | ||||
| 
 | ||||
| 		fprintf(stderr, "times (in ms):\n"); | ||||
| 		for(int i=0; i < NRUNS; i++) | ||||
| 		    fprintf(stderr, " %4d  %f\n", i, times[i]); | ||||
| 		for (int i = 0; i < NRUNS; i++) | ||||
| 			fprintf(stderr, " %4d  %f\n", i, times[i]); | ||||
| 
 | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| @ -4,25 +4,24 @@ | ||||
| #define _POSIX_C_SOURCE 200112L | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include <limits.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/syscall.h> | ||||
| #include <sys/types.h> | ||||
| #include <linux/limits.h> | ||||
| #include <limits.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| static inline void | ||||
| init(void) | ||||
| { | ||||
| 	char hostname[HOST_NAME_MAX]; | ||||
| 
 | ||||
| 	if(gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 	{ | ||||
| 	if (gethostname(hostname, HOST_NAME_MAX) != 0) { | ||||
| 		perror("gethostname failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| @ -32,7 +31,8 @@ init(void) | ||||
| 	ovni_add_cpu(0, 0); | ||||
| } | ||||
| 
 | ||||
| static void emit(uint8_t *buf, size_t size) | ||||
| static void | ||||
| emit(uint8_t *buf, size_t size) | ||||
| { | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 	ovni_ev_set_mcv(&ev, "O$$"); | ||||
| @ -40,7 +40,8 @@ static void emit(uint8_t *buf, size_t size) | ||||
| 	ovni_ev_jumbo_emit(&ev, buf, size); | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	size_t payload_size; | ||||
| 	uint8_t *payload_buf; | ||||
| @ -50,8 +51,7 @@ int main(void) | ||||
| 	payload_size = (size_t) (0.9 * (double) OVNI_MAX_EV_BUF); | ||||
| 	payload_buf = calloc(1, payload_size); | ||||
| 
 | ||||
| 	if(!payload_buf) | ||||
| 	{ | ||||
| 	if (!payload_buf) { | ||||
| 		perror("calloc failed"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
|  | ||||
| @ -3,8 +3,8 @@ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <inttypes.h> | ||||
| @ -15,27 +15,29 @@ | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| static void fail(const char *msg) | ||||
| static void | ||||
| fail(const char *msg) | ||||
| { | ||||
| 	fprintf(stderr, "%s\n", msg); | ||||
| 	abort(); | ||||
| } | ||||
| 
 | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c)               \ | ||||
| 	static inline void name(ta a, tb b, tc c)                \ | ||||
| 	{                                                        \ | ||||
| 		struct ovni_ev ev = {0};                         \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                       \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());        \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&b, sizeof(b)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&c, sizeof(c)); \ | ||||
| 		ovni_ev_emit(&ev);                                    \ | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c)                \ | ||||
| 	static inline void name(ta a, tb b, tc c)                 \ | ||||
| 	{                                                         \ | ||||
| 		struct ovni_ev ev = {0};                          \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                        \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());         \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &b, sizeof(b)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &c, sizeof(c)); \ | ||||
| 		ovni_ev_emit(&ev);                                \ | ||||
| 	} | ||||
| 
 | ||||
| INSTR_3ARG(instr_thread_execute, "OHx", int32_t, cpu, int32_t, creator_tid, uint64_t, tag) | ||||
| 
 | ||||
| static inline void instr_thread_end(void) | ||||
| static inline void | ||||
| instr_thread_end(void) | ||||
| { | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 
 | ||||
| @ -47,36 +49,37 @@ static inline void instr_thread_end(void) | ||||
| 	ovni_flush(); | ||||
| } | ||||
| 
 | ||||
| static inline void instr_start(int rank, int nranks) | ||||
| static inline void | ||||
| instr_start(int rank, int nranks) | ||||
| { | ||||
| 	char hostname[HOST_NAME_MAX]; | ||||
| 
 | ||||
| 	if(gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 	if (gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 		fail("gethostname failed"); | ||||
| 
 | ||||
| 	ovni_proc_init(1, hostname, getpid()); | ||||
| 	 | ||||
| 
 | ||||
| 	ovni_proc_set_rank(rank, nranks); | ||||
| 
 | ||||
| 	ovni_thread_init(gettid()); | ||||
| 
 | ||||
| 	/* Only the rank 0 inform about all CPUs */ | ||||
| 	if(rank == 0) | ||||
| 	{ | ||||
| 	if (rank == 0) { | ||||
| 		/* Fake nranks cpus */ | ||||
| 		for(int i=0; i < nranks; i++) | ||||
| 		for (int i = 0; i < nranks; i++) | ||||
| 			ovni_add_cpu(i, i); | ||||
| 	} | ||||
| 
 | ||||
| 	int curcpu = rank; | ||||
| 
 | ||||
| 	fprintf(stderr, "thread %d has cpu %d (ncpus=%d)\n", | ||||
| 			gettid(), curcpu, nranks); | ||||
| 		gettid(), curcpu, nranks); | ||||
| 
 | ||||
| 	instr_thread_execute(curcpu, -1, 0); | ||||
| } | ||||
| 
 | ||||
| static inline void instr_end(void) | ||||
| static inline void | ||||
| instr_end(void) | ||||
| { | ||||
| 	instr_thread_end(); | ||||
| 	ovni_thread_free(); | ||||
| @ -132,7 +135,8 @@ task(int32_t id, uint32_t typeid, int us) | ||||
| 	ovni_ev_emit(&ev); | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	int rank = atoi(getenv("OVNI_RANK")); | ||||
| 	int nranks = atoi(getenv("OVNI_NRANKS")); | ||||
| @ -143,11 +147,10 @@ int main(void) | ||||
| 	type_create(typeid); | ||||
| 
 | ||||
| 	/* Create some fake nosv tasks */ | ||||
| 	for(int i=0; i<10; i++) | ||||
| 	for (int i = 0; i < 10; i++) | ||||
| 		task(i + 1, typeid, 5000); | ||||
| 
 | ||||
| 	instr_end(); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -3,8 +3,8 @@ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "compat.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <inttypes.h> | ||||
| @ -16,27 +16,29 @@ | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| static void fail(const char *msg) | ||||
| static void | ||||
| fail(const char *msg) | ||||
| { | ||||
| 	fprintf(stderr, "%s\n", msg); | ||||
| 	abort(); | ||||
| } | ||||
| 
 | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c)               \ | ||||
| 	static inline void name(ta a, tb b, tc c)                \ | ||||
| 	{                                                        \ | ||||
| 		struct ovni_ev ev = {0};                         \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                       \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());        \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&b, sizeof(b)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *)&c, sizeof(c)); \ | ||||
| 		ovni_ev_emit(&ev);                                    \ | ||||
| #define INSTR_3ARG(name, mcv, ta, a, tb, b, tc, c)                \ | ||||
| 	static inline void name(ta a, tb b, tc c)                 \ | ||||
| 	{                                                         \ | ||||
| 		struct ovni_ev ev = {0};                          \ | ||||
| 		ovni_ev_set_mcv(&ev, mcv);                        \ | ||||
| 		ovni_ev_set_clock(&ev, ovni_clock_now());         \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &a, sizeof(a)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &b, sizeof(b)); \ | ||||
| 		ovni_payload_add(&ev, (uint8_t *) &c, sizeof(c)); \ | ||||
| 		ovni_ev_emit(&ev);                                \ | ||||
| 	} | ||||
| 
 | ||||
| INSTR_3ARG(instr_thread_execute, "OHx", int32_t, cpu, int32_t, creator_tid, uint64_t, tag) | ||||
| 
 | ||||
| static inline void instr_thread_end(void) | ||||
| static inline void | ||||
| instr_thread_end(void) | ||||
| { | ||||
| 	struct ovni_ev ev = {0}; | ||||
| 
 | ||||
| @ -48,29 +50,27 @@ static inline void instr_thread_end(void) | ||||
| 	ovni_flush(); | ||||
| } | ||||
| 
 | ||||
| static inline void instr_start(int rank) | ||||
| static inline void | ||||
| instr_start(int rank) | ||||
| { | ||||
| 	cpu_set_t mask; | ||||
| 	char hostname[HOST_NAME_MAX]; | ||||
| 	int i, j = 0, curcpu = -1; | ||||
| 	int last_phy; | ||||
| 
 | ||||
| 	if(gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 	if (gethostname(hostname, HOST_NAME_MAX) != 0) | ||||
| 		fail("gethostname failed"); | ||||
| 
 | ||||
| 	if(sched_getaffinity(0, sizeof(mask), &mask) < 0) | ||||
| 	if (sched_getaffinity(0, sizeof(mask), &mask) < 0) | ||||
| 		fail("sched_getaffinity failed"); | ||||
| 
 | ||||
| 	ovni_proc_init(1, hostname, getpid()); | ||||
| 	ovni_thread_init(gettid()); | ||||
| 
 | ||||
| 	/* Only the rank 0 inform about all CPUs */ | ||||
| 	if(rank == 0) | ||||
| 	{ | ||||
| 		for(i=0; i < CPU_SETSIZE; i++) | ||||
| 		{ | ||||
| 			if(CPU_ISSET(i, &mask)) | ||||
| 			{ | ||||
| 	if (rank == 0) { | ||||
| 		for (i = 0; i < CPU_SETSIZE; i++) { | ||||
| 			if (CPU_ISSET(i, &mask)) { | ||||
| 				last_phy = i; | ||||
| 
 | ||||
| 				if (rank == 0) | ||||
| @ -79,28 +79,30 @@ static inline void instr_start(int rank) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if(CPU_COUNT(&mask) == 1) | ||||
| 	if (CPU_COUNT(&mask) == 1) | ||||
| 		curcpu = last_phy; | ||||
| 	else | ||||
| 		curcpu = -1; | ||||
| 
 | ||||
| 	fprintf(stderr, "thread %d has cpu %d (ncpus=%d)\n", | ||||
| 			gettid(), curcpu, CPU_COUNT(&mask)); | ||||
| 		gettid(), curcpu, CPU_COUNT(&mask)); | ||||
| 
 | ||||
| 	instr_thread_execute(curcpu, -1, 0); | ||||
| } | ||||
| 
 | ||||
| static inline void instr_end(void) | ||||
| static inline void | ||||
| instr_end(void) | ||||
| { | ||||
| 	instr_thread_end(); | ||||
| 	ovni_thread_free(); | ||||
| 	ovni_proc_fini(); | ||||
| } | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	int rank = atoi(getenv("OVNI_RANK")); | ||||
| 	//int nranks = atoi(getenv("OVNI_NRANKS"));
 | ||||
| 	// int nranks = atoi(getenv("OVNI_NRANKS"));
 | ||||
| 
 | ||||
| 	instr_start(rank); | ||||
| 
 | ||||
| @ -110,4 +112,3 @@ int main(void) | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -4,9 +4,10 @@ | ||||
| #define _GNU_SOURCE | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	#pragma oss task if(0) | ||||
| #pragma oss task if (0) | ||||
| 	{ | ||||
| 		usleep(1000); | ||||
| 	} | ||||
|  | ||||
| @ -1,14 +1,15 @@ | ||||
| /* Copyright (c) 2022 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	#pragma oss task | ||||
| #pragma oss task | ||||
| 	{ | ||||
|         #pragma oss task | ||||
|         { | ||||
|         } | ||||
|         #pragma oss taskwait | ||||
| #pragma oss task | ||||
| 		{ | ||||
| 		} | ||||
| #pragma oss taskwait | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -36,25 +36,26 @@ do_run(void) | ||||
| 	memset(handle, 0, ntasks * sizeof(void *)); | ||||
| 	atomic_store(&nhandles, 0); | ||||
| 
 | ||||
| 	for(int t = 0; t < ntasks; t++) | ||||
| 	for (int t = 0; t < ntasks; t++) | ||||
| 		do_task(t); | ||||
| 
 | ||||
| 	/* Wait for all tasks to fill the handle */ | ||||
| 	while (atomic_load(&nhandles) < ntasks); | ||||
| 	while (atomic_load(&nhandles) < ntasks) | ||||
| 		; | ||||
| 
 | ||||
| 	/* Is ok if we call unblock before the block happens */ | ||||
| 	for(int t = 0; t < ntasks; t++) | ||||
| 	{ | ||||
| 	for (int t = 0; t < ntasks; t++) { | ||||
| 		if (handle[t] == NULL) | ||||
| 			abort(); | ||||
| 
 | ||||
| 		nanos6_unblock_task(handle[t]); | ||||
| 	} | ||||
| 
 | ||||
| 	#pragma oss taskwait | ||||
| #pragma oss taskwait | ||||
| } | ||||
| 
 | ||||
| static int get_ncpus(void) | ||||
| static int | ||||
| get_ncpus(void) | ||||
| { | ||||
| 	return (int) nanos6_get_num_cpus(); | ||||
| } | ||||
| @ -66,13 +67,12 @@ main(void) | ||||
| 
 | ||||
| 	handle = calloc(ntasks, sizeof(void *)); | ||||
| 
 | ||||
| 	if(handle == NULL) | ||||
| 	{ | ||||
| 	if (handle == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	for(int run = 0; run < nruns; run++) | ||||
| 	for (int run = 0; run < nruns; run++) | ||||
| 		do_run(); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -1,17 +1,16 @@ | ||||
| /* Copyright (c) 2022 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	for(int i = 0; i < 5000; i++) | ||||
| 	{ | ||||
| 		#pragma oss task | ||||
| 	for (int i = 0; i < 5000; i++) { | ||||
| #pragma oss task | ||||
| 		{ | ||||
| 			for(volatile long j = 0; j < 10000L; j++) | ||||
| 			{ | ||||
| 			for (volatile long j = 0; j < 10000L; j++) { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	#pragma oss taskwait | ||||
| #pragma oss taskwait | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -1,9 +1,10 @@ | ||||
| /* Copyright (c) 2022 Barcelona Supercomputing Center (BSC)
 | ||||
|  * SPDX-License-Identifier: GPL-3.0-or-later */ | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	#pragma oss task | ||||
| #pragma oss task | ||||
| 	{ | ||||
| 	} | ||||
| 	return 0; | ||||
|  | ||||
| @ -4,10 +4,11 @@ | ||||
| #define _GNU_SOURCE | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	#pragma oss task for | ||||
| 	for(int i = 0; i < 1024; i++) | ||||
| #pragma oss task for | ||||
| 	for (int i = 0; i < 1024; i++) | ||||
| 		usleep(1000); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
| @ -3,33 +3,35 @@ | ||||
| 
 | ||||
| #define _DEFAULT_SOURCE | ||||
| 
 | ||||
| #include <unistd.h> | ||||
| #include <nosv.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| 
 | ||||
| int main(void) | ||||
| int | ||||
| main(void) | ||||
| { | ||||
| 	nosv_init(); | ||||
| 
 | ||||
| 	nosv_task_type_t type; | ||||
| 	if(nosv_type_init(&type, NULL, NULL, NULL, "adopted", NULL, | ||||
| 				NULL, NOSV_TYPE_INIT_EXTERNAL) != 0) | ||||
| 	if (nosv_type_init(&type, NULL, NULL, NULL, "adopted", NULL, | ||||
| 		    NULL, NOSV_TYPE_INIT_EXTERNAL) | ||||
| 		!= 0) | ||||
| 		die("nosv_type_init failed\n"); | ||||
| 
 | ||||
| 	nosv_task_t task; | ||||
| 	if(nosv_attach(&task, type, 0, NULL, 0) != 0) | ||||
| 	if (nosv_attach(&task, type, 0, NULL, 0) != 0) | ||||
| 		die("nosv_attach failed\n"); | ||||
| 
 | ||||
| 	usleep(100); | ||||
| 
 | ||||
| 	if(nosv_detach(0) != 0) | ||||
| 	if (nosv_detach(0) != 0) | ||||
| 		die("nosv_detach failed\n"); | ||||
| 
 | ||||
| 	if(nosv_type_destroy(type, 0) != 0) | ||||
| 	if (nosv_type_destroy(type, 0) != 0) | ||||
| 		die("nosv_type_destroy failed\n"); | ||||
| 
 | ||||
| 	if(nosv_shutdown() != 0) | ||||
| 	if (nosv_shutdown() != 0) | ||||
| 		die("nosv_shutdown failed\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
|  | ||||
							
								
								
									
										290
									
								
								trace.c
									
									
									
									
									
								
							
							
						
						
									
										290
									
								
								trace.c
									
									
									
									
									
								
							| @ -6,20 +6,19 @@ | ||||
| #define _GNU_SOURCE | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <time.h> | ||||
| #include <string.h> | ||||
| #include <linux/limits.h> | ||||
| #include <errno.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/mman.h> | ||||
| #include <stdatomic.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <linux/limits.h> | ||||
| #include <stdatomic.h> | ||||
| #include <stdint.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| static int | ||||
| find_dir_prefix_str(const char *dirname, const char *prefix, const char **str) | ||||
| @ -29,18 +28,18 @@ find_dir_prefix_str(const char *dirname, const char *prefix, const char **str) | ||||
| 	p = dirname; | ||||
| 
 | ||||
| 	/* Check the prefix */ | ||||
| 	if(strncmp(p, prefix, strlen(prefix)) != 0) | ||||
| 	if (strncmp(p, prefix, strlen(prefix)) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	p += strlen(prefix); | ||||
| 
 | ||||
| 	/* Find the dot */ | ||||
| 	if(*p != '.') | ||||
| 	if (*p != '.') | ||||
| 		return -1; | ||||
| 
 | ||||
| 	p++; | ||||
| 
 | ||||
| 	if(str) | ||||
| 	if (str) | ||||
| 		*str = p; | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -51,7 +50,7 @@ find_dir_prefix_int(const char *dirname, const char *prefix, int *num) | ||||
| { | ||||
| 	const char *p; | ||||
| 
 | ||||
| 	if(find_dir_prefix_str(dirname, prefix, &p) != 0) | ||||
| 	if (find_dir_prefix_str(dirname, prefix, &p) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	/* Convert the suffix string to a number */ | ||||
| @ -66,9 +65,8 @@ count_dir_prefix(DIR *dir, const char *prefix) | ||||
| 	struct dirent *dirent; | ||||
| 	size_t n = 0; | ||||
| 
 | ||||
| 	while((dirent = readdir(dir)) != NULL) | ||||
| 	{ | ||||
| 		if(find_dir_prefix_str(dirent->d_name, prefix, NULL) != 0) | ||||
| 	while ((dirent = readdir(dir)) != NULL) { | ||||
| 		if (find_dir_prefix_str(dirent->d_name, prefix, NULL) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		n++; | ||||
| @ -88,8 +86,7 @@ load_thread(struct ovni_ethread *thread, struct ovni_eproc *proc, int index, int | ||||
| 	thread->state = TH_ST_UNKNOWN; | ||||
| 	thread->proc = proc; | ||||
| 
 | ||||
| 	if(strlen(filepath) >= PATH_MAX) | ||||
| 	{ | ||||
| 	if (strlen(filepath) >= PATH_MAX) { | ||||
| 		err("filepath too large: %s\n", filepath); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -105,24 +102,21 @@ load_proc_metadata(struct ovni_eproc *proc, int *rank_enabled) | ||||
| 	JSON_Object *meta; | ||||
| 
 | ||||
| 	meta = json_value_get_object(proc->meta); | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("load_proc_metadata: json_value_get_object() failed\n"); | ||||
| 
 | ||||
| 	JSON_Value *appid_val = json_object_get_value(meta, "app_id"); | ||||
| 	if(appid_val == NULL) | ||||
| 	if (appid_val == NULL) | ||||
| 		die("process %d is missing app_id in metadata\n", proc->pid); | ||||
| 
 | ||||
| 	proc->appid = (int) json_number(appid_val); | ||||
| 
 | ||||
| 	JSON_Value *rank_val = json_object_get_value(meta, "rank"); | ||||
| 
 | ||||
| 	if(rank_val != NULL) | ||||
| 	{ | ||||
| 	if (rank_val != NULL) { | ||||
| 		proc->rank = (int) json_number(rank_val); | ||||
| 		*rank_enabled = 1; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 	} else { | ||||
| 		proc->rank = -1; | ||||
| 	} | ||||
| } | ||||
| @ -131,40 +125,35 @@ static void | ||||
| check_metadata_version(struct ovni_eproc *proc) | ||||
| { | ||||
| 	JSON_Object *meta = json_value_get_object(proc->meta); | ||||
| 	if(meta == NULL) | ||||
| 	if (meta == NULL) | ||||
| 		die("check_metadata_version: json_value_get_object() failed\n"); | ||||
| 
 | ||||
| 	JSON_Value *version_val = json_object_get_value(meta, "version"); | ||||
| 	if(version_val == NULL) | ||||
| 	{ | ||||
| 	if (version_val == NULL) { | ||||
| 		die("process %d is missing attribute \"version\" in metadata\n", | ||||
| 				proc->pid); | ||||
| 			proc->pid); | ||||
| 	} | ||||
| 
 | ||||
| 	int version = (int) json_number(version_val); | ||||
| 
 | ||||
| 	if(version != OVNI_METADATA_VERSION) | ||||
| 	{ | ||||
| 	if (version != OVNI_METADATA_VERSION) { | ||||
| 		die("pid %d: metadata version mismatch %d (expected %d)\n", | ||||
| 				proc->pid, version, | ||||
| 				OVNI_METADATA_VERSION); | ||||
| 			proc->pid, version, | ||||
| 			OVNI_METADATA_VERSION); | ||||
| 	} | ||||
| 
 | ||||
| 	JSON_Value *mversion_val = json_object_get_value(meta, "model_version"); | ||||
| 	if(mversion_val == NULL) | ||||
| 	{ | ||||
| 	if (mversion_val == NULL) { | ||||
| 		die("process %d is missing attribute \"model_version\" in metadata\n", | ||||
| 				proc->pid); | ||||
| 			proc->pid); | ||||
| 	} | ||||
| 
 | ||||
| 	const char *mversion = json_string(mversion_val); | ||||
| 
 | ||||
| 	if(strcmp(mversion, OVNI_MODEL_VERSION) != 0) | ||||
| 	{ | ||||
| 	if (strcmp(mversion, OVNI_MODEL_VERSION) != 0) { | ||||
| 		die("pid %d: metadata model version mismatch '%s' (expected '%s')\n", | ||||
| 				proc->pid, mversion, | ||||
| 				OVNI_MODEL_VERSION); | ||||
| 
 | ||||
| 			proc->pid, mversion, | ||||
| 			OVNI_MODEL_VERSION); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| @ -174,9 +163,9 @@ compare_int(const void *a, const void *b) | ||||
| 	int aa = *(const int *) a; | ||||
| 	int bb = *(const int *) b; | ||||
| 
 | ||||
| 	if(aa < bb) | ||||
| 	if (aa < bb) | ||||
| 		return -1; | ||||
| 	else if(aa > bb) | ||||
| 	else if (aa > bb) | ||||
| 		return +1; | ||||
| 	else | ||||
| 		return 0; | ||||
| @ -197,16 +186,13 @@ load_proc(struct ovni_eproc *proc, struct ovni_loom *loom, int index, int pid, c | ||||
| 	proc->gindex = total_procs++; | ||||
| 	proc->loom = loom; | ||||
| 
 | ||||
| 	if(snprintf(path, PATH_MAX, "%s/%s", procdir, "metadata.json") >= | ||||
| 			PATH_MAX) | ||||
| 	{ | ||||
| 	if (snprintf(path, PATH_MAX, "%s/%s", procdir, "metadata.json") >= PATH_MAX) { | ||||
| 		err("snprintf: path too large: %s\n", procdir); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	proc->meta = json_parse_file_with_comments(path); | ||||
| 	if(proc->meta == NULL) | ||||
| 	{ | ||||
| 	if (proc->meta == NULL) { | ||||
| 		err("error loading metadata from %s\n", path); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -216,51 +202,45 @@ load_proc(struct ovni_eproc *proc, struct ovni_loom *loom, int index, int pid, c | ||||
| 	/* The appid is populated from the metadata */ | ||||
| 	load_proc_metadata(proc, &loom->rank_enabled); | ||||
| 
 | ||||
| 	if((dir = opendir(procdir)) == NULL) | ||||
| 	{ | ||||
| 	if ((dir = opendir(procdir)) == NULL) { | ||||
| 		fprintf(stderr, "opendir %s failed: %s\n", | ||||
| 				procdir, strerror(errno)); | ||||
| 			procdir, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	proc->nthreads = count_dir_prefix(dir, "thread"); | ||||
| 
 | ||||
| 	if(proc->nthreads <= 0) | ||||
| 	{ | ||||
| 	if (proc->nthreads <= 0) { | ||||
| 		err("cannot find any thread for process %d\n", | ||||
| 				proc->pid); | ||||
| 			proc->pid); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	proc->thread = calloc(proc->nthreads, sizeof(struct ovni_ethread)); | ||||
| 
 | ||||
| 	if(proc->thread == NULL) | ||||
| 	{ | ||||
| 	if (proc->thread == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	int *tids; | ||||
| 
 | ||||
| 	if((tids = calloc(proc->nthreads, sizeof(int))) == NULL) | ||||
| 	{ | ||||
| 	if ((tids = calloc(proc->nthreads, sizeof(int))) == NULL) { | ||||
| 		perror("calloc failed\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	rewinddir(dir); | ||||
| 
 | ||||
| 	for(size_t i = 0; i < proc->nthreads; ) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < proc->nthreads;) { | ||||
| 		dirent = readdir(dir); | ||||
| 
 | ||||
| 		if(dirent == NULL) | ||||
| 		{ | ||||
| 		if (dirent == NULL) { | ||||
| 			err("inconsistent: readdir returned NULL\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		if(find_dir_prefix_int(dirent->d_name, "thread", &tids[i]) != 0) | ||||
| 		if (find_dir_prefix_int(dirent->d_name, "thread", &tids[i]) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		i++; | ||||
| @ -271,20 +251,17 @@ load_proc(struct ovni_eproc *proc, struct ovni_loom *loom, int index, int pid, c | ||||
| 	/* Sort threads by ascending TID */ | ||||
| 	qsort(tids, proc->nthreads, sizeof(int), compare_int); | ||||
| 
 | ||||
| 	for(size_t i = 0; i < proc->nthreads; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < proc->nthreads; i++) { | ||||
| 		int tid = tids[i]; | ||||
| 
 | ||||
| 		if(snprintf(path, PATH_MAX, "%s/thread.%d", procdir, tid) >= | ||||
| 				PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(path, PATH_MAX, "%s/thread.%d", procdir, tid) >= PATH_MAX) { | ||||
| 			err("snprintf: path too large: %s\n", procdir); | ||||
| 			abort(); | ||||
| 		} | ||||
| 
 | ||||
| 		thread = &proc->thread[i]; | ||||
| 
 | ||||
| 		if(load_thread(thread, proc, i, tid, path) != 0) | ||||
| 		if (load_thread(thread, proc, i, tid, path) != 0) | ||||
| 			return -1; | ||||
| 	} | ||||
| 
 | ||||
| @ -302,27 +279,24 @@ load_loom(struct ovni_loom *loom, char *loomdir) | ||||
| 	DIR *dir; | ||||
| 	struct dirent *dirent; | ||||
| 
 | ||||
| 	if((dir = opendir(loomdir)) == NULL) | ||||
| 	{ | ||||
| 	if ((dir = opendir(loomdir)) == NULL) { | ||||
| 		fprintf(stderr, "opendir %s failed: %s\n", | ||||
| 				loomdir, strerror(errno)); | ||||
| 			loomdir, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	loom->rank_enabled = 0; | ||||
| 	loom->nprocs = count_dir_prefix(dir, "proc"); | ||||
| 
 | ||||
| 	if(loom->nprocs <= 0) | ||||
| 	{ | ||||
| 	if (loom->nprocs <= 0) { | ||||
| 		err("cannot find any process directory in loom %s\n", | ||||
| 				loom->hostname); | ||||
| 			loom->hostname); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	loom->proc = calloc(loom->nprocs, sizeof(struct ovni_eproc)); | ||||
| 
 | ||||
| 	if(loom->proc == NULL) | ||||
| 	{ | ||||
| 	if (loom->proc == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -330,28 +304,24 @@ load_loom(struct ovni_loom *loom, char *loomdir) | ||||
| 	rewinddir(dir); | ||||
| 
 | ||||
| 	i = 0; | ||||
| 	while((dirent = readdir(dir)) != NULL) | ||||
| 	{ | ||||
| 		if(find_dir_prefix_int(dirent->d_name, "proc", &pid) != 0) | ||||
| 	while ((dirent = readdir(dir)) != NULL) { | ||||
| 		if (find_dir_prefix_int(dirent->d_name, "proc", &pid) != 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		sprintf(path, "%s/%s", loomdir, dirent->d_name); | ||||
| 
 | ||||
| 		if(i >= loom->nprocs) | ||||
| 		{ | ||||
| 		if (i >= loom->nprocs) { | ||||
| 			err("more process than expected\n"); | ||||
| 			abort(); | ||||
| 		} | ||||
| 
 | ||||
| 		if(load_proc(&loom->proc[i], loom, i, pid, path) != 0) | ||||
| 		if (load_proc(&loom->proc[i], loom, i, pid, path) != 0) | ||||
| 			return -1; | ||||
| 
 | ||||
| 		i++; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	if(i != loom->nprocs) | ||||
| 	{ | ||||
| 	if (i != loom->nprocs) { | ||||
| 		err("unexpected number of processes\n"); | ||||
| 		abort(); | ||||
| 	} | ||||
| @ -359,15 +329,12 @@ load_loom(struct ovni_loom *loom, char *loomdir) | ||||
| 	closedir(dir); | ||||
| 
 | ||||
| 	/* Ensure all process have the rank, if enabled in any */ | ||||
| 	if(loom->rank_enabled) | ||||
| 	{ | ||||
| 		for(i = 0; i < loom->nprocs; i++) | ||||
| 		{ | ||||
| 	if (loom->rank_enabled) { | ||||
| 		for (i = 0; i < loom->nprocs; i++) { | ||||
| 			struct ovni_eproc *proc = &loom->proc[i]; | ||||
| 			if(proc->rank < 0) | ||||
| 			{ | ||||
| 			if (proc->rank < 0) { | ||||
| 				die("process %d is missing the rank\n", | ||||
| 						proc->pid); | ||||
| 					proc->pid); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @ -388,16 +355,15 @@ loom_to_host(const char *loom_name, char *host, int n) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for(i = 0; i < n; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < n; i++) { | ||||
| 		/* Copy until dot or end */ | ||||
| 		if(loom_name[i] != '.' && loom_name[i] != '\0') | ||||
| 		if (loom_name[i] != '.' && loom_name[i] != '\0') | ||||
| 			host[i] = loom_name[i]; | ||||
| 		else | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	if(i == n) | ||||
| 	if (i == n) | ||||
| 		die("loom host name %s too long\n", loom_name); | ||||
| 
 | ||||
| 	host[i] = '\0'; | ||||
| @ -408,24 +374,21 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir) | ||||
| { | ||||
| 	DIR *dir; | ||||
| 
 | ||||
| 	if((dir = opendir(tracedir)) == NULL) | ||||
| 	{ | ||||
| 	if ((dir = opendir(tracedir)) == NULL) { | ||||
| 		err("opendir %s failed: %s\n", tracedir, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	trace->nlooms = count_dir_prefix(dir, "loom"); | ||||
| 
 | ||||
| 	if(trace->nlooms == 0) | ||||
| 	{ | ||||
| 	if (trace->nlooms == 0) { | ||||
| 		err("cannot find any loom in %s\n", tracedir); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	trace->loom = calloc(trace->nlooms, sizeof(struct ovni_loom)); | ||||
| 
 | ||||
| 	if(trace->loom == NULL) | ||||
| 	{ | ||||
| 	if (trace->loom == NULL) { | ||||
| 		perror("calloc failed\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -435,25 +398,21 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir) | ||||
| 	size_t l = 0; | ||||
| 	struct dirent *dirent; | ||||
| 
 | ||||
| 	while((dirent = readdir(dir)) != NULL) | ||||
| 	{ | ||||
| 	while ((dirent = readdir(dir)) != NULL) { | ||||
| 		struct ovni_loom *loom = &trace->loom[l]; | ||||
| 		const char *loom_name; | ||||
| 		if(find_dir_prefix_str(dirent->d_name, "loom", &loom_name) != 0) | ||||
| 		{ | ||||
| 		if (find_dir_prefix_str(dirent->d_name, "loom", &loom_name) != 0) { | ||||
| 			/* Ignore other files in tracedir */ | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if(l >= trace->nlooms) | ||||
| 		{ | ||||
| 		if (l >= trace->nlooms) { | ||||
| 			err("extra loom detected\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		/* Copy the complete loom directory name to looms */ | ||||
| 		if(snprintf(loom->dname, PATH_MAX, "%s", dirent->d_name) >= PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(loom->dname, PATH_MAX, "%s", dirent->d_name) >= PATH_MAX) { | ||||
| 			err("error: loom name %s too long\n", dirent->d_name); | ||||
| 			return -1; | ||||
| 		} | ||||
| @ -465,30 +424,28 @@ ovni_load_trace(struct ovni_trace *trace, char *tracedir) | ||||
| 
 | ||||
| 	/* Sort the looms, so we get the hostnames in alphanumeric order */ | ||||
| 	qsort(trace->loom, trace->nlooms, sizeof(struct ovni_loom), | ||||
| 			compare_looms); | ||||
| 		compare_looms); | ||||
| 
 | ||||
| 	for(size_t i = 0; i < trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < trace->nlooms; i++) { | ||||
| 		struct ovni_loom *loom = &trace->loom[i]; | ||||
| 		const char *name = NULL; | ||||
| 
 | ||||
| 		if(find_dir_prefix_str(loom->dname, "loom", &name) != 0) | ||||
| 		{ | ||||
| 		if (find_dir_prefix_str(loom->dname, "loom", &name) != 0) { | ||||
| 			err("error: mismatch for loom %s\n", loom->dname); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		loom_to_host(name, loom->hostname, sizeof(loom->hostname)); | ||||
| 
 | ||||
| 		if(snprintf(loom->path, PATH_MAX, "%s/%s", | ||||
| 					tracedir, loom->dname) >= PATH_MAX) | ||||
| 		{ | ||||
| 		if (snprintf(loom->path, PATH_MAX, "%s/%s", | ||||
| 			    tracedir, loom->dname) | ||||
| 			>= PATH_MAX) { | ||||
| 			err("error: loom path %s/%s too long\n", | ||||
| 					tracedir, loom->dname); | ||||
| 				tracedir, loom->dname); | ||||
| 			return -1; | ||||
| 		} | ||||
| 
 | ||||
| 		if(load_loom(loom, loom->path) != 0) | ||||
| 		if (load_loom(loom, loom->path) != 0) | ||||
| 			return -1; | ||||
| 	} | ||||
| 
 | ||||
| @ -500,30 +457,27 @@ check_stream_header(struct ovni_stream *stream) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	if(stream->size < sizeof(struct ovni_stream_header)) | ||||
| 	{ | ||||
| 	if (stream->size < sizeof(struct ovni_stream_header)) { | ||||
| 		err("stream %d: incomplete stream header\n", | ||||
| 				stream->tid); | ||||
| 			stream->tid); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	struct ovni_stream_header *h = | ||||
| 		(struct ovni_stream_header *) stream->buf; | ||||
| 
 | ||||
| 	if(memcmp(h->magic, OVNI_STREAM_MAGIC, 4) != 0) | ||||
| 	{ | ||||
| 	if (memcmp(h->magic, OVNI_STREAM_MAGIC, 4) != 0) { | ||||
| 		char magic[5]; | ||||
| 		memcpy(magic, h->magic, 4); | ||||
| 		magic[4] = '\0'; | ||||
| 		err("stream %d: wrong stream magic '%s' (expected '%s')\n", | ||||
| 				stream->tid, magic, OVNI_STREAM_MAGIC); | ||||
| 			stream->tid, magic, OVNI_STREAM_MAGIC); | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if(h->version != OVNI_STREAM_VERSION) | ||||
| 	{ | ||||
| 	if (h->version != OVNI_STREAM_VERSION) { | ||||
| 		err("stream %d: stream version mismatch %u (expected %u)\n", | ||||
| 				stream->tid, h->version, OVNI_STREAM_VERSION); | ||||
| 			stream->tid, h->version, OVNI_STREAM_VERSION); | ||||
| 		ret = -1; | ||||
| 	} | ||||
| 
 | ||||
| @ -534,15 +488,13 @@ static int | ||||
| load_stream_fd(struct ovni_stream *stream, int fd) | ||||
| { | ||||
| 	struct stat st; | ||||
| 	if(fstat(fd, &st) < 0) | ||||
| 	{ | ||||
| 	if (fstat(fd, &st) < 0) { | ||||
| 		perror("fstat failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Error because it doesn't have the header */ | ||||
| 	if(st.st_size == 0) | ||||
| 	{ | ||||
| 	if (st.st_size == 0) { | ||||
| 		err("stream %d is empty\n", stream->tid); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -550,8 +502,7 @@ load_stream_fd(struct ovni_stream *stream, int fd) | ||||
| 	int prot = PROT_READ | PROT_WRITE; | ||||
| 	stream->buf = mmap(NULL, st.st_size, prot, MAP_PRIVATE, fd, 0); | ||||
| 
 | ||||
| 	if(stream->buf == MAP_FAILED) | ||||
| 	{ | ||||
| 	if (stream->buf == MAP_FAILED) { | ||||
| 		perror("mmap failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -566,31 +517,28 @@ load_stream_buf(struct ovni_stream *stream, struct ovni_ethread *thread) | ||||
| { | ||||
| 	int fd; | ||||
| 
 | ||||
| 	if((fd = open(thread->tracefile, O_RDWR)) == -1) | ||||
| 	{ | ||||
| 	if ((fd = open(thread->tracefile, O_RDWR)) == -1) { | ||||
| 		perror("open failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if(load_stream_fd(stream, fd) != 0) | ||||
| 	if (load_stream_fd(stream, fd) != 0) | ||||
| 		return -1; | ||||
| 
 | ||||
| 	if(check_stream_header(stream) != 0) | ||||
| 	{ | ||||
| 	if (check_stream_header(stream) != 0) { | ||||
| 		err("stream %d: bad header\n", stream->tid); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	stream->offset = sizeof(struct ovni_stream_header); | ||||
| 
 | ||||
| 	if(stream->offset == stream->size) | ||||
| 	if (stream->offset == stream->size) | ||||
| 		stream->active = 0; | ||||
| 	else | ||||
| 		stream->active = 1; | ||||
| 
 | ||||
| 	/* No need to keep the fd open */ | ||||
| 	if(close(fd)) | ||||
| 	{ | ||||
| 	if (close(fd)) { | ||||
| 		perror("close failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| @ -610,14 +558,11 @@ ovni_load_streams(struct ovni_trace *trace) | ||||
| 
 | ||||
| 	trace->nstreams = 0; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 			for(k=0; k<proc->nthreads; k++) | ||||
| 			{ | ||||
| 			for (k = 0; k < proc->nthreads; k++) { | ||||
| 				trace->nstreams++; | ||||
| 			} | ||||
| 		} | ||||
| @ -625,22 +570,18 @@ ovni_load_streams(struct ovni_trace *trace) | ||||
| 
 | ||||
| 	trace->stream = calloc(trace->nstreams, sizeof(struct ovni_stream)); | ||||
| 
 | ||||
| 	if(trace->stream == NULL) | ||||
| 	{ | ||||
| 	if (trace->stream == NULL) { | ||||
| 		perror("calloc failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	err("loaded %ld streams\n", trace->nstreams); | ||||
| 
 | ||||
| 	for(s=0, i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 	for (s = 0, i = 0; i < trace->nlooms; i++) { | ||||
| 		loom = &trace->loom[i]; | ||||
| 		for(j=0; j<loom->nprocs; j++) | ||||
| 		{ | ||||
| 		for (j = 0; j < loom->nprocs; j++) { | ||||
| 			proc = &loom->proc[j]; | ||||
| 			for(k=0; k<proc->nthreads; k++) | ||||
| 			{ | ||||
| 			for (k = 0; k < proc->nthreads; k++) { | ||||
| 				thread = &proc->thread[k]; | ||||
| 				stream = &trace->stream[s++]; | ||||
| 
 | ||||
| @ -652,12 +593,10 @@ ovni_load_streams(struct ovni_trace *trace) | ||||
| 				stream->offset = 0; | ||||
| 				stream->cur_ev = NULL; | ||||
| 
 | ||||
| 				if(load_stream_buf(stream, thread) != 0) | ||||
| 				{ | ||||
| 				if (load_stream_buf(stream, thread) != 0) { | ||||
| 					err("load_stream_buf failed\n"); | ||||
| 					return -1; | ||||
| 				} | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @ -668,10 +607,9 @@ ovni_load_streams(struct ovni_trace *trace) | ||||
| void | ||||
| ovni_free_streams(struct ovni_trace *trace) | ||||
| { | ||||
| 	for(size_t i = 0; i < trace->nstreams; i++) | ||||
| 	{ | ||||
| 	for (size_t i = 0; i < trace->nstreams; i++) { | ||||
| 		struct ovni_stream *stream = &trace->stream[i]; | ||||
| 		if(munmap(stream->buf, stream->size) != 0) | ||||
| 		if (munmap(stream->buf, stream->size) != 0) | ||||
| 			die("munmap stream failed: %s\n", strerror(errno)); | ||||
| 	} | ||||
| 
 | ||||
| @ -683,10 +621,8 @@ ovni_free_trace(struct ovni_trace *trace) | ||||
| { | ||||
| 	size_t i, j; | ||||
| 
 | ||||
| 	for(i=0; i<trace->nlooms; i++) | ||||
| 	{ | ||||
| 		for(j=0; j<trace->loom[i].nprocs; j++) | ||||
| 		{ | ||||
| 	for (i = 0; i < trace->nlooms; i++) { | ||||
| 		for (j = 0; j < trace->loom[i].nprocs; j++) { | ||||
| 			free(trace->loom[i].proc[j].thread); | ||||
| 		} | ||||
| 
 | ||||
| @ -699,23 +635,21 @@ ovni_free_trace(struct ovni_trace *trace) | ||||
| int | ||||
| ovni_load_next_event(struct ovni_stream *stream) | ||||
| { | ||||
| 	if(stream->active == 0) | ||||
| 	{ | ||||
| 	if (stream->active == 0) { | ||||
| 		dbg("stream is inactive, cannot load more events\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Only step the offset if we have load an event */ | ||||
| 	if(stream->cur_ev != NULL) | ||||
| 	if (stream->cur_ev != NULL) | ||||
| 		stream->offset += ovni_ev_size(stream->cur_ev); | ||||
| 
 | ||||
| 	/* It cannot overflow, otherwise we are reading garbage */ | ||||
| 	if(stream->offset > stream->size) | ||||
| 	if (stream->offset > stream->size) | ||||
| 		die("ovni_load_next_event: stream offset exceeds size\n"); | ||||
| 
 | ||||
| 	/* We have reached the end */ | ||||
| 	if(stream->offset == stream->size) | ||||
| 	{ | ||||
| 	if (stream->offset == stream->size) { | ||||
| 		stream->active = 0; | ||||
| 		stream->cur_ev = NULL; | ||||
| 		dbg("stream %d runs out of events\n", stream->tid); | ||||
|  | ||||
							
								
								
									
										2
									
								
								trace.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								trace.h
									
									
									
									
									
								
							| @ -4,8 +4,8 @@ | ||||
| #ifndef OVNI_TRACE_H | ||||
| #define OVNI_TRACE_H | ||||
| 
 | ||||
| #include "ovni.h" | ||||
| #include "emu.h" | ||||
| #include "ovni.h" | ||||
| 
 | ||||
| int ovni_load_next_event(struct ovni_stream *stream); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user