Exemple #1
0
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  OS_SemPost
 *  Description:  This functions release the semaphore and wakes up the task
 *  being blocked on it. A task can be also be waiting for a time event, so this
 *  function vefiries whether the relased task is also waiting for a time event
 *  or not. In case it is, the task is also removed from the time queue.
 * =====================================================================================
 */
int OS_SemPost(OS_SemID_t _sem)
{
    OS_task_t *task;
    OS_Node_t *n;
    OS_SemID_t id_sem = _sem;

    KTRACE_EVENT_SEM(KEVENT_UNLOCK, SEM(id_sem)->sem_id);
    
    if(OS_ListGetNum(&(SEM(id_sem)->list)) != 0)
    {

        /*  Outs the task from the semaphore queue  */
        n = OS_ListGetNode(&(SEM(id_sem)->list));
        task = GET_ELEMENT(OS_task_t, n, resource_node);

        /*  Store what is the blocked thread in the semaphore structure */
        SEM(id_sem)->tid_in = task->tid;
        
        KTRACE_EVENT_SEM_TID(KEVENT_LOCK_CATCHED, SEM(id_sem)->sem_id, task->tid);
        
        /*  
         * Verifies if the thread is blocked in the time queue
         * due to a TimedWait system call
         */
        if(task->status | TS_TIME_BLOCKED) {
            OS_TimeRemoveFromQueue(task);
        }

        /*  Reset the wait_sem value    */    
        task->wait_sem = 0;

        /*  Add the blocked task to the ready task queue    */
        OS_SchedTaskReady(task->tid);
    }
    else {
        /*  Increment the semaphore counter */
        SEM(id_sem)->sem_value = 1;
        OS_ListReset(&(SEM(id_sem)->list));
    }
    
    return 0;
}
Exemple #2
0
/*
 * Function: tid_t OS_TaskCreate(uint32_t  _stack_size, void *_ip, uint8 _priority)
 *
 * This routine creates a new thread and returns the TCB created
 */
tid_t OS_TaskCreate(uint32_t *_stackaddr, uint32_t  _stacksize, void *_ip, void *_arg, uint8_t _priority)
{
    OS_task_t *task;
    OS_Node_t *n;

  //  DEBUG ("(_stackaddr=%p, _stacksize=%p, _ip=%p, _arg=%p, priority=%d)",
   //     _stackaddr, _stacksize, _ip, _arg, _priority);

    ASSERT (_priority <= SCHED_MIN_PRIORITY);

    /* get a free thread control block */
    n = (OS_Node_t *) OS_ListGetNode (&tcb_list);

    /* assert that we really have a free tcb */
    ASSERT (n != NULL);
    if (n == NULL) return -1;

    task = GET_ELEMENT(OS_task_t, n, node);
    TRACE (task->tid, "d");
    KTRACE (KTRACE_CREATE, task->tid, _priority);

    /*  Stablish the thread stack */
    if (_stackaddr == NULL)
    {
        if (_stacksize < CONFIG_ERCOS_MIN_STACK) _stacksize = CONFIG_ERCOS_MIN_STACK;
        _stackaddr = OS_Malloc (_stacksize);
    } else {
        ASSERT (_stacksize >= CONFIG_ERCOS_MIN_STACK);
    }
    task->stack.size = _stacksize;
    task->stack.addr = (uint8_t *)_stackaddr;

    /*  Fill the stack with the 0x5a mark */
#ifndef CONFIG_NDEBUG
//    unsigned i;
//    DEBUG ("Stack @ %p, %p bytes", _stackaddr, _stacksize);
//   for (i = 0; i < _stacksize; i++) ((uint8_t *) _stackaddr)[i] = 0x5a;
#endif

    /*  Init the new thread context */
    ercos_hal_hwcontext_init (&(task->context), task->stack.addr, task->stack.size, 0, OS_ThreadWrapper);

    /*  Stablish the thread status  */
    task->status = TS_READY;

    /*  Stablish the thread entry point  */
    task->entry_point = _ip;
    task->arg = _arg;

    /*  Init the pointer to the catched mutex   */
    task->pmutex =(OS_Mutex_t*) NULL;

    /*  Set the thread base and temporal priorities   */
    task->priority = _priority;
    task->base_priority = _priority;

    /*  Add the task to the correspond sched queue  */
    OS_SchedTaskReady(task->tid);

    return task->tid;
}