Update subsystem on nested tasks
Also check the return value of update_task_channels().
This commit is contained in:
		
							parent
							
								
									10de4c8f09
								
							
						
					
					
						commit
						e22e6a21e0
					
				@ -76,31 +76,31 @@ static int
 | 
				
			|||||||
chan_task_stopped(struct emu *emu)
 | 
					chan_task_stopped(struct emu *emu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
						struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
				
			||||||
 | 
						struct chan *ch = th->m.ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct value null = value_null();
 | 
						struct value null = value_null();
 | 
				
			||||||
	if (chan_set(&th->m.ch[CH_TASKID], null) != 0) {
 | 
						if (chan_set(&ch[CH_TASKID], null) != 0) {
 | 
				
			||||||
		err("chan_set taskid failed");
 | 
							err("chan_set taskid failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (chan_set(&th->m.ch[CH_TYPE], null) != 0) {
 | 
						if (chan_set(&ch[CH_TYPE], null) != 0) {
 | 
				
			||||||
		err("chan_set type failed");
 | 
							err("chan_set type failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (chan_set(&th->m.ch[CH_APPID], null) != 0) {
 | 
						if (chan_set(&ch[CH_APPID], null) != 0) {
 | 
				
			||||||
		err("chan_set appid failed");
 | 
							err("chan_set appid failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct proc *proc = emu->proc;
 | 
						struct proc *proc = emu->proc;
 | 
				
			||||||
	if (proc->rank >= 0) {
 | 
						if (proc->rank >= 0) {
 | 
				
			||||||
		if (chan_set(&th->m.ch[CH_RANK], null) != 0) {
 | 
							if (chan_set(&ch[CH_RANK], null) != 0) {
 | 
				
			||||||
			err("chan_set rank failed");
 | 
								err("chan_set rank failed");
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* FIXME: Do we need this transition? */
 | 
						if (chan_pop(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
 | 
				
			||||||
	if (chan_pop(&th->m.ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
 | 
					 | 
				
			||||||
		err("chan_pop subsystem failed");
 | 
							err("chan_pop subsystem failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -156,10 +156,10 @@ chan_task_running(struct emu *emu, struct task *task)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
chan_task_switch(struct emu *emu,
 | 
					chan_task_switch(struct emu *emu, struct task *prev, struct task *next, char tr)
 | 
				
			||||||
		struct task *prev, struct task *next)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
						struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
				
			||||||
 | 
						struct chan *ch = th->m.ch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!prev || !next) {
 | 
						if (!prev || !next) {
 | 
				
			||||||
		err("cannot switch to or from a NULL task");
 | 
							err("cannot switch to or from a NULL task");
 | 
				
			||||||
@ -188,18 +188,32 @@ chan_task_switch(struct emu *emu,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* No need to change the rank or app ID as we will switch 
 | 
						/* No need to change the rank or app ID as we will switch 
 | 
				
			||||||
	 * to tasks from same thread */
 | 
						 * to tasks from same thread */
 | 
				
			||||||
	if (chan_set(&th->m.ch[CH_TASKID], value_int64(next->id)) != 0) {
 | 
						if (chan_set(&ch[CH_TASKID], value_int64(next->id)) != 0) {
 | 
				
			||||||
		err("chan_set taskid failed");
 | 
							err("chan_set taskid failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* TODO: test when switching to another task with the same type. We
 | 
						/* TODO: test when switching to another task with the same type. We
 | 
				
			||||||
	 * should emit the same type state value as previous task. */
 | 
						 * should emit the same type state value as previous task. */
 | 
				
			||||||
	if (chan_set(&th->m.ch[CH_TYPE], value_int64(next->type->gid)) != 0) {
 | 
						if (chan_set(&ch[CH_TYPE], value_int64(next->type->gid)) != 0) {
 | 
				
			||||||
		err("chan_set type failed");
 | 
							err("chan_set type failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Update the subsystem depending if we are pushing (X) or
 | 
				
			||||||
 | 
						 * poping (E) a task from the stack */
 | 
				
			||||||
 | 
						if (tr == 'X') {
 | 
				
			||||||
 | 
							if (chan_push(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
 | 
				
			||||||
 | 
								err("chan_push subsystem failed");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (tr == 'E') {
 | 
				
			||||||
 | 
							if (chan_pop(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) {
 | 
				
			||||||
 | 
								err("chan_pop subsystem failed");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -275,8 +289,7 @@ expand_transition_value(struct emu *emu, int was_running, int runs_now, char *tr
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
update_task_channels(struct emu *emu,
 | 
					update_task_channels(struct emu *emu, char tr, struct task *prev, struct task *next)
 | 
				
			||||||
		char tr, struct task *prev, struct task *next)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	switch (tr) {
 | 
						switch (tr) {
 | 
				
			||||||
@ -291,7 +304,7 @@ update_task_channels(struct emu *emu,
 | 
				
			|||||||
			/* Additional nested transitions */
 | 
								/* Additional nested transitions */
 | 
				
			||||||
		case 'X':
 | 
							case 'X':
 | 
				
			||||||
		case 'E':
 | 
							case 'E':
 | 
				
			||||||
			ret = chan_task_switch(emu, prev, next);
 | 
								ret = chan_task_switch(emu, prev, next, tr);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			err("unexpected transition value %c", tr);
 | 
								err("unexpected transition value %c", tr);
 | 
				
			||||||
@ -307,8 +320,22 @@ update_task_channels(struct emu *emu,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
enforce_task_rules(struct emu *emu, char tr, struct task *next)
 | 
					enforce_task_rules(struct emu *emu, char tr, struct task_stack *stack, struct task *next)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
				
			||||||
 | 
						struct value ss;
 | 
				
			||||||
 | 
						if (chan_read(&th->m.ch[CH_SUBSYSTEM], &ss) != 0) {
 | 
				
			||||||
 | 
							err("chan_read failed");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If there is no task in the stack, the subsystem must not be
 | 
				
			||||||
 | 
						 * running a task */
 | 
				
			||||||
 | 
						if (stack->top == NULL && ss.type == VALUE_INT64 && ss.i == ST_TASK_RUNNING) {
 | 
				
			||||||
 | 
							err("task stack empty but subsystem is Task running");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (tr != 'x' && tr != 'X')
 | 
						if (tr != 'x' && tr != 'X')
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -320,17 +347,9 @@ enforce_task_rules(struct emu *emu, char tr, struct task *next)
 | 
				
			|||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct nosv_thread *th = EXT(emu->thread, 'V');
 | 
					 | 
				
			||||||
	struct value ss;
 | 
					 | 
				
			||||||
	if (chan_read(&th->m.ch[CH_SUBSYSTEM], &ss) != 0) {
 | 
					 | 
				
			||||||
		err("chan_read failed");
 | 
					 | 
				
			||||||
		return -1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ss.type == VALUE_INT64 && ss.i != ST_TASK_RUNNING) {
 | 
						if (ss.type == VALUE_INT64 && ss.i != ST_TASK_RUNNING) {
 | 
				
			||||||
		err("wrong subsystem state on task begin");
 | 
							err("wrong subsystem state on task begin");
 | 
				
			||||||
		//return -1;
 | 
							return -1;
 | 
				
			||||||
		return 0; // FIXME
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
@ -352,18 +371,21 @@ update_task(struct emu *emu)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct task *next = task_get_running(stack);
 | 
						struct task *next = task_get_running(stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char tr;
 | 
				
			||||||
	int was_running = (prev != NULL);
 | 
						int was_running = (prev != NULL);
 | 
				
			||||||
	int runs_now = (next != NULL);
 | 
						int runs_now = (next != NULL);
 | 
				
			||||||
	char tr;
 | 
					 | 
				
			||||||
	if (expand_transition_value(emu, was_running, runs_now, &tr) != 0) {
 | 
						if (expand_transition_value(emu, was_running, runs_now, &tr) != 0) {
 | 
				
			||||||
		err("expand_transition_value failed");
 | 
							err("expand_transition_value failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Update the task related channels now */
 | 
						/* Update the task related channels now */
 | 
				
			||||||
	update_task_channels(emu, tr, prev, next);
 | 
						if (update_task_channels(emu, tr, prev, next) != 0) {
 | 
				
			||||||
 | 
							err("update_task_channels failed");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (enforce_task_rules(emu, tr, next) != 0) {
 | 
						if (enforce_task_rules(emu, tr, stack, next) != 0) {
 | 
				
			||||||
		err("enforce_task_rules failed");
 | 
							err("enforce_task_rules failed");
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,11 @@ static const int chan_stack[CH_MAX] = {
 | 
				
			|||||||
	[CH_SUBSYSTEM] = 1,
 | 
						[CH_SUBSYSTEM] = 1,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const int chan_dup[CH_MAX] = {
 | 
				
			||||||
 | 
						[CH_APPID] = 1,
 | 
				
			||||||
 | 
						[CH_TYPE] = 1,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* ----------------- pvt ------------------ */
 | 
					/* ----------------- pvt ------------------ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const int pvt_type[] = {
 | 
					static const int pvt_type[] = {
 | 
				
			||||||
@ -101,6 +106,7 @@ static const struct model_chan_spec th_chan = {
 | 
				
			|||||||
	.prefix = model_name,
 | 
						.prefix = model_name,
 | 
				
			||||||
	.ch_names = chan_name,
 | 
						.ch_names = chan_name,
 | 
				
			||||||
	.ch_stack = chan_stack,
 | 
						.ch_stack = chan_stack,
 | 
				
			||||||
 | 
						.ch_dup = chan_dup,
 | 
				
			||||||
	.pvt = &pvt_spec,
 | 
						.pvt = &pvt_spec,
 | 
				
			||||||
	.track = th_track,
 | 
						.track = th_track,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user