int ShbIpcThreadSignalJobReady (void *pvThreadParam_p)
{
tShbInstance    pShbInstance;
tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
long            lTimeOutJiffies;
int             iRetVal=-1;

    pShbInstance = (tShbMemInst*)pvThreadParam_p;
    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);

    DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalJobReady wait for job ready Sem\n");
    if (pShbMemInst->m_ulTimeOutMsJobReady != 0)
    {
        lTimeOutJiffies = (long) pShbMemInst->m_ulTimeOutMsJobReady / (1000 / HZ);
        if (lTimeOutJiffies <= 0)
        {   // wait at least 1 jiffy
            lTimeOutJiffies = 1;
        }
        //wait for job ready semaphore
        iRetVal = wait_event_timeout(pShbMemHeader->m_WaitQueueJobReady,
            kthread_should_stop()
            || (pShbMemHeader->m_fJobReady != FALSE),
            lTimeOutJiffies);
    }
    else
    {
        //wait for job ready semaphore
        wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
            kthread_should_stop()
            || (pShbMemHeader->m_fJobReady != FALSE));
    }

    if (pShbMemInst->m_pfnSigHndlrJobReady != NULL)
    {
        //call Handler
        pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, !pShbMemHeader->m_fJobReady);
    }

    pShbMemInst->m_pfnSigHndlrJobReady = NULL;

    if (down_trylock(&pShbMemInst->m_SemaphoreStopThreadJobReady))
    {   // lock failed
        wait_event_interruptible(pShbMemHeader->m_WaitQueueJobReady,
                                 kthread_should_stop());

        pShbMemInst->m_tThreadJobReadyId = INVALID_ID;
    }
    else
    {
        pShbMemInst->m_tThreadJobReadyId = INVALID_ID;
        up(&pShbMemInst->m_SemaphoreStopThreadJobReady);
    }

    DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalJobReady terminated\n");

    return 0;
}
INLINE_FUNCTION tShbError  ShbIpcStopSignalingNewData (
    tShbInstance pShbInstance_p)
{
tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
tShbError       ShbError;

    DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
    if (pShbInstance_p == NULL)
    {
        return (kShbInvalidArg);
    }
    ShbError = kShbOk;
    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);

    DEBUG_LVL_26_TRACE2("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n", pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
    if (pShbMemInst->m_pfnSigHndlrNewData != NULL)
    {   // signal handler was set before
        kthread_stop(pShbMemInst->m_tThreadNewDataId);

        pShbMemInst->m_pfnSigHndlrNewData = NULL;
        pShbMemInst->m_tThreadNewDataId = INVALID_ID;
    }

    return ShbError;

}
Exemplo n.º 3
0
INLINE_FUNCTION tShbError  ShbIpcSignalJobReady (
    tShbInstance pShbInstance_p)
{
tShbMemHeader*  pShbMemHeader;

    DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady\n");
    if (pShbInstance_p == NULL)
    {
        return (kShbInvalidArg);
    }
    pShbMemHeader = ShbIpcGetShbMemHeader (ShbIpcGetShbMemInst (pShbInstance_p));
    //set semaphore
    pShbMemHeader->m_fJobReady = TRUE;
    DEBUG_LVL_29_TRACE0("ShbIpcSignalJobReady set Sem -> Job Ready \n");

    return (kShbOk);
}
INLINE_FUNCTION tShbError  ShbIpcStartSignalingNewData (
    tShbInstance pShbInstance_p,
    tSigHndlrNewData pfnSignalHandlerNewData_p,
    tShbPriority ShbPriority_p)
{
tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
tShbError       ShbError;

    DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
    if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL))
    {
        return (kShbInvalidArg);
    }

    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
    ShbError = kShbOk;

    if ((pShbMemInst->m_tThreadNewDataId != INVALID_ID)
        || (pShbMemInst->m_pfnSigHndlrNewData != NULL))
    {
        ShbError = kShbAlreadySignaling;
        goto Exit;
    }
    DEBUG_LVL_26_TRACE2("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n", pShbInstance_p, pfnSignalHandlerNewData_p);
    pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
    pShbMemHeader->m_fNewData = FALSE;

    switch (ShbPriority_p)
    {
        case kShbPriorityLow:
            pShbMemInst->m_lThreadNewDataNice = -2;
            break;

        case kShbPriorityNormal:
            pShbMemInst->m_lThreadNewDataNice = -9;
            break;

        case kShbPriorityHigh:
            pShbMemInst->m_lThreadNewDataNice = -20;
            break;

    }

    //create thread for signalling new data
    pShbMemInst->m_tThreadNewDataId = kthread_run(ShbIpcThreadSignalNewData,
                                                  pShbInstance_p,
                                                  "ShbND%p", pShbInstance_p);

