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

📄 osapi_linux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        tmpPool->memPage[i].lAttached  = tmpPool->ulNumPages - i;
        pvTmpAddr                      = (BYTE *)pvTmpAddr + ulPageSize;
    }

    return ( (OS_MEMPOOL_ID)tmpPool);
}

/**
 * Deletes a memory pool created by OS_CreateMemPool. This does not release the memory
 * buffer used by the pool. This memory should be released by the application.
 *
 * @param pool   - The memory pool ID
 *
 * @retval OS_OK if successful, an osapi error code otherwise.
 */
OS_STATUS OS_DeleteMemPool(OS_MEMPOOL_ID pool)
{
    OS_MEMPOOL *tmpPool = (OS_MEMPOOL *)pool;   /* Pointer to memory pool */

    /*
     * If memory pool ID is NULL, then return.
     */
    if (pool == NULL)
    {
        return (OS_INVALID_MEMPOOL);
    }

    /*
     * Free any memory used by memory pool.
     */
    OS_MemFree(tmpPool->memPage);
    OS_MemFree(pool);

    return (OS_OK);
}

/**
 * Allocates a block of memory from the specified memory pool.
 *
 * @param pool   - The memory pool ID
 * @param ulSize - Size of memory block to allocate.
 *
 * @retval - pointer to allocated memory if successful, NULL if not successful
 */
PVOID OS_MemPoolAlloc(OS_MEMPOOL_ID pool, ULONG ulSize)
{
    LONG        lPgNeeded;                     /* Number of pages needed to allocate the *
                                                * requested block of memory.             */
    OS_MEMPOOL  *tmpPool = (OS_MEMPOOL *)pool; /* Pointer to memory pool */
    ULONG i;                                   /* Loop iterator */

    /*
     * If invalid memory pool, return.
     */
    if (pool == NULL)
    {
        return NULL;
    }

    /*
     * Determine how many pages are needed for the requested amount
     * of memory.
     */
    lPgNeeded = (ulSize / tmpPool->ulPgSize);
    if (ulSize % tmpPool->ulPgSize != 0)
    {
        ++lPgNeeded;
    }

    /* Search for a block of pages that have at least the number
     * of pages needed consecutively.  Once a block is found, return
     * the address of the first page of this block. If no blocks large
     * enough are found, then return NULL.
     */
    i = 0;
    while (i < tmpPool->ulNumPages)
    {
        /*
         * Look at the number of pages attached to the current page to
         * determine if the block of pages is large enough to use.  If
         * the number of pages attached is a negative value, then move ahead
         * that number of pages (positive value) because those pages are allocated.
         * If the number of pages attached is less than the number of pages
         * needed, then move ahead that number of pages because the block of
         * pages is not large enough.  Otherwise, the block is large enough,
         * so allocate a block starting at current page.
         */
        if (tmpPool->memPage[i].lAttached < 0)
        {
            i = i + (-1 * tmpPool->memPage[i].lAttached);
        }
        else if (tmpPool->memPage[i].lAttached < lPgNeeded)
        {
            i = i + tmpPool->memPage[i].lAttached;
        }
        else
        {
            /*
             * Adjust the number of pages attached to the allocated pages.
             * Simply change number to negative.
             */
            LONG lPages = lPgNeeded;
            for (ULONG j = i; j < (i + lPgNeeded); j++)
            {
                tmpPool->memPage[j].lAttached = -1 * lPages;
                lPages = lPages - 1;
            }

            return (tmpPool->memPage[i].pvPgAddr);
        }
    }

    return (NULL);
}

/**
 * Frees the given memory block back to the specified memory pool
 *
 * @param pool   - The memory pool ID
 * @param pvMemory - The address
 *
 * @retval - OS_OK if sucessful, an osapi error code otherwise.
 */
