📄 osapi_task.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 + -