Exit:
    return ShbError;

}
Exemplo n.º 5
0
INLINE_FUNCTION tShbError  ShbIpcStartSignalingNewData (
    tShbInstance pShbInstance_p,
    tSigHndlrNewData pfnSignalHandlerNewData_p,
    tShbPriority ShbPriority_p)
{
tShbMemInst*    pShbMemInst;
tShbMemInst**   ppShbMemInst;
tShbMemHeader*  pShbMemHeader;
tShbError       ShbError;

    DEBUG_LVL_29_TRACE0("------->ShbIpcStartSignalingNewData\n");
    if (ShbTgtIsInterruptContext())
    {
        return (kShbInterruptContextNotAllowed);
    }

    if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL))
    {
        return (kShbInvalidArg);
    }

    pShbMemInst   = ShbIpcGetShbMemInst(pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader(pShbMemInst);
    ShbError = kShbOk;

    if (pShbMemInst->m_pfnSigHndlrNewData != NULL)
    {
        ShbError = kShbAlreadySignaling;
        goto Exit;
    }
    DEBUG_LVL_26_TRACE2("ShbIpcStartSignalingNewData(%p) m_pfnSigHndlrNewData = %p\n", pShbInstance_p, pfnSignalHandlerNewData_p);
    pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
    pShbMemInst->m_PriorityNewData = ShbPriority_p;
    pShbMemHeader->m_fNewData = FALSE;

    // insert ShbMemInst into NewData process list
    // higher priority entries first
    ppShbMemInst = &pShbIpcProcessListNewDataFirst_g;
    while (*ppShbMemInst != NULL)
    {
        if ((*ppShbMemInst)->m_PriorityNewData < pShbMemInst->m_PriorityNewData)
        {
            break;
        }
        ppShbMemInst = &(*ppShbMemInst)->m_pProcessListNewDataNext;
    }
    pShbMemInst->m_pProcessListNewDataNext = *ppShbMemInst;
    *ppShbMemInst = pShbMemInst;

Exit:
    return ShbError;

}
Exemplo n.º 6
0
INLINE_FUNCTION tShbError  ShbIpcStopSignalingNewData (
    tShbInstance pShbInstance_p)
{
tShbMemInst*    pShbMemInst;
tShbMemInst**   ppShbMemInst;
tShbMemHeader*  pShbMemHeader;
tShbError       ShbError;

    DEBUG_LVL_29_TRACE0("------->ShbIpcStopSignalingNewData\n");
    if (ShbTgtIsInterruptContext())
    {
        return (kShbInterruptContextNotAllowed);
    }

    if (pShbInstance_p == NULL)
    {
        return (kShbInvalidArg);
    }
    ShbError = kShbOk;
    pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);

    DEBUG_LVL_26_TRACE2("ShbIpcStopSignalingNewData(%p) pfnSignHndlrNewData=%p\n", pShbInstance_p, pShbMemInst->m_pfnSigHndlrNewData);
    if (pShbMemInst->m_pfnSigHndlrNewData != NULL)
    {   // signal handler was set before
        // remove pShbMemInst from NewData process list
        ShbError = kShbInvalidSigHndlr;
        ppShbMemInst = &pShbIpcProcessListNewDataFirst_g;
        while (*ppShbMemInst != NULL)
        {
            if (*ppShbMemInst == pShbMemInst)
            {
                *ppShbMemInst = pShbMemInst->m_pProcessListNewDataNext;
                pShbMemInst->m_pProcessListNewDataNext = NULL;
                pShbMemInst->m_pfnSigHndlrNewData = NULL;

                if (ppShbIpcProcessListNewDataCurrent_g == &pShbMemInst->m_pProcessListNewDataNext)
                {
                    ppShbIpcProcessListNewDataCurrent_g = ppShbMemInst;
                }

                ShbError = kShbOk;
                break;
            }
            ppShbMemInst = &(*ppShbMemInst)->m_pProcessListNewDataNext;
        }
    }

    return ShbError;

}
int ShbIpcThreadSignalNewData (void *pvThreadParam_p)
{
tShbInstance    pShbInstance;
tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
int             fCallAgain;

    pShbInstance = (tShbMemInst*)pvThreadParam_p;
    pShbMemInst  = ShbIpcGetShbMemInst (pShbInstance);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);

    DEBUG_LVL_26_TRACE1("ShbIpcThreadSignalNewData(%p)\n",pvThreadParam_p);

    set_user_nice(current, pShbMemInst->m_lThreadNewDataNice);

