⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osapi_task.c

📁 这是DVD中伺服部分的核心代码
💻 C
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2006 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file osapi_task.cpp
 *
 * $Revision: 1.7 $ 
 *
 * Operating System API (OSAPI) source file. Provides an abstraction from the
 * operating system.
 *
 * This is the implementation for win32
 *
 */

#include <windows.h>

#include "osapi.h"
#include "DbgPrint.h"
#if TESTHARNESS
    #include "TestHarness.h"
#endif

/* MACROS AND DEFINES */
#define DBG_OSAPI DBG_ERROR
#define DBG_ON(x) (DBG_OSAPI >= x)

static CRITICAL_SECTION criticalSection;
static BOOL OSAPI_WIN32_initialized = FALSE;



/*
 *  Thread record
 */
typedef struct tagThreadRecord              /* prefix: thread */
{
    OS_FUNCPTR_PARAM    pvFunction;
    PVOID               pvParam;
    PVOID               pvStackBase;
    HANDLE              hThreadHandle;
    DWORD               threadID;
} OS_TASK;



OS_STATUS  OS_Initialize( void )
{
    InitializeCriticalSection(&criticalSection);
    OSAPI_WIN32_initialized = TRUE;

    return ( OS_OK );
}


OS_STATUS  OS_FreeResources( void )
{
    if ( OSAPI_WIN32_initialized == TRUE )
    {
        DeleteCriticalSection(&criticalSection);
        return ( OS_OK );
    }

    return ( OS_FAILURE );
}


/**
 * OS Task Spawn function.
 *
 * @param
 *    char *strName - task name
 *
 * @param
 *    int iPrio - task priority
 *
 * @param
 *    int iStackSize - task stack size
 *
 * @param
 *    OS_FUNCPTR func - task procedure function
 *
 * @retval
 *    int pthreadRecord - pointer to the task record, if successful
 *    OS_FAILURE if not successful.
 *
 * @remark
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskSpawn(char *strName,
                       int iPrio,
                       int iStackSize,
                       OS_FUNCPTR func
                       )
{
    return (OS_TaskSpawnParam( strName, iPrio, iStackSize, (OS_FUNCPTR_PARAM)func, NULL, NULL ));
}


/**
 * OS Task Spawn Parameter function.
 *
 * @param
 *    char *strName - task name
 *
 * @param
 *    int iPrio - task priority
 *
 * @param
 *    int iStackSize - task stack size
 *
 * @param
 *    OS_FUNCPTR func - task procedure function
 *
 * @param
 *    PVOID pvParam - task input parameter
 *
 * @param
 *    PVOID pvStackBaseParam - stack pointer, allows stack base to be passed
 *                             in rather than OS_Malloc'd.
 *
 * @retval
 *    int pthreadRecord - pointer to the task record, if successful
 *    OS_FAILURE if not successful.
 *
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskSpawnParam(char *strName,
                            int iPrio,
                            int iStackSize,
                            OS_FUNCPTR_PARAM func,
                            PVOID pvParam,
                            PVOID pvStackBaseParam
                            )
{
    OS_TASK *pthreadRecord;

    (void)strName;

    /* Allocate a record for the thread */
    pthreadRecord = (OS_TASK *)OS_MemAlloc(sizeof(OS_TASK));
    if (pthreadRecord == NULL)
    {
        DbgPrint(("OS_TaskSpawn: Could not allocate thread record!\n"));
        goto error_handler;
    }

    /* Check the validity of the given priority */
    if ( (iPrio < OS_TASK_MIN_PRIORITY) || (iPrio > OS_TASK_MAX_PRIORITY) )
    {
        DbgPrint(("%s: Invalid thread priority (%d)!\n", __FUNCTION__, iPrio));
        goto error_handler;
    }

    /* Save the paramater */
    pthreadRecord->pvParam = pvParam;

    /* Record the pointer to the thread stack base in the thread record */
    pthreadRecord->pvStackBase = pvStackBaseParam;

    /* Record the function pointer */
    pthreadRecord->pvFunction = func;


    if (pvStackBaseParam != NULL)
    {
        // windows doesn't use this memory.
    }

    pthreadRecord->hThreadHandle = CreateThread(
        NULL,                                       // security attributes
        0,      // iStackSize - use default stack size for executable in windows
        (LPTHREAD_START_ROUTINE) func,
        pvParam,
        EVENT_ALL_ACCESS | MUTEX_ALL_ACCESS | SEMAPHORE_ALL_ACCESS | TIMER_ALL_ACCESS, 
        &pthreadRecord->threadID);    

    if (pthreadRecord->hThreadHandle == NULL)
    {
        DbgPrint(("%s: Handle is NULL!\n", __FUNCTION__));
        goto error_handler;
    }


