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