#ifdef CONFIG_PREEMPT_RT
    if (pShbMemInst->m_lThreadNewDataNice == -20) // highest priority
    {
    struct sched_param  rt_prio;
        rt_prio.sched_priority = 79;
        sched_setscheduler(current, SCHED_FIFO, &rt_prio);
    }
#endif

//            DEBUG_LVL_29_TRACE1("ShbIpcThreadSignalNewData wait for New Data Sem %p\n",pShbMemInst->m_pSemNewData);
    while (!kthread_should_stop())
    {
        wait_event_interruptible(pShbMemHeader->m_WaitQueueNewData,
            kthread_should_stop()
            || (pShbMemHeader->m_fNewData != FALSE));

        if (pShbMemHeader->m_fNewData != FALSE)
        {
            pShbMemHeader->m_fNewData = FALSE;
            do
            {
                fCallAgain = pShbMemInst->m_pfnSigHndlrNewData(pShbInstance);
                // call scheduler, which will execute any task with higher priority
                schedule();
            } while (fCallAgain != FALSE);
        }
    }

    DEBUG_LVL_29_TRACE0("ShbIpcThreadSignalNewData terminated \n");

    return 0;
}
static void*  ShbIpcAllocPrivateMem (unsigned long ulMemSize_p)
{
tShbError       ShbError;
void*           pMem;

    DEBUG_LVL_29_TRACE0("ShbIpcAllocPrivateMem \n");
    //get private mem
    pMem = kmalloc(ulMemSize_p, GFP_KERNEL);
    if (pMem == NULL)
    {
        //unable to create mem
        ShbError = kShbOutOfMem;
        goto Exit;
    }
Exit:
    return (pMem);

}
INLINE_FUNCTION tShbError  ShbIpcLeaveAtomicSection (
    tShbInstance pShbInstance_p)
{

tShbMemInst*    pShbMemInst;
tShbMemHeader*  pShbMemHeader;
tShbError       ShbError = kShbOk;

    if (pShbInstance_p == NULL)
    {
        ShbError = kShbInvalidArg;
        goto Exit;
    }
    pShbMemInst   = ShbIpcGetShbMemInst   (pShbInstance_p);
    pShbMemHeader = ShbIpcGetShbMemHeader (pShbMemInst);
    // unlock interrupts
    spin_unlock_irqrestore(&pShbMemHeader->m_SpinlockBuffAccess, pShbMemInst->m_ulFlagsBuffAccess);

Exit:
    DEBUG_LVL_29_TRACE0("Leave Atomic \n");
    return ShbError;

}
tShbError  ShbIpcSignalNewData (
    tShbInstance pShbInstance_p)
{
tShbMemHeader*  pShbMemHeader;

    if (pShbInstance_p == NULL)
    {
        return (kShbInvalidArg);
    }
    pShbMemHeader = ShbIpcGetShbMemHeader (ShbIpcGetShbMemInst (pShbInstance_p));
    //set semaphore
    pShbMemHeader->m_fNewData = TRUE;
    DEBUG_LVL_29_TRACE0("ShbIpcSignalNewData set Sem -> New Data\n");

    wake_up(&pShbMemHeader->m_WaitQueueNewData);

    if (pShbMemHeader->m_pShbInstMaster != NULL)
    {
        return ShbIpcSignalNewData(pShbMemHeader->m_pShbInstMaster);
    }

    return (kShbOk);
}
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);

}
Exemplo n.º 12
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);

}