Only allow and emit state transitions
Fixes the ghost events shown in the PRV trace. Only transitions to a different state are allowed now.
This commit is contained in:
		
							parent
							
								
									78f5db4bce
								
							
						
					
					
						commit
						557371e836
					
				
							
								
								
									
										54
									
								
								chan.c
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								chan.c
									
									
									
									
									
								
							@ -37,15 +37,17 @@ chan_init(struct ovni_chan *chan, enum chan_track track, int row, int type, FILE
 | 
				
			|||||||
	chan->row = row;
 | 
						chan->row = row;
 | 
				
			||||||
	chan->dirty = 0;
 | 
						chan->dirty = 0;
 | 
				
			||||||
	chan->track = track;
 | 
						chan->track = track;
 | 
				
			||||||
 | 
						chan->lastst = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
mark_dirty(struct ovni_chan *chan)
 | 
					mark_dirty(struct ovni_chan *chan, enum chan_dirty dirty)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	assert(chan->dirty == 0);
 | 
						assert(chan->dirty == CHAN_CLEAN);
 | 
				
			||||||
 | 
						assert(dirty != CHAN_CLEAN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dbg("adding dirty chan %d to list\n", chan->id);
 | 
						dbg("adding dirty chan %d to list\n", chan->id);
 | 
				
			||||||
	chan->dirty = 1;
 | 
						chan->dirty = dirty;
 | 
				
			||||||
	DL_APPEND(*chan->update_list, chan);
 | 
						DL_APPEND(*chan->update_list, chan);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -75,7 +77,7 @@ chan_th_init(struct ovni_ethread *th,
 | 
				
			|||||||
	chan->enabled = enabled;
 | 
						chan->enabled = enabled;
 | 
				
			||||||
	chan->stack[chan->n++] = init_st;
 | 
						chan->stack[chan->n++] = init_st;
 | 
				
			||||||
	if(dirty)
 | 
						if(dirty)
 | 
				
			||||||
		mark_dirty(chan);
 | 
							mark_dirty(chan, CHAN_DIRTY_ACTIVE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
@ -104,7 +106,7 @@ chan_cpu_init(struct ovni_cpu *cpu,
 | 
				
			|||||||
	chan->enabled = enabled;
 | 
						chan->enabled = enabled;
 | 
				
			||||||
	chan->stack[chan->n++] = init_st;
 | 
						chan->stack[chan->n++] = init_st;
 | 
				
			||||||
	if(dirty)
 | 
						if(dirty)
 | 
				
			||||||
		mark_dirty(chan);
 | 
							mark_dirty(chan, CHAN_DIRTY_ACTIVE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@ -139,7 +141,7 @@ chan_enable(struct ovni_chan *chan, int enabled)
 | 
				
			|||||||
	/* Only append if not dirty */
 | 
						/* Only append if not dirty */
 | 
				
			||||||
	if(!chan->dirty)
 | 
						if(!chan->dirty)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		mark_dirty(chan);
 | 
							mark_dirty(chan, CHAN_DIRTY_ACTIVE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -179,7 +181,7 @@ chan_set(struct ovni_chan *chan, int st)
 | 
				
			|||||||
	/* Only append if not dirty */
 | 
						/* Only append if not dirty */
 | 
				
			||||||
	if(!chan->dirty)
 | 
						if(!chan->dirty)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		mark_dirty(chan);
 | 
							mark_dirty(chan, CHAN_DIRTY_VALUE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -215,7 +217,7 @@ chan_push(struct ovni_chan *chan, int st)
 | 
				
			|||||||
	chan->stack[chan->n++] = st;
 | 
						chan->stack[chan->n++] = st;
 | 
				
			||||||
	chan->t = *chan->clock;
 | 
						chan->t = *chan->clock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mark_dirty(chan);
 | 
						mark_dirty(chan, CHAN_DIRTY_VALUE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
@ -248,7 +250,7 @@ chan_pop(struct ovni_chan *chan, int expected_st)
 | 
				
			|||||||
	chan->n--;
 | 
						chan->n--;
 | 
				
			||||||
	chan->t = *chan->clock;
 | 
						chan->t = *chan->clock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mark_dirty(chan);
 | 
						mark_dirty(chan, CHAN_DIRTY_VALUE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return st;
 | 
						return st;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -267,7 +269,7 @@ chan_ev(struct ovni_chan *chan, int ev)
 | 
				
			|||||||
	chan->ev = ev;
 | 
						chan->ev = ev;
 | 
				
			||||||
	chan->t = *chan->clock;
 | 
						chan->t = *chan->clock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mark_dirty(chan);
 | 
						mark_dirty(chan, CHAN_DIRTY_VALUE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
@ -283,6 +285,32 @@ chan_get_st(struct ovni_chan *chan)
 | 
				
			|||||||
	return chan->stack[chan->n-1];
 | 
						return chan->stack[chan->n-1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					emit(struct ovni_chan *chan, int64_t t, int state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						assert(chan->dirty != CHAN_CLEAN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* 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)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* TODO: Print the raw clock of the offending event */
 | 
				
			||||||
 | 
							err("chan: id=%d cannot emit the same state %d twice\n",
 | 
				
			||||||
 | 
									chan->id, state);
 | 
				
			||||||
 | 
							abort();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(chan->lastst != state)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							prv_ev(chan->prv, chan->row, t, chan->type, state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							chan->lastst = state;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
emit_ev(struct ovni_chan *chan)
 | 
					emit_ev(struct ovni_chan *chan)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -294,8 +322,8 @@ emit_ev(struct ovni_chan *chan)
 | 
				
			|||||||
	new = chan->ev;
 | 
						new = chan->ev;
 | 
				
			||||||
	last = chan_get_st(chan);
 | 
						last = chan_get_st(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prv_ev(chan->prv, chan->row, chan->t-1, chan->type, new);
 | 
						emit(chan, chan->t-1, new);
 | 
				
			||||||
	prv_ev(chan->prv, chan->row, chan->t, chan->type, last);
 | 
						emit(chan, chan->t, last);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chan->ev = -1;
 | 
						chan->ev = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -307,7 +335,7 @@ emit_st(struct ovni_chan *chan)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	st = chan_get_st(chan);
 | 
						st = chan_get_st(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	prv_ev(chan->prv, chan->row, chan->t, chan->type, st);
 | 
						emit(chan, chan->t, st);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Emits either the current state or punctual event in the PRV file */
 | 
					/* Emits either the current state or punctual event in the PRV file */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								emu.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								emu.c
									
									
									
									
									
								
							@ -82,7 +82,7 @@ print_cur_ev(struct ovni_emu *emu)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
 | 
					cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int th_enabled, cpu_enabled;
 | 
						int th_enabled, cpu_enabled, st;
 | 
				
			||||||
	struct ovni_chan *th_chan;
 | 
						struct ovni_chan *th_chan;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	assert(th);
 | 
						assert(th);
 | 
				
			||||||
@ -112,7 +112,9 @@ cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
 | 
				
			|||||||
	if(th_enabled && cpu_enabled)
 | 
						if(th_enabled && cpu_enabled)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Both enabled: simply follow the same value */
 | 
							/* Both enabled: simply follow the same value */
 | 
				
			||||||
		chan_set(cpu_chan, chan_get_st(th_chan));
 | 
							st = chan_get_st(th_chan);
 | 
				
			||||||
 | 
							if(chan_get_st(cpu_chan) != st)
 | 
				
			||||||
 | 
								chan_set(cpu_chan, st);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if(th_enabled && !cpu_enabled)
 | 
						else if(th_enabled && !cpu_enabled)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@ -192,7 +194,8 @@ emu_cpu_update_chan(struct ovni_cpu *cpu, struct ovni_chan *cpu_chan)
 | 
				
			|||||||
		if(!chan_is_enabled(cpu_chan))
 | 
							if(!chan_is_enabled(cpu_chan))
 | 
				
			||||||
			chan_enable(cpu_chan, 1);
 | 
								chan_enable(cpu_chan, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chan_set(cpu_chan, ST_TOO_MANY_TH);
 | 
							if(chan_get_st(cpu_chan) != ST_TOO_MANY_TH)
 | 
				
			||||||
 | 
								chan_set(cpu_chan, ST_TOO_MANY_TH);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								emu.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								emu.h
									
									
									
									
									
								
							@ -170,6 +170,16 @@ enum chan_to_prv_type {
 | 
				
			|||||||
	CHAN_CPU = 2,
 | 
						CHAN_CPU = 2,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum chan_dirty {
 | 
				
			||||||
 | 
						CHAN_CLEAN = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The channel is dirty because it has been enabled or disabled */
 | 
				
			||||||
 | 
						CHAN_DIRTY_ACTIVE = 1,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* The channel is dirty because it changed the state */
 | 
				
			||||||
 | 
						CHAN_DIRTY_VALUE = 2,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Same order as `enum chan` */
 | 
					/* Same order as `enum chan` */
 | 
				
			||||||
static const int chan_to_prvtype[CHAN_MAX][3] = {
 | 
					static const int chan_to_prvtype[CHAN_MAX][3] = {
 | 
				
			||||||
	/* Channel		TH  CPU */
 | 
						/* Channel		TH  CPU */
 | 
				
			||||||
@ -212,6 +222,9 @@ struct ovni_chan {
 | 
				
			|||||||
	/* What state should be shown in errors */
 | 
						/* What state should be shown in errors */
 | 
				
			||||||
	int badst;
 | 
						int badst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Last state emitted (-1 otherwise) */
 | 
				
			||||||
 | 
						int lastst;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Punctual event: -1 if not used */
 | 
						/* Punctual event: -1 if not used */
 | 
				
			||||||
	int ev;
 | 
						int ev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -227,8 +240,8 @@ struct ovni_chan {
 | 
				
			|||||||
	/* Paraver row */
 | 
						/* Paraver row */
 | 
				
			||||||
	int row;
 | 
						int row;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 1 if channel needs flush to PRV */
 | 
						/* Type of dirty */
 | 
				
			||||||
	int dirty;
 | 
						enum chan_dirty dirty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Where should the events be written to? */
 | 
						/* Where should the events be written to? */
 | 
				
			||||||
	FILE *prv;
 | 
						FILE *prv;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user