Initial commit
This commit is contained in:
		
						commit
						1092faebf3
					
				
							
								
								
									
										16
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | CFLAGS=-g -O0 -fPIC | ||||||
|  | 
 | ||||||
|  | CFLAGS+=-fsanitize=address | ||||||
|  | LDFLAGS+=-fsanitize=address | ||||||
|  | 
 | ||||||
|  | BIN=dump libovni.a | ||||||
|  | 
 | ||||||
|  | all: $(BIN) | ||||||
|  | 
 | ||||||
|  | libovni.a: ovni.o | ||||||
|  | 	ar -crs $@ $^ | ||||||
|  | 
 | ||||||
|  | dump: ovni.o dump.o | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	rm -f *.o $(BIN) | ||||||
							
								
								
									
										51
									
								
								def.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								def.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | #ifndef OVNI_DEF_H | ||||||
|  | #define OVNI_DEF_H | ||||||
|  | 
 | ||||||
|  | #define MAX_CPU 256 | ||||||
|  | #define MAX_PROC 32 | ||||||
|  | #define MAX_LOOM 4 | ||||||
|  | #define TRACEDIR "ovni" | ||||||
|  | 
 | ||||||
|  | struct ovnithr { | ||||||
|  | 	int cpu; | ||||||
|  | 	uint64_t clockvalue; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovniproc { | ||||||
|  | 	int proc; | ||||||
|  | 	int loom; | ||||||
|  | 	int ncpus; | ||||||
|  | 	FILE *cpustream[MAX_CPU]; | ||||||
|  | 	atomic_int opened[MAX_CPU]; | ||||||
|  | 	char dir[PATH_MAX]; | ||||||
|  | 	clockid_t clockid; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovniloom { | ||||||
|  | 	int nprocs; | ||||||
|  | 	struct ovniproc proc[MAX_PROC]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct __attribute__((__packed__)) ovnievent { | ||||||
|  | 	uint64_t clock; | ||||||
|  | 	uint8_t fsm; | ||||||
|  | 	uint8_t event; | ||||||
|  | 	int32_t data; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovnistream { | ||||||
|  | 	FILE *f; | ||||||
|  | 	int cpu; | ||||||
|  | 	int loaded; | ||||||
|  | 	int active; | ||||||
|  | 	struct ovnievent last; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | struct ovnitrace { | ||||||
|  | 	int nlooms; | ||||||
|  | 	struct ovniloom loom[MAX_LOOM]; | ||||||
|  | 	int nstreams; | ||||||
|  | 	struct ovnistream *stream; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* OVNI_DEF_H */ | ||||||
							
								
								
									
										289
									
								
								dump.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										289
									
								
								dump.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,289 @@ | |||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <linux/limits.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <sys/stat.h> | ||||||
|  | #include <stdatomic.h> | ||||||
|  | 
 | ||||||
|  | #include "def.h" | ||||||
|  | 
 | ||||||
|  | int load_proc(struct ovniproc *proc, char *procdir) | ||||||
|  | { | ||||||
|  | 	FILE *f; | ||||||
|  | 	int cpu; | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 
 | ||||||
|  | 	for(cpu=0; cpu<MAX_CPU; cpu++) | ||||||
|  | 	{ | ||||||
|  | 		sprintf(path, "%s/cpu.%d", procdir, cpu); | ||||||
|  | 		f = fopen(path, "r"); | ||||||
|  | 
 | ||||||
|  | 		if(f == NULL) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		proc->cpustream[cpu] = f; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	proc->ncpus = cpu; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int load_loom(struct ovniloom *loom, char *loomdir) | ||||||
|  | { | ||||||
|  | 	int proc; | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 	struct stat st; | ||||||
|  | 
 | ||||||
|  | 	for(proc=0; proc<MAX_PROC; proc++) | ||||||
|  | 	{ | ||||||
|  | 		sprintf(path, "%s/proc.%d", loomdir, proc); | ||||||
|  | 
 | ||||||
|  | 		if(stat(path, &st) != 0) | ||||||
|  | 		{ | ||||||
|  | 			/* Proc numbers exausted */ | ||||||
|  | 			if(errno == ENOENT) | ||||||
|  | 				break; | ||||||
|  | 
 | ||||||
|  | 			fprintf(stderr, "cannot stat %s: %s\n", path, | ||||||
|  | 					strerror(errno)); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if(!S_ISDIR(st.st_mode)) | ||||||
|  | 		{ | ||||||
|  | 			fprintf(stderr, "not a dir %s\n", path); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if(load_proc(&loom->proc[proc], path)) | ||||||
|  | 			return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	loom->nprocs = proc; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int load_trace(struct ovnitrace *trace, char *tracedir) | ||||||
|  | { | ||||||
|  | 	int loom, nlooms; | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 
 | ||||||
|  | 	/* TODO: For now only one loom */ | ||||||
|  | 	nlooms = 1; | ||||||
|  | 	loom = 0; | ||||||
|  | 
 | ||||||
|  | 	sprintf(path, "%s/loom.%d", tracedir, loom); | ||||||
|  | 
 | ||||||
|  | 	if(load_loom(&trace->loom[loom], path)) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	trace->nlooms = nlooms; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Populates the streams in a single array */ | ||||||
|  | int load_streams(struct ovnitrace *trace) | ||||||
|  | { | ||||||
|  | 	int i, j, k, s; | ||||||
|  | 	struct ovniloom *loom; | ||||||
|  | 	struct ovniproc *proc; | ||||||
|  | 	struct ovnistream *stream; | ||||||
|  | 
 | ||||||
|  | 	trace->nstreams = 0; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<trace->nlooms; i++) | ||||||
|  | 	{ | ||||||
|  | 		loom = &trace->loom[i]; | ||||||
|  | 		for(j=0; j<loom->nprocs; j++) | ||||||
|  | 		{ | ||||||
|  | 			proc = &loom->proc[j]; | ||||||
|  | 			for(k=0; k<proc->ncpus; k++) | ||||||
|  | 			{ | ||||||
|  | 				trace->nstreams++; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	trace->stream = calloc(trace->nstreams, sizeof(struct ovnistream)); | ||||||
|  | 
 | ||||||
|  | 	if(trace->stream == NULL) | ||||||
|  | 	{ | ||||||
|  | 		perror("calloc"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fprintf(stderr, "loaded %d streams\n", trace->nstreams); | ||||||
|  | 
 | ||||||
|  | 	for(s=0, i=0; i<trace->nlooms; i++) | ||||||
|  | 	{ | ||||||
|  | 		loom = &trace->loom[i]; | ||||||
|  | 		for(j=0; j<loom->nprocs; j++) | ||||||
|  | 		{ | ||||||
|  | 			proc = &loom->proc[j]; | ||||||
|  | 			for(k=0; k<proc->ncpus; k++) | ||||||
|  | 			{ | ||||||
|  | 				stream = &trace->stream[s++]; | ||||||
|  | 				stream->f = proc->cpustream[k]; | ||||||
|  | 				stream->cpu = k; | ||||||
|  | 				stream->active = 1; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int load_first_event(struct ovnitrace *trace) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	struct ovnistream *stream; | ||||||
|  | 	struct ovnievent *ev; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<trace->nstreams; i++) | ||||||
|  | 	{ | ||||||
|  | 		stream = &trace->stream[i]; | ||||||
|  | 		ev = &stream->last; | ||||||
|  | 		if(fread(ev, sizeof(*ev), 1, stream->f) != 1) | ||||||
|  | 		{ | ||||||
|  | 			fprintf(stderr, "failed to read and event\n"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		fprintf(stderr, "ev clock %u\n", ev->clock); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void emit(struct ovnievent *ev, int cpu) | ||||||
|  | { | ||||||
|  | 	static uint64_t lastclock = 0; | ||||||
|  | 	uint64_t delta; | ||||||
|  | 
 | ||||||
|  | 	delta = ev->clock - lastclock; | ||||||
|  | 
 | ||||||
|  | 	printf("%d %c %c %d %020lu (+%lu) ns\n", | ||||||
|  | 			cpu, ev->fsm, ev->event, ev->data, ev->clock, delta); | ||||||
|  | 
 | ||||||
|  | 	lastclock = ev->clock; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void load_next_event(struct ovnistream *stream) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 	size_t n; | ||||||
|  | 	struct ovnievent *ev; | ||||||
|  | 
 | ||||||
|  | 	if(!stream->active) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	ev = &stream->last; | ||||||
|  | 	if((n = fread(ev, sizeof(*ev), 1, stream->f)) != 1) | ||||||
|  | 	{ | ||||||
|  | 		//fprintf(stderr, "failed to read an event, n=%ld\n", n);
 | ||||||
|  | 		stream->active = 0; | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	stream->active = 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dump_events(struct ovnitrace *trace) | ||||||
|  | { | ||||||
|  | 	int i, f; | ||||||
|  | 	uint64_t minclock, lastclock; | ||||||
|  | 	struct ovnievent *ev; | ||||||
|  | 	struct ovnistream *stream; | ||||||
|  | 
 | ||||||
|  | 	/* Load events */ | ||||||
|  | 	for(i=0; i<trace->nstreams; i++) | ||||||
|  | 	{ | ||||||
|  | 		stream = &trace->stream[i]; | ||||||
|  | 		load_next_event(stream); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	lastclock = 0; | ||||||
|  | 
 | ||||||
|  | 	while(1) | ||||||
|  | 	{ | ||||||
|  | 		f = -1; | ||||||
|  | 		minclock = 0; | ||||||
|  | 
 | ||||||
|  | 		/* Select next event based on the clock */ | ||||||
|  | 		for(i=0; i<trace->nstreams; i++) | ||||||
|  | 		{ | ||||||
|  | 			stream = &trace->stream[i]; | ||||||
|  | 
 | ||||||
|  | 			if(!stream->active) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			ev = &stream->last; | ||||||
|  | 			if(f < 0 || ev->clock < minclock) | ||||||
|  | 			{ | ||||||
|  | 				f = i; | ||||||
|  | 				minclock = ev->clock; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		//fprintf(stderr, "f=%d minclock=%u\n", f, minclock);
 | ||||||
|  | 
 | ||||||
|  | 		if(f < 0) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 		stream = &trace->stream[f]; | ||||||
|  | 
 | ||||||
|  | 		if(lastclock >= stream->last.clock) | ||||||
|  | 		{ | ||||||
|  | 			fprintf(stderr, "warning: backwards jump in time\n"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/* Emit current event */ | ||||||
|  | 		emit(&stream->last, stream->cpu); | ||||||
|  | 
 | ||||||
|  | 		lastclock = stream->last.clock; | ||||||
|  | 
 | ||||||
|  | 		/* Read the next one */ | ||||||
|  | 		load_next_event(stream); | ||||||
|  | 
 | ||||||
|  | 		/* Unset the index */ | ||||||
|  | 		f = -1; | ||||||
|  | 		minclock = 0; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void free_streams(struct ovnitrace *trace) | ||||||
|  | { | ||||||
|  | 	free(trace->stream); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int main(int argc, char *argv[]) | ||||||
|  | { | ||||||
|  | 	char *tracedir; | ||||||
|  | 	struct ovnitrace trace; | ||||||
|  | 
 | ||||||
|  | 	if(argc != 2) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "missing tracedir\n"); | ||||||
|  | 		exit(EXIT_FAILURE); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tracedir = argv[1]; | ||||||
|  | 
 | ||||||
|  | 	if(load_trace(&trace, tracedir)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	if(load_streams(&trace)) | ||||||
|  | 		return 1; | ||||||
|  | 
 | ||||||
|  | 	dump_events(&trace); | ||||||
|  | 
 | ||||||
|  | 	free_streams(&trace); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
							
								
								
									
										230
									
								
								ovni.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								ovni.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,230 @@ | |||||||
|  | #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 <stdatomic.h> | ||||||
|  | 
 | ||||||
|  | #include "ovni.h" | ||||||
|  | #include "def.h" | ||||||
|  | 
 | ||||||
|  | /* Data per process */ | ||||||
|  | struct ovniproc ovniproc = {0}; | ||||||
|  | 
 | ||||||
|  | /* Data per thread */ | ||||||
|  | _Thread_local struct ovnithr ovnithr = {0}; | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | create_trace_dirs(char *tracedir, int loom, int proc) | ||||||
|  | { | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 
 | ||||||
|  | 	fprintf(stderr, "create trace dirs for loom=%d, proc=%d\n", | ||||||
|  | 			loom, proc); | ||||||
|  | 
 | ||||||
|  | 	snprintf(path, PATH_MAX, "%s", tracedir); | ||||||
|  | 
 | ||||||
|  | 	if(mkdir(path, 0755)) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "mkdir %s: %s\n", path, strerror(errno)); | ||||||
|  | 		//return -1;
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	snprintf(path, PATH_MAX, "%s/loom.%d", tracedir, loom); | ||||||
|  | 
 | ||||||
|  | 	if(mkdir(path, 0755)) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "mkdir %s: %s\n", path, strerror(errno)); | ||||||
|  | 		//return -1;
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	snprintf(ovniproc.dir, PATH_MAX, "%s/loom.%d/proc.%d", tracedir, loom, proc); | ||||||
|  | 
 | ||||||
|  | 	if(mkdir(ovniproc.dir, 0755)) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "mkdir %s: %s\n", ovniproc.dir, strerror(errno)); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | create_trace_streams(int ncpus) | ||||||
|  | { | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<ncpus; i++) | ||||||
|  | 	{ | ||||||
|  | 		snprintf(path, PATH_MAX, "%s/cpu.%d", ovniproc.dir, i); | ||||||
|  | 		if((ovniproc.cpustream[i] = fopen(path, "w")) == NULL) | ||||||
|  | 		{ | ||||||
|  | 			perror("fopen"); | ||||||
|  | 			return -1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | ovni_init(int loom, int proc, int ncpus) | ||||||
|  | { | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	fprintf(stderr, "ovni_init\n"); | ||||||
|  | 	memset(&ovniproc, 0, sizeof(ovniproc)); | ||||||
|  | 	memset(&ovnithr, 0, sizeof(ovnithr)); | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<MAX_CPU; i++) | ||||||
|  | 		ovniproc.opened[i] = ATOMIC_VAR_INIT(0); | ||||||
|  | 
 | ||||||
|  | 	ovniproc.loom = loom; | ||||||
|  | 	ovniproc.proc = proc; | ||||||
|  | 	ovniproc.ncpus = ncpus; | ||||||
|  | 
 | ||||||
|  | 	/* By default we use the monotonic clock */ | ||||||
|  | 	ovniproc.clockid = CLOCK_MONOTONIC; | ||||||
|  | 
 | ||||||
|  | 	if(create_trace_dirs(TRACEDIR, loom, proc)) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	if(create_trace_streams(ncpus)) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_cpu_set(int cpu) | ||||||
|  | { | ||||||
|  | 	ovnithr.cpu = cpu; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Sets the current time so that all subsequent events have the new
 | ||||||
|  |  * timestamp */ | ||||||
|  | int | ||||||
|  | ovni_clock_update() | ||||||
|  | { | ||||||
|  | 	struct timespec tp; | ||||||
|  | 	uint64_t ns = 1000LL * 1000LL * 1000LL; | ||||||
|  | 	uint64_t raw; | ||||||
|  | 
 | ||||||
|  | 	if(clock_gettime(ovniproc.clockid, &tp)) | ||||||
|  | 		return -1; | ||||||
|  | 
 | ||||||
|  | 	raw = tp.tv_sec * ns + tp.tv_nsec; | ||||||
|  | 	//raw = raw >> 6;
 | ||||||
|  | 	ovnithr.clockvalue = (uint64_t) raw; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | //static void
 | ||||||
|  | //pack_int64(uint8_t **q, int64_t n)
 | ||||||
|  | //{
 | ||||||
|  | //	uint8_t *p = *q;
 | ||||||
|  | //
 | ||||||
|  | //	*p++ = (n >>  0) & 0xff;
 | ||||||
|  | //	*p++ = (n >>  8) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 16) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 24) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 32) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 40) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 48) & 0xff;
 | ||||||
|  | //	*p++ = (n >> 56) & 0xff;
 | ||||||
|  | //
 | ||||||
|  | //	*q = p;
 | ||||||
|  | //}
 | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | pack_uint32(uint8_t **q, uint32_t n) | ||||||
|  | { | ||||||
|  | 	uint8_t *p = *q; | ||||||
|  | 
 | ||||||
|  | 	*p++ = (n >>  0) & 0xff; | ||||||
|  | 	*p++ = (n >>  8) & 0xff; | ||||||
|  | 	*p++ = (n >> 16) & 0xff; | ||||||
|  | 	*p++ = (n >> 24) & 0xff; | ||||||
|  | 
 | ||||||
|  | 	*q = p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | pack_uint8(uint8_t **q, uint8_t n) | ||||||
|  | { | ||||||
|  | 	uint8_t *p = *q; | ||||||
|  | 
 | ||||||
|  | 	*p++ = n; | ||||||
|  | 
 | ||||||
|  | 	*q = p; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | ovni_write(uint8_t *buf, size_t size) | ||||||
|  | { | ||||||
|  | 	FILE *f; | ||||||
|  | 	int i, j; | ||||||
|  | 
 | ||||||
|  | 	printf("writing %ld bytes in cpu=%d\n", size, ovnithr.cpu); | ||||||
|  | 
 | ||||||
|  | 	for(i=0; i<size; i+=16) | ||||||
|  | 	{ | ||||||
|  | 		for(j=0; j<16 && i+j < size; j++) | ||||||
|  | 		{ | ||||||
|  | 			printf("%02x ", buf[i+j]); | ||||||
|  | 		} | ||||||
|  | 		printf("\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	f = ovniproc.cpustream[ovnithr.cpu]; | ||||||
|  | 
 | ||||||
|  | 	if(fwrite(buf, 1, size, f) != size) | ||||||
|  | 	{ | ||||||
|  | 		perror("fwrite"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fflush(f); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int | ||||||
|  | ovni_ev(uint8_t fsm, uint8_t event, int32_t data) | ||||||
|  | { | ||||||
|  | 	struct ovnievent ev; | ||||||
|  | 
 | ||||||
|  | 	ev.clock = ovnithr.clockvalue; | ||||||
|  | 	ev.fsm = fsm; | ||||||
|  | 	ev.event = event; | ||||||
|  | 	ev.data = data; | ||||||
|  | 
 | ||||||
|  | 	return ovni_write((uint8_t *) &ev, sizeof(ev)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | ovni_ev_worker(uint8_t fsm, uint8_t event, int32_t data) | ||||||
|  | { | ||||||
|  | 	return ovni_ev(fsm, event, data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_stream_open(int cpu) | ||||||
|  | { | ||||||
|  | 	if(atomic_fetch_add(&ovniproc.opened[cpu], 1) + 1 > 1) | ||||||
|  | 	{ | ||||||
|  | 		fprintf(stderr, "the stream for cpu.%d is already in use\n", cpu); | ||||||
|  | 		abort(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_stream_close(int cpu) | ||||||
|  | { | ||||||
|  | 	atomic_fetch_sub(&ovniproc.opened[cpu], 1); | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								ovni.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ovni.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | #ifndef OVNI_H | ||||||
|  | #define OVNI_H | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | ovni_init(int loom, int proc, int ncpus); | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | ovni_clock_update(); | ||||||
|  | 
 | ||||||
|  | int | ||||||
|  | ovni_ev_worker(uint8_t fsm, uint8_t event, int32_t data); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_cpu_set(int cpu); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_stream_open(int cpu); | ||||||
|  | 
 | ||||||
|  | void | ||||||
|  | ovni_stream_close(int cpu); | ||||||
|  | 
 | ||||||
|  | #endif /* OVNI_H */ | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user