OS_STATUS OS_MemPoolFree(OS_MEMPOOL_ID pool, PVOID pvMemory)
{
    LONG        lIndex,                          /* Page number in memory pool */
                lNextIndex;                      /* Page number of next block  */
    OS_MEMPOOL  *tmpPool = (OS_MEMPOOL *)pool;   /* Pointer to memory pool */
    ULONG       ulFront,                         /* Beginning and end address of */
                ulEnd;                           /* memory pool.                 */
    /*
     * If null pointer was passed, return.
     */
    if (pvMemory == NULL)
    {
        return (OS_NULL_POINTER);
    }

    /*
     * Check that memory is in the specified memory pool. If it's not
     * then do not free the memory.
     */
    ulFront = (ULONG)tmpPool->memPage[0].pvPgAddr;
    ulEnd   = (ULONG)tmpPool->memPage[tmpPool->ulNumPages - 1].pvPgAddr +
              tmpPool->ulPgSize;
    if ( ( (ULONG)pvMemory < ulFront) || ( (ULONG)pvMemory >= ulEnd) ||
         (pool == NULL) )
    {
        return (OS_INVALID_MEMPOOL);
    }

    /*
     * Determine, from the address, which page(s) to free.  If address
     * is not a page address, then return.
     */
    lIndex     = (BYTE *)pvMemory - (BYTE *)tmpPool->memPage[0].pvPgAddr;
    if (lIndex % tmpPool->ulPgSize != 0)
    {
        return (OS_FAILURE);
    }
    lIndex     = lIndex / tmpPool->ulPgSize;

    /*
     * Make sure that the memory address given is not already free.
     */
    if (tmpPool->memPage[lIndex].lAttached >= 0)
    {
        return (OS_FAILURE);
    }

    /*
     * Adjust the number of pages attached to the freed page(s).
     */
    lNextIndex = lIndex + (-1 * tmpPool->memPage[lIndex].lAttached);
    LONG i;
    if (tmpPool->memPage[lNextIndex].lAttached > 0)
    {
        /*
         * Need to add the number of pages attached to the pages
         * following the freed pages.
         */
        for (i = lIndex; i < lNextIndex; i++)
        {
            tmpPool->memPage[i].lAttached =
                    (-1 * tmpPool->memPage[i].lAttached) +
                    tmpPool->memPage[lNextIndex].lAttached;
        }
    }
    else
    {
        /*
         * No non-allocated pages following the freed pages.
         */
        for (i = lIndex; i < lNextIndex; i++)
        {
            tmpPool->memPage[i].lAttached =
                    (-1 * tmpPool->memPage[i].lAttached);
        }
    }

    /*
     * Adjust the number of pages attached to any pages preceding the
     * freed pages.
     */
    i = lIndex - 1;
    while ( (tmpPool->memPage[i].lAttached >= 0) && (i >= 0) )
    {
        tmpPool->memPage[i].lAttached += tmpPool->memPage[lIndex].lAttached;
        i = i - 1;
    }

    return (OS_OK);
}

/**
 * Frees all memory blocks back to the specified memory pool
 *
 * @param pool   - The memory pool ID
 *
 * @retval - OS_OK if sucessful, an osapi error code otherwise.
 */
OS_STATUS OS_MemPoolReset(OS_MEMPOOL_ID pool)
{
    OS_MEMPOOL *pMemPool = (OS_MEMPOOL *)pool;

    if (pool == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MemPoolReset: NULL pointer!\n"));
        return (OS_NULL_POINTER);
    }

    /* Free all pages of mempool */
    for (ULONG i = 0; i < pMemPool->ulNumPages; i++)
    {
        pMemPool->memPage[i].lAttached  = pMemPool->ulNumPages - i;
    }

    return (OS_OK);
}

/**
 * Allocates a block of memory from the OS memory pool.
 *
 * @param ulSize - memory size.
 *
 * @retval
 *    pvMemory - pointer to allocated memory, if successful
 *    NULL - if not successful
 */
#ifndef DMALLOC
PVOID OS_MemAlloc(ULONG ulSize)
{
    PVOID pvMemory = NULL;

#ifdef __CALC_PEAK_ALLOCATION
    if (fFirstAlloc == TRUE)
    {
        memset(test, 0, sizeof(mem_info) * 512);
        fFirstAlloc = FALSE;
    }
#endif

    /*
     *  Check the validity of the given memory size
     */
    if (ulSize == 0)
    {
        DbgPrint(("OS_MemAlloc: Memory size is 0!\n"));
        return (NULL);
    }

    /*
     *  Allocate a block of the given size from the OS memory
     */
    pvMemory = malloc(ulSize);

#ifdef __CALC_PEAK_ALLOCATION
    if (pvMemory != NULL)
    {
        for (int i=0; i<512; i++)
        {
            if (test[i].pvAddr == NULL)
            {
                test[i].pvAddr = pvMemory;
                test[i].size   = ulSize;
                break;
            }
        }

        ulCurrentAllocations += ulSize;
        if (ulPeakAllocations < ulCurrentAllocations)
        {
            ulPeakAllocations = ulCurrentAllocations;
        }
    }
#endif

    DbgAssert(pvMemory != NULL);

    /*
     *  Return a pointer to the allocated block
     */
    return (pvMemory);
}

/**
 * Frees the given memory block back to the OS memory pool.
 *
 * @param pvMemory - pointer to the memory to be freed
 *
 * @retval OS_OK if successful, otherwise an osapi error code
 */
