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

📄 osapi_linux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * @param
 *    int iInitialCount - initial reference count
 *
 * @param
 *    char *strName - semaphore name
 *
 * @retval
 *    OS_SEM_ID semId - semaphore identifier, if successful
 *    0 - if not successful
 */
OS_SEM_ID OS_SemCCreateNamed(int iOSOptions, int iInitialCount, char *strName)
{
    OS_SEM_ID semId = 0;
    OS_SEMAPHORE *psemRecord;

    /*
     *  Create a counting semaphore
     */
    semId = OS_SemCCreate( iOSOptions, iInitialCount );
    if (semId == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemNamedCCreate: Could not create named semaphore!\n"));
        return 0;
    }

    /*
     *  Name the counting semaphore
     */
    psemRecord = (OS_SEMAPHORE *)semId;
    strncpy(psemRecord->strName, strName, MAX_NAME_SIZE);
    psemRecord->strName[MAX_NAME_SIZE-1] = 0;

    /*
     *  Return a handle to the counting semaphore
     */
    return (OS_SEM_ID)psemRecord;
}

/**
 * OS Semaphore Delete function.
 *
 * @param
 *    OS_SEM_ID semId - semaphore identifier
 *
 * @retval
 *    Returns OS_OK.
 *    This command is always successful.
 */
