예제 #1
0
//--------------------------------------------------------------------------------------------------
static dstr_Ref_t NewOrFirstSegmentRef
(
    dstr_Ref_t headRef  ///< [IN] The head of the string.
)
//--------------------------------------------------------------------------------------------------
{
    dstr_Ref_t segmentRef = FirstSegmentRef(headRef);

    if (segmentRef != NULL)
    {
        return segmentRef;
    }

    segmentRef = NewSegment();
    le_sls_Stack(&headRef->head.list, &segmentRef->body.link);

    return segmentRef;
}
예제 #2
0
//--------------------------------------------------------------------------------------------------
static void AddDestructor
(
    ThreadObj_t*            threadPtr,  ///< [in] Ptr to the Thread Object to add the destructor to.
    le_thread_Destructor_t  destructor, ///< [in] The function to be called.
    void*                   context     ///< [in] Parameter to pass to the destructor function.
)
{
    // Create the destructor object.
    DestructorObj_t* destructorObjPtr = le_mem_ForceAlloc(DestructorObjPool);

    // Init the destructor object.
    destructorObjPtr->destructor = destructor;
    destructorObjPtr->context = context;
    destructorObjPtr->link = LE_SLS_LINK_INIT;

    // Get a pointer to the calling thread's Thread Object and
    // Add the destructor object to its list.
    le_sls_Stack(&(threadPtr->destructorList), &(destructorObjPtr->link));
}
예제 #3
0
파일: mem.c 프로젝트: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void InitBlock
(
    le_mem_PoolRef_t pool,       ///< [IN] The pool the new block belongs to.
    MemBlock_t* newBlockPtr      ///< [IN] The block being initialized.
)
{
    // Initialize the block.
    #ifndef LE_MEM_VALGRIND
        // Add the block to the pool's free list.
        newBlockPtr->link = LE_SLS_LINK_INIT;
        le_sls_Stack(&(pool->freeList), &(newBlockPtr->link));
    #endif

    newBlockPtr->refCount = 0;
    newBlockPtr->poolPtr = pool;

    #ifdef USE_GUARD_BAND
        InitGuardBands(newBlockPtr);
    #endif
}
예제 #4
0
//--------------------------------------------------------------------------------------------------
static void PushContext
(
    Parser_t* parserPtr,
    le_json_ContextType_t type,
    le_json_EventHandler_t eventHandler
)
//--------------------------------------------------------------------------------------------------
{
    Context_t* contextPtr = le_mem_ForceAlloc(ContextPool);

    contextPtr->link = LE_SLS_LINK_INIT;
    contextPtr->type = type;
    contextPtr->eventHandler = eventHandler;

    le_sls_Stack(&parserPtr->contextStack, &contextPtr->link);

    // Clear the value buffer.
    memset(parserPtr->buffer, 0, sizeof(parserPtr->buffer));
    parserPtr->numBytes = 0;
}
예제 #5
0
파일: mem.c 프로젝트: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
static void MoveBlocks
(
    le_mem_PoolRef_t    destPool,   ///< [IN] The pool to move the blocks to.
    le_mem_PoolRef_t    srcPool,    ///< [IN] The pool to get the blocks from.
    size_t              numBlocks   ///< [IN] The maximum number of blocks to move.
)
{
    #ifndef LE_MEM_VALGRIND
        // Get the first block to move.
        le_sls_Link_t* blockLinkPtr = le_sls_Pop(&(srcPool->freeList));

        size_t i = 0;
        while (i < numBlocks)
        {
            if (blockLinkPtr == NULL)
            {
                LE_FATAL("Asked to move %zu blocks from pool '%s' to pool '%s', "
                         "but only %zu were available.",
                         numBlocks,
                         srcPool->name,
                         destPool->name,
                         i);
            }

            // Add the block to the destination pool.
            le_sls_Stack(&(destPool->freeList), blockLinkPtr);

            // Update the blocks parent pool.
            MemBlock_t* blockPtr = CONTAINER_OF(blockLinkPtr, MemBlock_t, link);
            blockPtr->poolPtr = destPool;

            // Get the next block.
            blockLinkPtr = le_sls_Pop(&(srcPool->freeList));

            i++;
        }
    #endif
}
예제 #6
0
파일: mem.c 프로젝트: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
void le_mem_Release
(
    void*   objPtr  ///< [IN] Pointer to the object to be released.
)
{
    MemBlock_t* blockPtr;

    // Get the block from the object pointer.
    #ifdef USE_GUARD_BAND
        uint8_t* dataPtr = objPtr;
        dataPtr -= GUARD_BAND_SIZE;
        blockPtr = CONTAINER_OF(dataPtr, MemBlock_t, data);
    #else
        blockPtr = CONTAINER_OF(objPtr, MemBlock_t, data);
    #endif

    #ifdef USE_GUARD_BAND
        CheckGuardBands(blockPtr);
    #endif

    Lock();

    switch (blockPtr->refCount)
    {
        case 1:
        {
            MemPool_t* poolPtr = blockPtr->poolPtr;

            // The reference count has reached zero.
            blockPtr->refCount = 0;

            // Call the destructor, if there is one.
            if (poolPtr->destructor)
            {
                // Make sure that the destructor is not called with the mutex locked, because
                // it is not a recursive mutex and therefore will deadlock if locked again by
                // the same thread.  Also, fetch the destructor function address before unlocking
                // the mutex so that we don't touch the pool object while the mutex is unlocked.
                le_mem_Destructor_t destructor = poolPtr->destructor;
                Unlock();
                destructor(objPtr);

                // Re-lock the mutex now so that it is safe to access the pool object again.
                Lock();
            }

            #ifndef LE_MEM_VALGRIND
                // Release the memory back into the pool.
                // Note that we don't do this before calling the destructor because the destructor
                // still needs to access it, but after it goes back on the free list, it could get
                // reallocated by another thread (or even the destructor itself) and have its
                // contents clobbered.
                le_sls_Stack(&(poolPtr->freeList), &(blockPtr->link));
            #else
                free(blockPtr);
            #endif

            poolPtr->numBlocksInUse--;

            break;
        }

        case 0:
            LE_EMERG("Releasing free block.");
            LE_FATAL("Free block released from pool %p (%s).",
                     blockPtr->poolPtr,
                     blockPtr->poolPtr->name);

        default:
            blockPtr->refCount--;
    }

    Unlock();
}
예제 #7
0
파일: main.c 프로젝트: hakanernam/legato-af
static le_result_t TestSinglyLinkLists(size_t maxListSize)
{
    // Node definition.
    typedef struct
    {
        le_sls_Link_t link;
        uint32_t id;  
    }
    idRecord_t;

    int i;
    le_sls_List_t list0, list1;

    printf("\n");
    printf("*** Unit Test for le_singlyLinkedList module. ***\n");

    //
    // Multiple list creation
    //
    // Initialize the lists
    list0 = LE_SLS_LIST_INIT;
    list1 = LE_SLS_LIST_INIT;
    printf("One singly linked list was successfully created.\n");


    //
    // Attempt to query empty list
    //
    if ( (le_sls_Peek(&list0) != NULL) || (le_sls_Pop(&list0) != NULL) )
    {
        printf("Query of empty list failed: %d", __LINE__);
        return LE_FAULT;
    }
    printf("Query of empty list correct.\n");


    //
    // Node insertions
    //
    {
        idRecord_t* newNodePtr;
        le_sls_Link_t* prevLinkPtr;
        
        // Queue nodes to list0.
        for (i = 0; i < maxListSize; i++)
        {
            // Create the new node
            newNodePtr = (idRecord_t*)malloc(sizeof(idRecord_t));
            newNodePtr->id = i;
            
            // Initialize the link.
            newNodePtr->link = LE_SLS_LINK_INIT;

            if (i < maxListSize/2)
            {
                // Insert the new node to the tail.
                le_sls_Queue(&list0, &(newNodePtr->link));
            }
            else
            {
                // Insert to the tail using insert after.
                le_sls_AddAfter(&list0, prevLinkPtr, &(newNodePtr->link));
            }

            prevLinkPtr = &(newNodePtr->link);
        }
        printf("%zu nodes were queued to the tail of list0.\n", maxListSize);
        
        // Stack nodes to list1.
        for (i = 0; i < maxListSize; i++)
        {
            // Create the new node
            newNodePtr = (idRecord_t*)malloc(sizeof(idRecord_t));
            newNodePtr->id = i;
            
            // Initialize the link.
            newNodePtr->link = LE_SLS_LINK_INIT;

            // Insert the new node to the head.
            le_sls_Stack(&list1, &(newNodePtr->link));
        }
        printf("%zu nodes were stacked to the head of list1.\n", maxListSize);
    }

    //
    // Check that all the nodes have been added properly
    //
    {
        idRecord_t* nodePtr;
        le_sls_Link_t* link0Ptr = le_sls_Peek(&list0);
        le_sls_Link_t* link1Ptr = le_sls_Peek(&list1);
        
        if ( (link0Ptr == NULL) || (link1Ptr == NULL) )
        {
            printf("Link error: %d", __LINE__);
            return LE_FAULT;
        }
        
        i = 0;
        do
        {
            // Get the node from list 0
            nodePtr = CONTAINER_OF(link0Ptr, idRecord_t, link);

            // Check the node.
            if ( nodePtr->id != i)
            {
                printf("Link error: %d", __LINE__);
                return LE_FAULT;
            }

            // Get the node from list 1
            nodePtr = CONTAINER_OF(link1Ptr, idRecord_t, link);

            // Check the node.
            if ( nodePtr->id != maxListSize - i - 1)
            {
                printf("Link error: %d", __LINE__);
                return LE_FAULT;
            }

            // Move to the next node.
            link0Ptr = le_sls_PeekNext(&list0, link0Ptr);
            link1Ptr = le_sls_PeekNext(&list1, link1Ptr);
            i++;

        } while (link0Ptr != NULL);
        
        // Make sure everything is correct.
        if ( (i != maxListSize) || (link1Ptr != NULL) )
        {
            printf("Link error: %d", __LINE__);
            return LE_FAULT;
        }
    }
    
    printf("Checked that all nodes added to the head and tails are all correct.\n");
   

    //
    // Pop nodes.
    //
    {
        //pop half the list.
        for (i = 0; i < (maxListSize / 2); i++)
        {
            le_sls_Pop(&list0);
        }
    }
    
    printf("Popped half the nodes from the head of list0.\n");
    
    // Check that the list is still in tact.
    {
        idRecord_t* nodePtr;
        
        // For list 0.
        le_sls_Link_t* linkPtr = le_sls_Peek(&list0);    
        i = maxListSize/2;
        do
        {
            nodePtr = CONTAINER_OF(linkPtr, idRecord_t, link);

            if (nodePtr->id != i++)
            {
                printf("Link error: %d", __LINE__);
                return LE_FAULT;
            }
            
            linkPtr = le_sls_PeekNext(&list0, linkPtr);
        } while (linkPtr != NULL);
        
        // Check that the number of links left is correct.
        if (i != maxListSize)
        {
            printf("Wrong number of links: %d", __LINE__);
            return LE_FAULT;
        }
    }
    printf("Checked that all nodes were properly popped from the lists.\n");


    //
    // Check for list corruption.
    //
    {
        le_sls_Link_t* linkPtr;
        
        if (le_sls_IsListCorrupted(&list0))
        {
            printf("List0 is corrupt but shouldn't be: %d", __LINE__);
            return LE_FAULT;
        }

        // Access one of the links directly.  This should corrupt the list.
        linkPtr = le_sls_Peek(&list0);
        linkPtr = le_sls_PeekNext(&list0, linkPtr);
        linkPtr->nextPtr = NULL;

        if (!le_sls_IsListCorrupted(&list0))
        {
            printf("List0 is not corrupted but should be: %d", __LINE__);
            return LE_FAULT;
        }
    }

    printf("Checked lists for corruption.\n");
    
    printf("*** Unit Test for le_singlyLinkedList module passed. ***\n");
    printf("\n");
    return LE_OK;
}