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