#if defined(NDEBUG)
OS_STATUS OS_SemDelete(OS_SEM_ID semId)
#else
OS_STATUS OS_SemDeleteDbg(OS_SEM_ID semId, char *srcFile, int srcLine)
#endif
{
    /* Cast the given semaphore identifier to a semaphore record */
    OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;

    if (semId == 0)
    {
#if defined(NDEBUG)
        DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
        DbgPrint(("%s: BAD POINTER.  Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
        return (OS_FAILURE);
    }

    /* release all wait states */
    OS_SemFlush(semId);

    /* Destroy the semaphore */
    if (pthread_cond_destroy(&psemRecord->condWait) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemDelete: Could not init condWait"));
    }
    if (pthread_mutex_destroy(&psemRecord->mutex) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemDelete: Could not init mutex"));
    }

    /* Delete the semaphore record */
    OS_MemFree(psemRecord);

    /* Return success */
    return (OS_OK);
}

/**
 * OS Semaphore Take function. Basically decrements the semaphore count, if
 * possible.
 *
 * @param
 *    OS_SEM_ID semId - semaphore identifier
 *
 * @param
 *    int iTimeout - semaphore take timeout value
 *
 * @retval
 *    OS_OK if successful
 *    OS_TIMEOUT if timout
 *    OS_FAILURE if not successful
 */
#if defined(NDEBUG)
OS_STATUS OS_SemTake(OS_SEM_ID semId, int iTimeout)
#else
OS_STATUS OS_SemTakeDbg(OS_SEM_ID semId, int iTimeout, char *srcFile, int srcLine)
#endif
{
    int iRet                 = OS_OK;
    OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
    struct timeval  tv;
    struct timespec abstime;

    /* Check the validity of the semaphore */
    if (semId == 0)
    {
#if defined(NDEBUG)
        DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
        DbgPrint(("%s: BAD POINTER.  Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
        goto error_handler;
    }

    /* Check the validity of the given timeout value */
    if (iTimeout < OS_WAIT_FOREVER)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Invalid timeout value (%d)!\n", __FUNCTION__, iTimeout));
        goto error_handler;
    }

    if (pthread_mutex_lock(&psemRecord->mutex) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
        goto error_handler;
    }

    if ( (OS_WAIT_FOREVER != iTimeout) && (OS_NO_WAIT != iTimeout) )
    {
        /* get the current time */
        if (gettimeofday(&tv, NULL) != 0)
        {
            DbgPrint(("%s: gettimeofday Failed!\n",__FUNCTION__));
            pthread_mutex_unlock(&psemRecord->mutex);
            iRet = OS_FAILURE;
            goto error_handler;
        }

        /* set our timeout */
        abstime.tv_sec  = tv.tv_sec + iTimeout/CLOCKS_PER_SEC;
        abstime.tv_nsec = ( tv.tv_usec + (iTimeout%CLOCKS_PER_SEC) ) * 1000;

        while ( abstime.tv_nsec > 1000000000 )
        {
            abstime.tv_sec  += 1;
            abstime.tv_nsec -= 1000000000;
        }
    }

    while (psemRecord->ulCount == 0)
    {
        if (OS_WAIT_FOREVER == iTimeout)
        {
            iRet = pthread_cond_wait(&psemRecord->condWait, &psemRecord->mutex);
            if (iRet != 0)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemTake: pthread_cond_wait ERROR = %s!\n", strerror(errno)));
                iRet = OS_FAILURE;
                break;
            }
        }
        else if (OS_NO_WAIT == iTimeout)
        {
            iRet = OS_TIMEOUT;
            break;
        }
        else
        {
            iRet = pthread_cond_timedwait(&psemRecord->condWait, &psemRecord->mutex, &abstime);
            if (iRet != 0)
            {
                if (iRet == ETIMEDOUT)
                {
                    iRet = OS_TIMEOUT;
                    break;
                }
                else
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemTake: pthread_cond_timedwait ERROR = %s!\n", strerror(errno)));
                    iRet = OS_FAILURE;
                    break;
                }
            }
        }
    }

    if (psemRecord->ulCount != 0)
    {
        psemRecord->ulCount--;
        iRet = OS_OK;
    }

    if (pthread_mutex_unlock(&psemRecord->mutex))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* Return status */
    return iRet;

error_handler:

    /* Return failure */
    return (OS_FAILURE);
}

/**
 * OS Semaphore Take function.
 *
 * @param
 *    semId - semaphore identifier
 *
 * @param
 *    ulMilliSeconds - semaphore take timeout value in milliseconds
 *
 * @retval
 *    OS_OK if successful
 *    OS_TIMEOUT if timout
 *    OS_FAILURE if not successful
 */
#if defined(NDEBUG)
OS_STATUS OS_SemTakeMsec(OS_SEM_ID semId, int milliseconds)
#else
OS_STATUS OS_SemTakeMsecDbg(OS_SEM_ID semId, int milliseconds, char* srcFile, int srcLine)
#endif
{
    if ( (milliseconds == OS_WAIT_FOREVER) || (milliseconds == OS_NO_WAIT) )
    {
        return ( OS_SemTake(semId, milliseconds) );
    }
    else
    {
        return ( OS_SemTake(semId, milliseconds*(CLOCKS_PER_SEC/1000)) );
    }
}

/**
 * OS Semaphore Give function. Basically increments the semaphore count,
 * if possible.
 *
 * @param
 *    OS_SEM_ID semId - semaphore identifier
 *
 * @retval
 *    OS_OK if successful
 *    OS_FAILURE if not successful
 */
#if defined(NDEBUG)
OS_STATUS OS_SemGive(OS_SEM_ID semId)
#else
OS_STATUS OS_SemGiveDbg(OS_SEM_ID semId, char *srcFile, int srcLine)
#endif
{
    OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;

    /* Check the validity of the semaphore */
    if (semId == 0)
    {
#if defined(NDEBUG)
        DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
        DbgPrint(("%s: BAD POINTER.  Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
        goto error_handler;
    }

    if (pthread_mutex_lock(&psemRecord->mutex) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* If the semaphore is binary and the count is 1, return an error */
    if (psemRecord->ulSemType == OS_SEM_BINARY)
    {
        if (psemRecord->ulCount == 1)
        {
            pthread_mutex_unlock(&psemRecord->mutex);
            goto error_handler;
        }
    }

    /* Increment the semaphore count */
    psemRecord->ulCount++;

    /* wake one waiting thread */
    if (pthread_cond_signal(&psemRecord->condWait))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
    }

    if (pthread_mutex_unlock(&psemRecord->mutex))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* Return successfully */
    return OS_OK;

error_handler:

    /* Return failure */
    return (OS_FAILURE);
}

/**
 * OS Semaphore Flush function
 *
 * @param
 *    OS_SEM_ID semId - semaphore identifier
 *
 * @retval
 *    Returns OS_OK is successful, OS_FAILURE otherwise.
 */
OS_STATUS OS_SemFlush(OS_SEM_ID semId)
{
    OS_SEMAPHORE *psemRecord = (OS_SEMAPHORE *)semId;
    OS_STATUS    status      = OS_OK;

    /* Check the validity of the semaphore */
    if (0 == semId)
    {
        DbgPrint(("OS_SemFlush: BAD POINTER\n"));
        return (OS_FAILURE);
    }

    if (pthread_mutex_lock(&psemRecord->mutex) == 0)
    {
        if (pthread_cond_broadcast(&psemRecord->condWait) != 0)
        {
            DbgPrint(("OS_SemFlush: Broadcast Failed\n"));
            status = OS_FAILURE;
        }

        pthread_mutex_unlock(&psemRecord->mutex);
    }
    else
    {
        status = OS_FAILURE;
    }

    return (status);
}


/**
 * OS memory pool Information function. Prints out information about
 * the specified memory pool.  This information includes the number of
 * pages in the memory pool, the page size, the address of each memory
 * page, and if each page is allocated or not.
 *
 * @param pool   - The memory pool ID
 *
 * @retval
 *    None.
 */
void OS_MemoryInfo(OS_MEMPOOL_ID pool)
{
    if (pool == NULL)
    {
#ifdef __CALC_PEAK_ALLOCATION
        DBGPRINT(1, ("OS_MemoryInfo:\n"));
        DBGPRINT(1, ("/tPeak Allocations    = %d Bytes\n", ulPeakAllocations));
        DBGPRINT(1, ("/tCurrent Allocations = %d Bytes\n", ulCurrentAllocations));
#endif
    }
    else
    {
        OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool;  /* Pointer to memory pool */
        CHAR       cUsed;                          /* Indicates if page allocated */
        LONG       lAtt;                           /* Indicates # pages attached */

        DbgPrint( ("\n----- Memory Pool Information -----\n") );
        DbgPrint( ("Number of Pages: %d\n", tmpPool->ulNumPages) );
        DbgPrint( ("Page Size:       %d\n", tmpPool->ulPgSize) );
        DbgPrint( ("Memory Pages:\n") );
        DbgPrint( ("\tPage\tAddress\t\tAllocated?\n") );
        for (ULONG i = 0; i < tmpPool->ulNumPages; i++)
        {
            if (tmpPool->memPage[i].lAttached < 0)
            {
                lAtt  =  -1 * tmpPool->memPage[i].lAttached;
                cUsed = 'Y';
            }
            else
            {
                lAtt  = tmpPool->memPage[i].lAttached;
                cUsed = 'N';
            }
            DbgPrint( ("\t%d:\t%x\t\t%c\n", i + 1, (ULONG)tmpPool->memPage[i].pvPgAddr, cUsed) );
        }
    }

    return;
}

/**
 * Creates a memory pool with the specified page size. This function does not
 * allocate the memory for the pool. The memory address is provided as an input.
 *
 * @param pAddr      - pointer to allocated memory buffer
 * @param ulSize     - Size of the memory pool
 * @param ulPageSize - Page size of allocations from the pool. All allocations
 *                     will be a multiple of this size.
 *
 * @retval non-negative memPoolID if success, NULL otherwise.
 *
 * @remark
 *    If ulSize is not a multiple of ulPageSize, then the memory pool
 *    will only contain the number of whole pages that fit in the size
 *    ulSize.
 */
OS_MEMPOOL_ID OS_CreateMemPool(PVOID pvAddr, ULONG ulSize, ULONG ulPageSize)
{
    PVOID          pvTmpAddr;           /* Address of a page in memory pool */
    OS_MEMPOOL     *tmpPool = NULL;     /* Pointer to memory pool */
    ULONG          ulArraySize;         /* Size of array to hold memory pool */

    /*
     * If any of the parameters are invalid, return.
     */
    if ( (pvAddr == NULL) || (ulPageSize == 0) )
    {
        return (NULL);
    }

    /*
     * Allocate memory for the memory pool.
     */
    tmpPool = (OS_MEMPOOL *)OS_MemAlloc(sizeof(OS_MEMPOOL) );
    if (tmpPool == NULL)
    {
        return (NULL);
    }

    /*
     * Set value for memory pool page size and the number of pages.
     */
    tmpPool->ulPgSize   = ulPageSize;
    tmpPool->ulNumPages = ulSize / ulPageSize;

    /*
     * Allocate an array large enough to hold the memory pool.
     */
    ulArraySize         = sizeof(OS_MEMPOOL::Page) * tmpPool->ulNumPages;
    tmpPool->memPage    = (OS_MEMPOOL::Page *)OS_MemAlloc(ulArraySize);
    if (tmpPool->memPage == NULL)
    {
        (void)OS_MemFree(tmpPool);
        return (NULL);
    }

    /*
     * Give a memory address to each page in the memory pool.  Also,
     * each page is given a value of the number of pages attached to
     * it, including itself.
     */
    pvTmpAddr = pvAddr;
    for (ULONG i = 0; i < tmpPool->ulNumPages; i++)
    {
        tmpPool->memPage[i].pvPgAddr   = pvTmpAddr;

⌨️ 快捷键说明

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