#if 0
    ret_code = SetThreadPriority(pthreadRecord->pvParam, iPrio);
    if (ret_code == FALSE)
    {
        DbgPrint(("OS_TaskSpawnParam: SetThreadPriority failed\n"));
        goto error_handler;
    }
#endif

#if TESTHARNESS
    TestHarness_AddThread( strName, pthreadRecord->threadID );
#endif

    /* Return the thread record as an integer */
    return ( (int)pthreadRecord );


error_handler:

    if (NULL != pthreadRecord)
    {
        OS_MemFree(pthreadRecord);
    }

    return (OS_FAILURE);
}





/**
 * OS Task Delete function.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    This function will print a status message if it was not successful.
 *
 * @remark
 *    According to eCos documentation, cyg_thread_delete only deregisters
 *    the thread from the scheduler, it does not free dynamic memory and
 *    it does not unlock any synchronization objects. Also, cyg_thread_delete
 *    returns "false" (i.e. 0) if not successful and "true" (i.e. 1) if
 *    successful.
 *
 * @verified
 *    No.
 */
void OS_TaskDelete(int taskId)
{
    OS_TASK *pthreadRecord;
    int iRetStatus;

    /* Cast the given task identifier to a pointer to a task record */
    pthreadRecord = (OS_TASK *)taskId;

    if (pthreadRecord != 0)
    {
        // this will terminate the thread, but doesn't release all resources
        // windows wants threads to terminate gracefully, not like this
        iRetStatus = CloseHandle(pthreadRecord->hThreadHandle);
        if ( iRetStatus == 0 ) 
        {
            DbgPrint(("OS_TaskDelete: CloseHandle failed\n"));
        }

        /* wait for the task to exit */

        /* Delete the thread record */
        OS_MemFree(pthreadRecord);
    }
}




/**
 * OS Task Exit function.
 *
 * @param
 *    None.
 *
 * @retval
 *    None.
 *
 * @verified
 *    No.
 */
void OS_TaskExit(void)
{
#if TESTHARNESS
    TestHarness_DeleteThread( GetCurrentThreadId() );
#endif

    ExitThread(0);
}


/**
 * Restarts the task from the beginning of the function passed into the spawn command.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This function is always successful.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskReset(int taskId)
{
    (void)taskId;

    return (OS_NOT_IMPLEMENTED);
}


/**
 * OS Task Suspend function.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This function is always successful.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskSuspend(int taskId)
{
    (void)taskId;

    return (OS_NOT_IMPLEMENTED);
}


/**
 * Resume a task after a suspend. This replaces OS_TaskRestart!
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This function is always successful.
 *
 * @remark
 *    According to eCos documentation, if a thread has been suspended multiple
 *    times, it will need to be resumed the same number of times before it
 *    will run.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskResume(int taskId)
{
    (void) taskId;

    return (OS_NOT_IMPLEMENTED);
}


/**
 * OS Task Join function.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This function is always successful.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskJoin(int taskId)
{
    OS_STATUS   status = OS_OK;
    OS_TASK*    pthreadRecord;
    DWORD       threadExitCode;
    BOOL        win32Result;

    /* Cast the given task identifier to a pointer to a task record */
    pthreadRecord = (OS_TASK *)taskId;

    if (pthreadRecord != 0)
    {
        win32Result = GetExitCodeThread( pthreadRecord->hThreadHandle, &threadExitCode );
        while (( win32Result != 0 ) && ( threadExitCode == STILL_ACTIVE))
        {
            Sleep(25);      // wait for thread to exit
            win32Result = GetExitCodeThread( pthreadRecord->hThreadHandle, &threadExitCode );
        }

        if ( win32Result == 0 )
        {
            DbgPrint(("GetExitCodeThread failed: %s\n",strerror(GetLastError())));
            status = OS_FAILURE;
        }
    }
    else
    {
        status = OS_FAILURE;
    }
    
    return (status);
}

/**
 * OS Task Yield function.
 *
 * @param
 *    None.
 *
 * @retval
 *    This function is always successful.
 *
 * @remark
 *    According to eCos documentation, cyg_thread_yield() yields control
 *    to the next runnable thread of equal priority. If no such thread
 *    exists, this cyg_thread_yield() has no effect.
 *
 * @verified
 *    No.
 */
void OS_TaskYield(void)
{
    Sleep(0);
}

/**
 * OS Task Delay function.
 *
 * @param
 *    int iTicks - time to delay the current task, in ticks
 *
 * @retval
 *    This function is always successful.
 *
 * @remark
 *    According to eCos documentation, 100 tick ~ 1 second.
 *
 * @verified
 *    No.
 */
