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

📄 osapi_linux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2002 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_linux.cpp
 *
 * $Revision: 1.63 $ 
 *
 * Operating System API (OSAPI) source file. Provides an abstraction from the
 * operating system.
 *
 * This is the implementation for Linux
 *
 */
#define POSIX_SEMAPHORE
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

#define MAX_NAME_SIZE 16
#define OS_MSG_Q_HEAD 0
#define OS_MSG_Q_TAIL 1

//#define __CALC_PEAK_ALLOCATION


/* TYPEDEFS */

#ifdef __CALC_PEAK_ALLOCATION
typedef struct tag_mem_info
{
    PVOID pvAddr;
    ULONG size;
} mem_info;
#endif

/*
 *  Thread record
 */
typedef struct tagThreadRecord              /* prefix: thread */
{
    PVOID           pvFunction;
    PVOID           pvParam;
    PVOID           pvStackBase;
    pthread_t       pthread;
    pthread_attr_t  attr;
} OS_TASK;

/*
 *  Semaphore record
 */
typedef struct tagSemaphoreRecord           /* prefix: sem */
{
    ULONG           ulSemType;
    char            strName[MAX_NAME_SIZE];
    ULONG           ulCount;
    ULONG           ulMaxCount;
    pthread_cond_t  condWait;       /* Signal waiting threads */
    pthread_mutex_t mutex;          /* Critical sections */

} OS_SEMAPHORE;

/*
 *  Message Box record
 */
typedef struct tagMessageBoxRecord          /* prefix: mbox */
{
    ULONG           ulDepth;                /* message queue depth */
    ULONG           ulSize;                 /* message size */
    ULONG           ulHead;
    ULONG           ulTail;
    BYTE           *pbBuffers;              /* buffer for messages */
    pthread_cond_t  condWaitFull;           /* Signal waiting threads */
    pthread_cond_t  condWaitEmpty;          /* Signal waiting threads */
    pthread_mutex_t mutex;                  /* Critical sections */
} OS_MBOX;


typedef struct tagTimerRecord
{
    PVOID           pvFunction;
    PVOID           pvParam;
    timer_t         timerID;
} OS_TIMER;


/*
 * Memory Pool ID record
 */
typedef struct tagMemPoolRecord
{
    ULONG          ulPgSize;           /* Size of each page of memory */
    ULONG          ulNumPages;         /* Number of memory pages */
    struct Page                        /* A page from a memory pool */
    {
        PVOID      pvPgAddr;           /* Pointer to memory address */
        LONG       lAttached;          /* Number of pages attached with page *
                                        * (including itself)                 */
    } *memPage;
} OS_MEMPOOL;


/* GLOABALS */

pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;

#ifdef __CALC_PEAK_ALLOCATION
mem_info test[512];
BOOLEAN fFirstAlloc          = TRUE;
ULONG   ulCurrentAllocations = 0;
ULONG   ulPeakAllocations    = 0;
#endif


/* private function prototypes */
static PVOID linuxThread(PVOID);
static void linuxTimer(union sigval sigval);

#ifdef VC_TIMERS
int vc_timer_delete(timer_t timerid);
int vc_timer_create(clockid_t clock_id, struct sigevent *evp, timer_t *timerid);
int vc_timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
int vc_timer_gettime(timer_t timerid, struct itimerspec *value);
static ULONG TimerThreadProc( PVOID pvParam );

#define timer_delete  vc_timer_delete
#define timer_create  vc_timer_create
#define timer_settime vc_timer_settime
#define timer_gettime vc_timer_gettime
#endif

static OS_STATUS OS_MsgQReceiveOption(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize, int iTimeout, int iOption);

/******************************************************************************
*******************************************************************************
**                                                                           **
**  Task function definitions                                                **
**                                                                           **
*******************************************************************************
******************************************************************************/

/**
 * 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.
 */
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.
 */
OS_STATUS OS_TaskSpawnParam(char *strName,
                            int iPrio,
                            int iStackSize,
                            OS_FUNCPTR_PARAM func,
                            PVOID pvParam,
                            PVOID pvStackBaseParam
                            )
{
    OS_TASK *pthreadRecord;
    int     iRetStatus      = 0;

    /* Allocate a record for the thread */
    pthreadRecord = (OS_TASK *)OS_MemAlloc(sizeof(OS_TASK));
    if (pthreadRecord == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("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(DBG_ON(DBG_ERROR), ("%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 = (PVOID)func;

    /* Create the thread attributes */
    iRetStatus = pthread_attr_init(&pthreadRecord->attr);
    if (iRetStatus != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: ATTRIBUTE CREATION FAILED!\n", __FUNCTION__));
        goto error_handler;
    }

    /* Specify the threads stack size */
    pthread_attr_setstacksize(&pthreadRecord->attr, iStackSize);
    if (iRetStatus != 0)
    {
        /* this is not a critical error so just let it be known and continue
         * setting up the thread */
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Could not set our stack size, Using default!\n", __FUNCTION__));
    }


    /* Create the thread */
    iRetStatus = pthread_create(&pthreadRecord->pthread, &pthreadRecord->attr, linuxThread, (PVOID)pthreadRecord);
    if (iRetStatus != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Handle is NULL!\n", __FUNCTION__));
        goto error_handler;
    }

    /* 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.
 */
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)
    {
        /* Delete the given thread */
        iRetStatus = pthread_cancel(pthreadRecord->pthread);

        /* wait for the task to exit */
        OS_TaskJoin(taskId);

        /* delete the pthread attributes */
        iRetStatus = pthread_attr_destroy(&pthreadRecord->attr);

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


/**
 * OS Task Exit function.
 *
 * @param
 *    None.
 *
 * @retval
 *    None.
 */
void OS_TaskExit(void)
{
    pthread_exit(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.
 */
OS_STATUS OS_TaskReset(int taskId)
{
    return (OS_NOT_IMPLEMENTED);
}


/**
 * OS Task Suspend function.
 *
 * @param
 *    int taskId - task identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This function is always successful.
 */
OS_STATUS OS_TaskSuspend(int 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.
 */
OS_STATUS OS_TaskResume(int taskId)
{
    return (OS_NOT_IMPLEMENTED);
}


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

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

    if (pthreadRecord != 0)
    {
        /* Join the given thread */
        if (pthread_join(pthreadRecord->pthread, NULL) != 0)
        {
            status = OS_FAILURE;
        }
    }
    else
    {
        status = OS_FAILURE;
    }

    return (status);
}

/**
 * OS Task Yield function.
 *
 * @param
 *    None.
 *
 * @retval
 *    This function is always successful.
 */
void OS_TaskYield(void)
{
    if (sched_yield() == -1)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("failed to yield\n"));
    }
}

/**
 * OS Task Delay function.
 *
 * @param
 *    int iTicks - time to delay the current task, in ticks
 *
 * @retval
 *    This function is always successful.
 */
void OS_TaskDelay(int iTicks)
{
#if (CLOCKS_PER_SEC == 1000000)
    usleep(iTicks);
#else
    ULONGLONG microseconds;
    microseconds = (ULONGLONG)iTicks;
    microseconds *= 1000000;
    microseconds /= CLOCKS_PER_SEC;
    usleep( (unsigned long)microseconds );
#endif
}

/**
 * OS Task Delay function.
 *
 * @param
 *    milliseconds - time to delay the current task, in milliseconds

⌨️ 快捷键说明

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