コード例 #1
0
ファイル: coroutine.c プロジェクト: bigvaliant/coroutine
static void *
_yield(struct coroutine *co) {
    assert(_scheduler() == co->sched);
    co->stack_lowest = (uint8_t*)&co;
    co->result = NULL;
    _switch_context(&co->ctx, &co->sched->ctx);
    return co->result;
}
コード例 #2
0
ファイル: coroutine.c プロジェクト: bigvaliant/coroutine
static void
_push_coroutine(struct scheduler *s, struct coroutine *co) {
    struct scheduler *self = _scheduler();
    if (s == self) {
        queue_push(s->self_queue, co);
    } else {
        pthread_mutex_lock(&s->queue_mutex);
        s->lock_queue_n += 1;
        queue_push(s->lock_queue, co);
        pthread_mutex_unlock(&s->queue_mutex);
        pthread_cond_signal(&s->queue_signal);
    }
}
コード例 #3
0
ファイル: coroutine.c プロジェクト: bigvaliant/coroutine
inline static void
_resume(struct coroutine *co) {
    struct scheduler *s = co->sched;
    assert(s == _scheduler());
    if (co->inited) {
        _copy_stack(co);
    } else {
        // init in the same thread as coroutine context.
        co->inited = true;
        _make_context(co, &s->ctx, &s->stack);
    }
    co->status = STATUS_RUNNING;
    _switch_context(&s->ctx, &co->ctx);
}
コード例 #4
0
ファイル: OurTOS.c プロジェクト: cbrem/ourtos
void interrupt (TIMER_INTERRUPT_VECTOR) _timerIsr(void) {

	/* make this local vars static so as to store on the heap instead
	 * of the stack. This avoids stack smashing.
	 */
	static uint8_t* stackPtrTmp;
	static uint8_t scheduledTask;
	static int32_t elapsedTime, curTime;

	// TODO remove post demo
	static bool_t printedMutex = false;

	/* acknowledge interrupt */
	TFLG2_TOF = 1;

	/* get current stackPtr */
	{ asm STS stackPtrTmp; }

	/* Save stack ptr
	 * special case on main loop.
	 * The main loop stack pointer is saved in a seperate variable*/
	if (MAIN_LOOP_PRIORITY == _currentTask) {
		_mainLoopStackPtr = stackPtrTmp;
	} else {
		taskArray[_currentTask].stackPtr = stackPtrTmp;
	}

	/* Set current stack to ISR stack.
	 * The ISR stack keeps the ISR from stack smashing
	 * an uninitialized task's stack.
	 * start at lowest memory address in stack, note this is ptr arithmatic.
	 */
	stackPtrTmp = _ISRstack + TASK_STACK_SIZE - 1;
	{ asm LDS stackPtrTmp; }

	/* update time variables */
	timerUpdateCurrent();

	/* update task timing - note that this requires interrupts be disabled */
	elapsedTime = timerElapsedTime();
	_updateTaskTimes(elapsedTime);

	/* Run the scheduler every time through the ISR
	 * The scheduler determines which task to run once the
	 * ISR returns.
	 */
	scheduledTask = _scheduler();

	/* If serial dubugging is enabled and we have we just changed tasks,
	 * print information about the current state of all tasks.
	 */
	if (_debug && scheduledTask != _currentTask) {
		curTime = timerGetCurrentMsec();
		_debugPrint(scheduledTask, curTime);
	}

	// TODO remove after demo
	/* task 4 is set to run but task 3 is ready to run */
	if ((false == printedMutex) &&
	    (scheduledTask == 4) &&
		  (taskArray[3].enabled == true) &&
		  (taskArray[3].timeToNextRun <= 0) ) {
		serialWrite("HA I GOT YOUR MUTEX!!\n", 23);
		printedMutex = true;
	} else if (scheduledTask != 4){
	  printedMutex = false;
	}

	/* Special case if scheduler has no tasks to run.
	 * In this case the returned index is _numTasks.
	 * The main loop will be run until a task is ready
	 * to run. Otherwise simply use the designated task's
	 * stack ptr.
	 */
	if ( MAIN_LOOP_PRIORITY == scheduledTask ) {
		stackPtrTmp = _mainLoopStackPtr;

	} else {

		if ( false == taskArray[scheduledTask].running ) {
			/* Create launch stack if not currently running
			 * This operation sets the stack pointer.
			 */
			_createNewStack(scheduledTask);
		}

		/* grab stack ptr */
		stackPtrTmp = taskArray[scheduledTask].stackPtr;
		/* task is now runing */
		taskArray[scheduledTask].running = true;

	}

	/* Set global current task to the scheduled task */
	_currentTask = scheduledTask;

	/* Set stack pointer to the current task stack pointer */
	{ asm LDS stackPtrTmp; }

	/* ISR does an RTI to return to the current stack. The
	 * RTI restores all of the state (registers, cond codes, etc)
	 * if the task was running before or simply loads the dummy
	 * state (as set by the create stack function) if the task
	 * is being initialized.
	 */
}