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);

}
Пример #2
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_TRACE0("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_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_TRACE2("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_TRACE2("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_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 for instance local information
    // to administrate/manage the shared buffer
    DEBUG_LVL_29_TRACE0("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;
    }
    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);

}