OS_STATUS OS_MemFree(PVOID pvMemory)
{
    /*
     *  Check the validity of the given memory pointer
     */
    if (pvMemory == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MemFree: Memory pointer is NULL!\n"));
        return (OS_NULL_POINTER);
    }

#ifdef __CALC_PEAK_ALLOCATION
    for (int i=0; i<512; i++)
    {
        if (test[i].pvAddr == pvMemory)
        {
            ulCurrentAllocations -= test[i].size;

            test[i].pvAddr = NULL;
            test[i].size   = 0;
            break;
        }
    }
#endif

    /*
     *  Make sure the OS memory pool has been created
     */

    /*
     *  Free the given block back to the OS memory
     */
    free(pvMemory);

    return (OS_OK);
}
#endif

/**
 * OS Initialize DRAM Top function.
 *
 * @param
 *    None.
 *
 * @retval
 *    OS_MEMORY_BASE - offset to the top of DRAM, if successful
 *    NULL - if not successful
 */
OS_STATUS OS_InitDramTop(PVOID pStartAddr, ULONG ulMemSize)
{
    return (OS_NOT_IMPLEMENTED);
}

/******************************************************************************
*******************************************************************************
**                                                                           **
**  Timer function prototypes                                                **
**                                                                           **
*******************************************************************************
******************************************************************************/

#ifdef VC_TIMERS

typedef struct tagThreadTimer
{
    int iThreadID;              /* the ID of the thread in charge of this timer */
    timer_t timerid;            /* the slot value and unique timer id */
    struct sigevent evp;        /* description of event, only callback type supported */
    char strThreadName[17];     /* name of thread, this shall be VCTimerThreadXXX */
    struct itimerspec itimer;   /* this contains the timeout or repeat value */
    OS_SEM_ID semTimerSet;      /* used to block for timeout specified */
    BOOLEAN fTimerSetPending;   /* set when timer set is pending / cleared once timer starts counting */
    BOOLEAN fTimerCounting;     /* set while timer is counting */
    BOOLEAN fTimerExitPending;  /* set when timer exit is pending */
    struct timespec abstime;
} ThreadTimer;

#define TOTAL_TIMERS 200
#define VC_TIMER_THREAD_STACK_SIZE  1024

/* @todo Track the timer list with a dynamic clist */
ThreadTimer *pttMasterList[TOTAL_TIMERS] = { NULL };

/**
 * VCI Pthread-based, Posix-style Timer
 *
 * @param
 *    clockid_t clock_id
 *
 * @param
 *    struct sigevent *evp
 *
 * @param
 *    timer_t *timerid

 * @retval
 *    0 if successful
 *    -1 if not successful
 */
int vc_timer_create( clockid_t clockid, struct sigevent *evp, timer_t *timerid )
{

    int iReturn = 0;
    int i = 0;
    char *strThreadName = "VCTimerThread";
    ThreadTimer *pttThreadTimer = NULL;
    BOOLEAN fFoundOpen = FALSE;

    /* we only handle REALTIME at this time */
    if( CLOCK_REALTIME != clockid )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s - clockid problem %08X\n", __FUNCTION__, clockid) );
        iReturn = -1;
        goto leave;
    }

    /* we only treat call-back signals */
    if( NULL == evp )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s - NULL POINTER\n", __FUNCTION__) );
        iReturn = -1;
        goto leave;
    }

    /* malloc a structure to store all of the timer info including the threadid, timerid, and all of the private params */
    if( NULL == ( pttThreadTimer = (ThreadTimer*)OS_MemAlloc(sizeof(ThreadTimer)) ) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s - OUT OF MEMORY\n", __FUNCTION__) );
        iReturn = -1;
        goto leave;
    }

    /* @todo - add new pThreadTimer to a list of some sort(possibly a clist) */
    /* find a free slot in the global timer storage */
    for (i = 0; i < TOTAL_TIMERS; i++)
    {
        if (pttMasterList[i] == NULL)
        {
            pttMasterList[i] = pttThreadTimer;
            fFoundOpen = TRUE;
            break;
        }
    }

    if( FALSE == fFoundOpen )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s - can't find an open timer slot\n", __FUNCTION__) );
        iReturn = -1;
        goto leave;
    }

    /* Intially timer is waiting for a timer to be set and not counting */
    pttThreadTimer->fTimerExitPending = FALSE;
    pttThreadTimer->fTimerSetPending  = FALSE;
    pttThreadTimer->fTimerCounting    = FALSE;

    /* This is a semaphore that allows the thread to wait for the time that timer is set to */
    pttThreadTimer->semTimerSet = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);

    /* The evp contains the function that gets called from the ti

⌨️ 快捷键说明

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