//------------------------------------------------------------------------------
// Function:    ShbIpcAllocBuffer
//
// Description: Allocates memory for the shared buffers
//
// Parameters:
//   ulBufferSize_p          size of the shared buffer to allocate
//   pszBufferId_p           string containing the shared buffer identifier
//   ppShbInstance_p         pointer to store the instance of this shared
//                           buffer
//   pfShbNewCreated_p       pointer to store the buffer creation flag
//
// Return:      tShbError = error
//------------------------------------------------------------------------------
tShbError ShbIpcAllocBuffer (ULONG ulBufferSize_p, const char* pszBufferID_p,
                              tShbInstance* ppShbInstance_p,
                              UINT* pfShbNewCreated_p)
{
    tShbError               ShbError;
    UINT                    uiBufferKey;
    BOOL                    fShbNewCreated;
    ULONG                   ulShMemSize;
    tShbMemHeader*          pShbMemHeader;
    tShbMemInst*            pShbMemInst = NULL;
    tShbInstance            pShbInstance;

    ulShMemSize      = ulBufferSize_p + sizeof(tShbMemHeader);

    //create Buffer Key
    uiBufferKey = ShbIpcCrc32GetCrc(pszBufferID_p);

    EPL_DBGLVL_SHB_TRACE("%s() Allocate %lu Bytes, sBufferID:%s BufferKey:%08x\n",
    		          __func__, ulShMemSize, pszBufferID_p, (key_t)uiBufferKey);
    //---------------------------------------------------------------
    // (1) open an existing or create a new shared memory
    //---------------------------------------------------------------
    // try to create shared memory

    if ((pShbMemHeader = ShbIpcFindMem(uiBufferKey)) == NULL)
    {
        fShbNewCreated = TRUE;
        if ((pShbMemHeader = ShbIpcAlloc(uiBufferKey, ulShMemSize)) == NULL)
        {
            //unable to create mem
            EPL_DBGLVL_ERROR_TRACE("%s() Shared memory allocation error!\n",
                                    __func__);
            ShbError = kShbOutOfMem;
            goto Exit;
        }
        else
        {
            EPL_DBGLVL_SHB_TRACE("%s() Shared memory allocated, Addr:%p Key:%08x size:%ld\n",
            		__func__, (void *)pShbMemHeader, uiBufferKey, ulShMemSize);
        }
    }
    else
    {
        EPL_DBGLVL_SHB_TRACE("%s() Attached to shared memory, Addr:%p Key:%08x size:%ld\n",
        		     __func__, (void *)pShbMemHeader, uiBufferKey, ulShMemSize);
        fShbNewCreated = FALSE;
    }

    //---------------------------------------------------------------
    // (2) setup or update header and management information
    //---------------------------------------------------------------

    // allocate a memory block from process specific mempool to save
    // process local information to administrate/manage the shared buffer
    if ((pShbMemInst = (tShbMemInst*)ShbIpcAllocPrivateMem(sizeof(tShbMemInst)))
    		 == NULL)
    {
        EPL_DBGLVL_ERROR_TRACE("%s() Couldn't alloc private mem!\n", __func__);
        ShbError = kShbOutOfMem;
        goto Exit;
    }

    memset(pShbMemInst, 0, sizeof(tShbMemInst));

    // reset complete header to default values
    pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
    pShbMemInst->m_uiSharedMemId = uiBufferKey;
    strncpy(pShbMemInst->m_sBufId, pszBufferID_p, MAX_LEN_BUFFER_ID - 1);
    pShbMemInst->m_pfnSigHndlrNewData = NULL;
    pShbMemInst->m_fNewDataThreadStarted = FALSE;
    pShbMemInst->m_ulTimeOutMsJobReady = 0;
    pShbMemInst->m_pfnSigHndlrJobReady = NULL;
    pShbMemInst->m_pShbMemHeader = pShbMemHeader;
    pShbMemInst->m_fThreadTermFlag = FALSE;

    ShbError = kShbOk;

    if (fShbNewCreated)
    {
        memset (pShbMemHeader, 0, sizeof(tShbMemHeader));

        // this process was the first who wanted to use the shared memory,
        // so a new shared memory was created
        // -> setup new header information inside the shared memory region
        //    itself
        pShbMemHeader->m_ulShMemSize = ulShMemSize;
        pShbMemHeader->m_ulRefCount = 1;
        pShbMemHeader->m_uiBufferKey = uiBufferKey;

        //create semaphores for buffer access and signal new data
        if ((pShbMemHeader->m_mutexBuffAccess =
        		       semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE)) == NULL)
        {
            ShbError = kShbOutOfMem;
            goto Exit;
        }

        if ((pShbMemHeader->m_semNewData = semCCreate(SEM_Q_PRIORITY, 0)) == NULL)
        {
            ShbError = kShbOutOfMem;
            goto Exit;
        }

        if ((pShbMemHeader->m_semStopSignalingNewData =
        		                         semCCreate(SEM_Q_PRIORITY, 0)) == NULL)
        {
            ShbError = kShbOutOfMem;
            goto Exit;
        }

        if ((pShbMemHeader->m_semJobReady = semCCreate(SEM_Q_PRIORITY, 0)) == NULL)
        {
            ShbError = kShbOutOfMem;
            goto Exit;
        }
    }
    else
    {
        // any other process has created the shared memory and this
        // process has only attached to it
        // -> check and update existing header information inside the
        //    shared memory region itself
        if (pShbMemHeader->m_uiBufferKey != uiBufferKey)
        {
            EPL_DBGLVL_ERROR_TRACE("%s() Shared Mem mismatch buffer key %x:%x!\n",
            		__func__, uiBufferKey, pShbMemHeader->m_uiBufferKey);
            ShbError = kShbOpenMismatch;
            goto Exit;

        }
        //TRACEX("%s() Check mem size is:%ld should be:%ld \n", __func__,
        //       pShbMemHeader->m_ulShMemSize, ulShMemSize);
        if (pShbMemHeader->m_ulShMemSize != ulShMemSize)
        {
            EPL_DBGLVL_ERROR_TRACE("%s() Shared Mem mismatch size! %ld:%ld\n",
            		      __func__, ulShMemSize, pShbMemHeader->m_ulShMemSize);
            ShbError = kShbOpenMismatch;
            goto Exit;
        }
        pShbMemHeader->m_ulRefCount++;
    }

Exit:
    if (ShbError != kShbOk)
    {
        EPL_DBGLVL_ERROR_TRACE("%s() allocating shared buf failed!\n (%d)",
        		                __func__, ShbError);
        if (pShbMemInst != NULL)
        {
            ShbIpcReleasePrivateMem (pShbMemInst);
        }
        if ((pShbMemHeader != NULL) && (fShbNewCreated))
        {
            ShbIpcFree(uiBufferKey);
        }
    }

    pShbInstance = (tShbInstance*)pShbMemInst;
    *pfShbNewCreated_p = fShbNewCreated;
    *ppShbInstance_p   = pShbInstance;

    return (ShbError);
}
tShbError  ShbIpcAllocBuffer (
    unsigned long ulBufferSize_p,
    const char* pszBufferID_p,
    tShbInstance* ppShbInstance_p,
    unsigned int* pfShbNewCreated_p)
{
tShbError               ShbError;
int                     iBufferId=0;
unsigned long           ulCrc32=0;
unsigned int            uiFirstProcess=0;
unsigned long           ulShMemSize;
tShbMemHeader*          pShbMemHeader;
tShbMemInst*            pShbMemInst=NULL;
tShbInstance            pShbInstance;
unsigned int            fShMemNewCreated=FALSE;
void                    *pSharedMem=NULL;
struct sShbMemTable     *psMemTableElement;


    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer \n");
    ulShMemSize      = ulBufferSize_p + sizeof(tShbMemHeader);

    //create Buffer ID
#ifndef CONFIG_CRC32
    {
        unsigned long           aulCrcTable[256];
        ShbIpcCrc32GenTable(aulCrcTable);
        ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable);
    }
#else
    ulCrc32 = crc32(0xFFFFFFFF, pszBufferID_p, strlen(pszBufferID_p));
#endif

    iBufferId=ulCrc32;
    DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",ulBufferSize_p,sizeof(tShbMemHeader));
    DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",iBufferId,ulShMemSize);
    //---------------------------------------------------------------
    // (1) open an existing or create a new shared memory
    //---------------------------------------------------------------
    //test if buffer already exists
    if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0)
    {
        //Buffer already exists
        fShMemNewCreated=FALSE;
        pSharedMem = psMemTableElement->m_pBuffer;
        DEBUG_LVL_29_TRACE1("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",pSharedMem);
        uiFirstProcess=1;
    }
    else
    {
        //create new Buffer
        fShMemNewCreated = TRUE;
        uiFirstProcess=0;
        pSharedMem = kmalloc(ulShMemSize,GFP_KERNEL);
        DEBUG_LVL_29_TRACE2("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",pSharedMem,iBufferId);
        if (pSharedMem == NULL)
        {
            //unable to create mem
            ShbError = kShbOutOfMem;
            goto Exit;
        }
        DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer create semas\n");
        // append Element to Mem Table
        psMemTableElement = kmalloc(sizeof(struct sShbMemTable),GFP_KERNEL);
        psMemTableElement->m_iBufferId = iBufferId;
        psMemTableElement->m_pBuffer = pSharedMem;
        psMemTableElement->m_psNextMemTableElement = NULL;
        ShbIpcAppendListElement (psMemTableElement);
    }

    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer update header\n");
    //update header
    pShbMemHeader = (tShbMemHeader*)pSharedMem;
    DEBUG_LVL_29_TRACE1("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",pShbMemHeader->m_ulShMemSize);
    // allocate a memory block from process specific mempool to save
    // process local information to administrate/manage the shared buffer
    DEBUG_LVL_29_TRACE0("ShbIpcAllocBuffer alloc private mem\n");
    pShbMemInst = (tShbMemInst*) ShbIpcAllocPrivateMem (sizeof(tShbMemInst));
    if (pShbMemInst == NULL)
    {
        ShbError = kShbOutOfMem;
        goto Exit;
    }

    // reset complete header to default values
    //pShbMemInst->m_SbiMagicID                             = SBI_MAGIC_ID;
//    pShbMemInst->m_pSharedMem                               = pSharedMem;
    pShbMemInst->m_tThreadNewDataId                         = INVALID_ID;
    pShbMemInst->m_tThreadJobReadyId                        = INVALID_ID;
    pShbMemInst->m_pfnSigHndlrNewData                       = NULL;
    pShbMemInst->m_ulTimeOutMsJobReady                      = 0;
    pShbMemInst->m_pfnSigHndlrJobReady                      = NULL;
    sema_init(&pShbMemInst->m_SemaphoreStopThreadJobReady, 1);
    pShbMemInst->m_pShbMemHeader                            = pShbMemHeader;

    ShbError         = kShbOk;
    if ( fShMemNewCreated )
    {
        // this process was the first who wanted to use the shared memory,
        // so a new shared memory was created
        // -> setup new header information inside the shared memory region
        //    itself
        pShbMemHeader->m_ulShMemSize = ulShMemSize;
        pShbMemHeader->m_ulRefCount  = 1;
        pShbMemHeader->m_iBufferId=iBufferId;
        pShbMemHeader->m_pShbInstMaster = NULL;
        // initialize spinlock
        spin_lock_init(&pShbMemHeader->m_SpinlockBuffAccess);
        // initialize wait queues
        init_waitqueue_head(&pShbMemHeader->m_WaitQueueNewData);
        init_waitqueue_head(&pShbMemHeader->m_WaitQueueJobReady);
    }
    else
    {
        // any other process has created the shared memory and this
        // process only has to attach to it
        // -> check and update existing header information inside the
        //    shared memory region itself
        if (pShbMemHeader->m_ulShMemSize != ulShMemSize)
        {
            ShbError = kShbOpenMismatch;
            goto Exit;
        }
        pShbMemHeader->m_ulRefCount++;
    }

    Exit:
    pShbInstance = (tShbInstance*)pShbMemInst;
    *pfShbNewCreated_p = fShMemNewCreated;
    *ppShbInstance_p   = pShbInstance;
    return (ShbError);

}
Esempio n. 3
0
tShbError  ShbIpcAllocBuffer (
    unsigned long ulBufferSize_p,
    const char* pszBufferID_p,
    tShbInstance* ppShbInstance_p,
    unsigned int* pfShbNewCreated_p)
{
tShbError               ShbError;
int                     iBufferId=0;
unsigned long           ulCrc32=0;
unsigned int            uiFirstProcess=0;
unsigned long           ulShMemSize;
tShbMemHeader*          pShbMemHeader;
tShbMemInst*            pShbMemInst=NULL;
tShbInstance            pShbInstance;
unsigned int            fShMemNewCreated=FALSE;
void                    *pSharedMem=NULL;
struct sShbMemTable     *psMemTableElement;
unsigned long           aulCrcTable[256];

    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer \n");
    if (ShbTgtIsInterruptContext())
    {
        ShbError = kShbInterruptContextNotAllowed;
        goto Exit;
    }

    ulShMemSize      = ulBufferSize_p + sizeof(tShbMemHeader);

    //create Buffer ID
    ShbIpcCrc32GenTable(aulCrcTable);
    ulCrc32 = ShbIpcCrc32GetCrc(pszBufferID_p, aulCrcTable);

    iBufferId=ulCrc32;
    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer BufferSize:%d sizeof(tShb..):%d\n",ulBufferSize_p,sizeof(tShbMemHeader));
    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer BufferId:%d MemSize:%d\n",iBufferId,ulShMemSize);
    //---------------------------------------------------------------
    // (1) open an existing or create a new shared memory
    //---------------------------------------------------------------
    //test if buffer already exists
    if (ShbIpcFindListElement(iBufferId, &psMemTableElement) == 0)
    {
        //Buffer already exists
        fShMemNewCreated=FALSE;
        pSharedMem = psMemTableElement->m_pBuffer;
        DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer attach Buffer at:%p Id:%d\n",pSharedMem, iBufferId);
        uiFirstProcess=1;
    }
    else
    {
        //create new Buffer
        fShMemNewCreated = TRUE;
        uiFirstProcess=0;
        pSharedMem = malloc(ulShMemSize);
        DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer Create New Buffer at:%p Id:%d\n",pSharedMem,iBufferId);
        if (pSharedMem == NULL)
        {
            //unable to create mem
            ShbError = kShbOutOfMem;
            goto Exit;
        }
        // append Element to Mem Table
        psMemTableElement = malloc(sizeof(struct sShbMemTable));
        psMemTableElement->m_iBufferId = iBufferId;
        psMemTableElement->m_pBuffer = pSharedMem;
        psMemTableElement->m_psNextMemTableElement = NULL;
        ShbIpcAppendListElement (psMemTableElement);
    }

    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer update header\n");
    //update header
    pShbMemHeader = (tShbMemHeader*)pSharedMem;

    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer 0 pShbMemHeader->m_ulShMemSize: %d\n",pShbMemHeader->m_ulShMemSize);
    // allocate a memory block for instance local information
    // to administrate/manage the shared buffer
    DEBUG_LVL_29_TRACE("ShbIpcAllocBuffer alloc private mem\n");

    pShbMemInst = (tShbMemInst*) malloc(sizeof(tShbMemInst));
    if (pShbMemInst == NULL)
    {
        ShbError = kShbOutOfMem;
        goto Exit;
    }

    // reset complete header to default values
    //pShbMemInst->m_SbiMagicID                             = SBI_MAGIC_ID;
    pShbMemInst->m_pfnSigHndlrNewData                       = NULL;
    pShbMemInst->m_ulTimeOutMsJobReady                      = 0;
    pShbMemInst->m_ulStartTimeMsJobReady                    = 0;
    pShbMemInst->m_pfnSigHndlrJobReady                      = NULL;
    pShbMemInst->m_pShbMemHeader                            = pShbMemHeader;
    pShbMemInst->m_pProcessListNewDataNext                  = NULL;
    pShbMemInst->m_pProcessListJobReadyNext                 = NULL;

    // initialize
    ShbError         = kShbOk;
    if ( fShMemNewCreated )
    {
        // this process was the first who wanted to use the shared memory,
        // so a new shared memory was created
        // -> setup new header information inside the shared memory region
        //    itself
        pShbMemHeader->m_ulShMemSize = ulShMemSize;
        pShbMemHeader->m_ulRefCount  = 1;
        pShbMemHeader->m_iBufferId   = iBufferId;
        pShbMemHeader->m_pShbInstMaster = NULL;
    }
    else
    {
        // any other process has created the shared memory and this
        // process only has to attach to it
        // -> check and update existing header information inside the
        //    shared memory region itself
        if (pShbMemHeader->m_ulShMemSize != ulShMemSize)
        {
            ShbError = kShbOpenMismatch;
            goto Exit;
        }
        pShbMemHeader->m_ulRefCount++;
    }

Exit:
    pShbInstance = (tShbInstance*)pShbMemInst;
    *pfShbNewCreated_p = fShMemNewCreated;
    *ppShbInstance_p   = pShbInstance;
    return (ShbError);

}