void OS_TaskDelay(int iTicks)
{
    uint64 milliseconds;

    milliseconds = (uint64)iTicks;
    milliseconds = milliseconds * 1000;
    milliseconds = milliseconds / OS_GetTicksPerSecond();

    Sleep((unsigned long)milliseconds);
}


/**
 * OS Task Delay function.
 *
 * @param
 *    milliseconds - time to delay the current task, in milliseconds
 *
 * @retval
 *    This function is always successful.
 */
void OS_TaskDelayMsec(int milliseconds)
{
    Sleep((unsigned long)milliseconds);
}


/**
 * OS Task Priority Set function
 *
 * @param
 *    int taskId - task identifier
 *
 * @param
 *    int iPrio - task priority
 *
 * @retval
 *    OS_OK if successful.
 *    OS_FAILURE if not successful.
 *
 * @remark
 *    According to eCos documentation, the smaller the priority value, the
 *    higher the priority of the thread. There is always an idle thread, owned
 *    by the kernel, running at the minimum priority (CYG_THREAD_MIN_PRIORITY).
 *    Because of this, no other thread should be running at the minimum
 *    priority.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskPrioritySet(int taskId, int iPrio)
{
    OS_TASK *pthreadRecord;

    /*
     *  Cast the given task identifier to a pointer to a task record
     */
    pthreadRecord = (OS_TASK *)taskId;

    /*
     *  Make sure the given priority value is valid
     */
    if( (iPrio < 1) || (iPrio > 64) )
    {
        DbgPrint(("OS_TaskPrioritySet: Invalid priority value (%d)!\n", iPrio));
        return OS_FAILURE;
    }

    /*
     *  Set the priority of the given thread
     */
    /* <TBD> */

    /*
     *  Return successfully
     */
    return OS_OK;
}

/**
 * OS Task Identify Self function.
 *
 * @param
 *    None.
 *
 * @retval
 *    int tHandle - handle of current task, if successful
 *    OS_FAILURE - if not successful
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
ULONG OS_TaskIdSelf(void)
{
    return((ULONG)GetCurrentThreadId());
}

/**
 * OS Task Lock function.
 *
 * @param
 *    None.
 *
 * @retval
 *    Returns FALSE on success, TRUE on failure.
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
BOOLEAN OS_TaskLock(void)
{
    if ( OSAPI_WIN32_initialized == FALSE ) 
    {
        OS_Initialize();
    }

    EnterCriticalSection(&criticalSection);

    return FALSE;
}

/**
 * OS Task Unlock function.
 *
 * @param
 *    None.
 *
 * @retval
 *    Returns FALSE on success, TRUE on failure.
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
BOOLEAN OS_TaskUnlock(void)
{
    if ( OSAPI_WIN32_initialized == FALSE ) 
    {
        OS_Initialize();
    }

    LeaveCriticalSection(&criticalSection);

    return (FALSE);
}

/**
 * OS Task Name function.
 *
 * @param
 *    OS_TASK taskId - task identifier
 *
 * @retval
 *    char *strTaskName - task name, if successful
 *    NULL - if not successful
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
char *OS_TaskName(int taskId)
{
    (void)taskId;

    DbgPrint(("OS_TaskName: NOT IMPLEMENTED!\n"));
    return (char *)NULL;
}

/**
 * OS Task Verify function.
 *
 * @param
 *    OS_TASK taskId - task identifier
 *
 * @retval
 *    OS_OK if successful.
 *    OS_FAILURE if not successful.
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
OS_STATUS OS_TaskVerify(int taskId)
{
    (void)taskId;

    DbgPrint(("OS_TaskVerify: NOT IMPLEMENTED!\n"));
    return OS_FAILURE;
}

/**
 * OS Task Name to Identifier function.
 *
 * @param
 *    char *strName - task name
 *
 * @retval
 *    int taskId - identifier of current task, if successful
 *    0 - if not successful
 *
 * @remark
 *    None.
 *
 * @verified
 *    No.
 */
int OS_TaskNameToId(char *strName)
{
    (void)strName;

    DbgPrint(("OS_TaskNameToId: NOT IMPLEMENTED!\n"));
    return 0;
}

/**
 * OS Task Show PC function.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    None.
 *
 * @remark
 *    This function was not implemented by the Y-Code.
 *
 * @verified
 *    No.
 */
void OS_TaskShowPc(int taskId)
{
    (void)taskId;

    DbgPrint(("OS_TaskShowPc: NOT IMPLEMENTED!\n"));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -