示例#1
0
/*
 *  ======== GateMutexPri_Instance_finalize ========
 */
Void GateMutexPri_Instance_finalize(GateMutexPri_Object *obj)
{
    Queue_Handle pendQ;

    pendQ = GateMutexPri_Instance_State_pendQ(obj);
    Queue_destruct(Queue_struct(pendQ));
}
示例#2
0
/*
 *  ======== Semaphore_Instance_finalize ========
 */
Void Semaphore_Instance_finalize(Semaphore_Object *sem)
{
    Queue_Handle pendQ;

    pendQ = Semaphore_Instance_State_pendQ(sem);
    Queue_destruct(Queue_struct(pendQ));

    if (Semaphore_supportsEvents && (sem->event != NULL)) {
        Semaphore_eventSync(sem->event, sem->eventId, 0);
    }
}
示例#3
0
/*
 *  ======== pthread_exit ========
 */
void pthread_exit(void *retval)
{
    pthread_Obj      *thread = (pthread_Obj *)pthread_self();

    /*
     *  This function terminates the calling thread and returns
     *  a value via retval that (if the thread is joinable) is available to
     *  another thread that calls pthread_join().
     *
     *  Any clean-up handlers that have not yet been popped, are popped
     *  (in the reverse of the order in which they were pushed) and executed.
     */
    thread->ret = retval;

    /*
     *  Don't bother disabling the Task scheduler while the thread
     *  is exiting.  It will be up to the application to not make
     *  such calls as pthread_cancel() or pthread_detach() while the
     *  thread is exiting.
     */

    /* Pop and execute the cleanup handlers */
    while (thread->cleanupList != NULL) {
        _pthread_cleanup_pop(thread->cleanupList, 1);
    }

    /* Cleanup any pthread specific data */
    _pthread_removeThreadKeys((pthread_t)thread);

    if (!thread->detached) {
        Semaphore_post(Semaphore_handle(&(thread->joinSem)));

        /* Set this task's priority to -1 to stop it from running. */
        Task_setPri(thread->task, -1);
    }
    else {
        /* Free memory */
#if ti_sysbios_posix_Settings_supportsMutexPriority__D
        Queue_destruct(&(thread->mutexList));
#endif
        Semaphore_destruct(&(thread->joinSem));

        Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj));

        /*
         *  Don't call Task_delete on the calling thread.  Task_exit()
         *  will put the task on the terminated queue, and if
         *  Task_deleteTerminatedTasks is TRUE, the task will be cleaned
         *  up automatically.
         */
        Task_exit();
    }
}
示例#4
0
/*
 *  ======== GIO_Instance_finalize ========
 */
Void GIO_Instance_finalize(GIO_Object *obj, Int status)
{    
    Queue_Handle            freeList;
    SyncSemThread_Handle    sync;
    IOM_Fxns                *iomFxns;

    iomFxns = (IOM_Fxns *)obj->fxns;

    /* fall through in switch below is intentional */
    switch (status) {
        case 0:        
            /* GIO_delete() */
            if (obj->submitCount > 0) {
                GIO_flush(obj);
            }
            iomFxns->mdDeleteChan(obj->mdChan);

            /* OK to fall through */                 

        case 4:
            /* mdCreateChan failed */

            /* OK to fall through */                 

        case 3:
            /* name not found */
            Memory_free(NULL, obj->packets, 
                sizeof(IOM_Packet) * obj->numPackets);

            /* OK to fall through */                 
        
        case 2:
            /* alloc packets failed */
            freeList = GIO_Instance_State_freeList(obj);
            Queue_destruct(Queue_struct(freeList));
            
            if (obj->userSync == FALSE) {
                sync = SyncSemThread_Handle_downCast(obj->sync);
                SyncSemThread_delete(&sync);
            }

            /* OK to fall through */                 

        case 1:
            /* Sync_create failed */

            /* OK to fall through */                 

        default:
            break;
    }
}
示例#5
0
/*
 *  ======== pthread_cancel ========
 *  The specification of this API is that it be used as a means for one thread
 *  to termintate the execution of another thread.  There is no mention of
 *  returning an error if the argument, pthread, is the same thread as the
 *  calling thread.
 */
int pthread_cancel(pthread_t pthread)
{
    pthread_Obj  *thread = (pthread_Obj *)pthread;
    UInt          key;

    /*
     *  Cancel the thread.  Only asynchronous cancellation is supported,
     *  since functions that would normally be cancellation points (eg,
     *  printf()), are not cancellation points for BIOS.
     */
    key = Task_disable();

    /* Indicate that cancellation is requested. */
    thread->cancelPending = 1;

    if (thread->cancelState == PTHREAD_CANCEL_ENABLE) {
        /* Set this task's priority to -1 to stop it from running. */
        Task_setPri(thread->task, -1);

        Task_restore(key);

        /* Pop and execute the cleanup handlers */
        while (thread->cleanupList != NULL) {
            _pthread_cleanup_pop(thread->cleanupList, 1);
        }

        /* Cleanup any pthread specific data */
        _pthread_removeThreadKeys(pthread);

        if (thread->detached) {
            /* Free memory */
#if ti_sysbios_posix_Settings_supportsMutexPriority__D
            Queue_destruct(&(thread->mutexList));
#endif
            Semaphore_destruct(&(thread->joinSem));
            Task_delete(&(thread->task));

            Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj));
        }
        else {
            /* pthread_join() will clean up. */
            thread->ret = PTHREAD_CANCELED;
            Semaphore_post(Semaphore_handle(&(thread->joinSem)));
        }
    }
    else {
        Task_restore(key);
    }

    return (0);
}
示例#6
0
/*
 *  ======== _pthread_runStub ========
 */
static void _pthread_runStub(UArg arg0, UArg arg1)
{
    UInt         key;
    Ptr          arg;
    pthread_Obj *thread = (pthread_Obj *)(xdc_uargToPtr(arg1));

    arg = Task_getEnv(thread->task);
    thread->ret = thread->fxn(arg);

    /* Pop and execute the cleanup handlers */
    while (thread->cleanupList != NULL) {
        _pthread_cleanup_pop(thread->cleanupList, 1);
    }

    /* Cleanup any pthread specific data */
    _pthread_removeThreadKeys((pthread_t)thread);

    key = Task_disable();

    if (!thread->detached) {
        Semaphore_post(Semaphore_handle(&(thread->joinSem)));

        /*
         * Set this task's priority to -1 to prevent it from being put
         * on the terminated queue (and deleted if Task.deleteTerminatedTasks
         * is true). pthread_join() will delete the Task object.
         */
        Task_setPri(thread->task, -1);
        Task_restore(key);
    }
    else {
        Task_restore(key);

        /* Free memory */
#if ti_sysbios_posix_Settings_supportsMutexPriority__D
        Queue_destruct(&(thread->mutexList));
#endif
        Semaphore_destruct(&(thread->joinSem));

        Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj));

        /* The system will have to clean up the Task object */
    }

    /* Task_exit() is called when returning from this function */
}
示例#7
0
/*
 *  ======== pthread_join ========
 *  Wait for thread to terminate.
 *
 *  If multiple threads simultaneously try to join with the same
 *  thread, the results are undefined.  We will return an error.
 *
 *  If the thread calling pthread_join() is canceled, then the target
 *  thread will remain joinable (i.e., it will not be detached).
 */
int pthread_join(pthread_t pthread, void **thread_return)
{
    pthread_Obj  *thread = (pthread_Obj *)pthread;
    UInt          key;

    key = Task_disable();

    if ((thread->joinThread != NULL) || (thread->detached != 0)) {
        /*
         *  Error - Another thread has already called pthread_join()
         *  for this thread, or the thread is in the detached state.
         */
        Task_restore(key);
        return (EINVAL);
    }

    if (pthread == pthread_self()) {
        Task_restore(key);
        return (EDEADLK);
    }

    /*
     *  Allow pthread_join() to be called from a BIOS Task.  If we
     *  set joinThread to pthread_self(), we could get NULL if the
     *  Task arg1 is 0.  All we need is a non-NULL value for joinThread.
     */
    thread->joinThread = Task_self();

    Task_restore(key);

    Semaphore_pend(Semaphore_handle(&(thread->joinSem)), BIOS_WAIT_FOREVER);

    if (thread_return) {
        *thread_return = thread->ret;
    }

#if ti_sysbios_posix_Settings_supportsMutexPriority__D
    Queue_destruct(&(thread->mutexList));
#endif
    Semaphore_destruct(&(thread->joinSem));

    Task_delete(&(thread->task));

    Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj));
    return (0);
}
示例#8
0
/*
 *  ======== pthread_create ========
 */
int pthread_create(pthread_t *newthread, const pthread_attr_t *attr,
        void *(*startroutine)(void *), void *arg)
{
    Semaphore_Params  semParams;
    Task_Params       taskParams;
    pthread_Obj      *thread = NULL;
    Error_Block       eb;
    pthread_attr_t   *pAttr;

    Error_init(&eb);
    Task_Params_init(&taskParams);

    *newthread = NULL;

    thread = (pthread_Obj *)Memory_alloc(Task_Object_heap(),
            sizeof(pthread_Obj), 0, &eb);

    if (thread == NULL) {
        return (ENOMEM);
    }

    pAttr = (attr == NULL) ? &defaultPthreadAttrs : (pthread_attr_t *)attr;

    taskParams.priority = pAttr->priority;
    taskParams.stack = pAttr->stack;
    taskParams.stackSize = pAttr->stacksize + pAttr->guardsize;

    /* Save the function in arg0 for ROV */
    taskParams.arg0 = (UArg)startroutine;
    taskParams.arg1 = (UArg)thread;
    taskParams.env = arg;
    taskParams.priority = -1;

    thread->detached = (pAttr->detachstate == PTHREAD_CREATE_JOINABLE) ? 0 : 1;
    thread->fxn = startroutine;
    thread->joinThread = NULL;
    thread->cancelState = PTHREAD_CANCEL_ENABLE;
    thread->cancelPending = 0;
    thread->priority = pAttr->priority;
    thread->cleanupList = NULL;

#if ti_sysbios_posix_Settings_supportsMutexPriority__D
    thread->blockedMutex = NULL;
    Queue_elemClear((Queue_Elem *)thread);
    Queue_construct(&(thread->mutexList), NULL);
#endif

    Semaphore_Params_init(&semParams);
    semParams.mode = Semaphore_Mode_BINARY;

    Semaphore_construct(&(thread->joinSem), 0, &semParams);

    thread->task = Task_create((Task_FuncPtr)_pthread_runStub,
            &taskParams, &eb);

    if (thread->task == NULL) {
        Semaphore_destruct(&(thread->joinSem));

#if ti_sysbios_posix_Settings_supportsMutexPriority__D
        Queue_destruct(&(thread->mutexList));
#endif
        Memory_free(Task_Object_heap(), thread, sizeof(pthread_Obj));

        return (ENOMEM);
    }

    *newthread = (pthread_t)thread;
    Task_setPri(thread->task, pAttr->priority);

    return (0);
}