Example #1
0
void
arch_sched(Thread *prev)
{
    if (prev) {
        context_switch(&prev->arch_data.context, sched_context);
    } else {
        context_restore(sched_context);
        panic("schould not return here");
    }
}
Example #2
0
error_t sched_do()  {
    current_task++;
    if(current_task>=num_tasks)
        current_task = 0;
    if(!tasks[current_task].pid || !tasks[current_task].stack)
        return E_INVALID;

    tasks[current_task].stack = context_restore(tasks[current_task].stack);
    return E_NONE;
}
Example #3
0
/*
 * This is the wrapper for the task that executes rendundantly on both cores
 * There is one VERY important thing to note. When the critical task begins executing
 * the value of the stack pointer MUST be the same on both cores. This means that
 * the wrapper must have the same number of variables declared within its scope (i.e.
 * onto its stack) before calling the critical task (pt() in this example)
 */
void preemption_task(void* pdata){
	int done = 0;
	int first = 0;
	int t_os;

	CriticalFunctionPointers* cp =
				(CriticalFunctionPointers*) SHARED_MEMORY_BASE;
	pt = cp->task[1];

	while(1){
		// Get initial time, then wait for 2 ticks
		t_os = OSTimeGet();
		OSTimeDly(2 - t_os);

		//This is a crude way of synchronizing the beginning of the task
		//on both cores
		while (done == 0) {
			altera_avalon_mutex_lock(mutex, 1); //Acquire the hardware mutex
			{
				if(first == 0){
					cp->checkout[1] = 1;
					first = 1;
				}
				if( cp->checkout[0] == 1){
					cp->checkout[0] = 0;
					done = 1;
				}

			}
			altera_avalon_mutex_unlock(mutex);
		}

		// Set default block size for fingerprinting
		fprint_set_block_size(cp->blocksize[1]);

		//Context switch is necessary to clear the callee saved registers
		long registers[8];
		context_switch(registers);

		//Set the global pointer in case of compilation issues related
		//to global variables
		set_gp();
		//call the critical task
		pt(cp->args[1]);
		//restore the original global pointer
		restore_gp();
		//Restore the callee saved registers
		context_restore(registers);
		//Get the end time
		alt_u64 t = alt_timestamp();
		//store the end time
		cp->core_time[1] = t;
	}
}
Example #4
0
/* fig_begin task_start */ 
void task_start(int task_id)
{
    /* a pointer to a TCB */ 
    task_control_block *tcb_ref; 

    /* get a pointer to the TCB associated with 
       task identity task_id */ 
    tcb_ref = tcb_storage_get_tcb_ref(task_id); 

    /* set Task_Id_Running to task id of new task */ 
    Task_Id_Running = task_id; 

    /* restore context for the task with this 
       TCB */ 
    context_restore(tcb_ref->stack_pointer); 
}
Example #5
0
/**
 * Restore environment previously stored by setjmp.
 *
 * This function never returns.
 *
 * @param env Variable with the environment previously stored by call
 * to setjmp.
 * @param val Value to fake when returning from setjmp (0 is transformed to 1).
 */
void longjmp(jmp_buf env, int val) {
	env[0].return_value = (val == 0) ? 1 : val;
	context_restore(&env[0].context);
	__builtin_unreachable();
}
Example #6
0
/**
 * @brief The PENDSV interrupt is used for context switching
 *
 * This interrupt saves the context, runs the scheduler and restores the context of the thread
 * that is run next.
 */
__attribute__((naked)) void isr_pendsv(void)
{
    context_save();
    sched_run();
    context_restore();
}
Example #7
0
/**
 * @brief The SVC interrupt is used for dispatching a thread if no context exists.
 *
 * Starting a thread from non-existing context is needed in two situations:
 * 1) after system initialization for running the main thread
 * 2) after exiting from a thread
 */
__attribute__((naked)) void isr_svc(void)
{
    sched_run();
    context_restore();
}