Пример #1
0
int GDALRasterBlock::FlushCacheBlock(int bDirtyBlocksOnly)

{
    GDALRasterBlock *poTarget;

    {
        INITIALIZE_LOCK;
        poTarget = poOldest;

        while( poTarget != NULL && (poTarget->GetLockCount() > 0 ||
                                    (bDirtyBlocksOnly && !poTarget->GetDirty())) )
            poTarget = poTarget->poPrevious;

        if( poTarget == NULL )
            return FALSE;

        poTarget->Detach_unlocked();
        poTarget->GetBand()->UnreferenceBlock(poTarget->GetXOff(),poTarget->GetYOff());
    }

    if( poTarget->GetDirty() )
    {
        CPLErr eErr = poTarget->Write();
        if( eErr != CE_None )
        {
            /* Save the error for later reporting */
            poTarget->GetBand()->SetFlushBlockErr(eErr);
        }
    }
    delete poTarget;

    return TRUE;
}
Пример #2
0
int GDALRasterBlock::FlushCacheBlock( int bDirtyBlocksOnly )

{
    GDALRasterBlock *poTarget;

    {
        INITIALIZE_LOCK;
        poTarget = poOldest;

        while( poTarget != NULL )
        {
            if( !bDirtyBlocksOnly || poTarget->GetDirty() )
            {
                if( CPLAtomicCompareAndExchange(
                        &(poTarget->nLockCount), 0, -1) )
                    break;
            }
            poTarget = poTarget->poPrevious;
        }

        if( poTarget == NULL )
            return FALSE;
        if( bSleepsForBockCacheDebug )
            CPLSleep(CPLAtof(
                CPLGetConfigOption(
                    "GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_DROP_LOCK", "0")));

        poTarget->Detach_unlocked();
        poTarget->GetBand()->UnreferenceBlock(poTarget);
    }

    if( bSleepsForBockCacheDebug )
        CPLSleep(CPLAtof(
            CPLGetConfigOption("GDAL_RB_FLUSHBLOCK_SLEEP_AFTER_RB_LOCK", "0")));

    if( poTarget->GetDirty() )
    {
        const CPLErr eErr = poTarget->Write();
        if( eErr != CE_None )
        {
            // Save the error for later reporting.
            poTarget->GetBand()->SetFlushBlockErr(eErr);
        }
    }

    VSIFree(poTarget->pData);
    poTarget->pData = NULL;
    poTarget->GetBand()->AddBlockToFreeList(poTarget);

    return TRUE;
}
int GDALRasterBlock::FlushCacheBlock()

{
    int nXOff, nYOff;
    GDALRasterBand *poBand;

    {
        CPLMutexHolderD( &hRBMutex );
        GDALRasterBlock *poTarget = (GDALRasterBlock *) poOldest;

        while( poTarget != NULL && poTarget->GetLockCount() > 0 ) 
            poTarget = poTarget->poPrevious;
        
        if( poTarget == NULL )
            return FALSE;

        poTarget->Detach();

        nXOff = poTarget->GetXOff();
        nYOff = poTarget->GetYOff();
        poBand = poTarget->GetBand();
    }

    CPLErr eErr = poBand->FlushBlock( nXOff, nYOff );
    if (eErr != CE_None)
    {
        /* Save the error for later reporting */
        poBand->SetFlushBlockErr(eErr);
    }

    return TRUE;
}
Пример #4
0
void GDALRasterBlock::CheckNonOrphanedBlocks( GDALRasterBand* poBand )
{
    TAKE_LOCK;
    for( GDALRasterBlock *poBlock = poNewest;
                          poBlock != NULL;
                          poBlock = poBlock->poNext )
    {
        if ( poBlock->GetBand() == poBand )
        {
            printf("Cache has still blocks of band %p\n", poBand);
            printf("Band : %d\n", poBand->GetBand());
            printf("nRasterXSize = %d\n", poBand->GetXSize());
            printf("nRasterYSize = %d\n", poBand->GetYSize());
            int nBlockXSize, nBlockYSize;
            poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
            printf("nBlockXSize = %d\n", nBlockXSize);
            printf("nBlockYSize = %d\n", nBlockYSize);
            printf("Dataset : %p\n", poBand->GetDataset());
            if( poBand->GetDataset() )
                printf("Dataset : %s\n",
                       poBand->GetDataset()->GetDescription());
        }
    }
}
Пример #5
0
CPLErr GDALRasterBlock::Internalize()

{
    void        *pNewData = NULL;
    int         nSizeInBytes;

    CPLAssert( pData == NULL );

    // This call will initialize the hRBLock mutex. Other call places can
    // only be called if we have go through there.
    GIntBig     nCurCacheMax = GDALGetCacheMax64();

    /* No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo() */
    nSizeInBytes = GetBlockSize();

    /* -------------------------------------------------------------------- */
    /*      Flush old blocks if we are nearing our memory limit.            */
    /* -------------------------------------------------------------------- */
    int bFirstIter = TRUE;
    int bLoopAgain;
    do
    {
        bLoopAgain = FALSE;
        GDALRasterBlock* apoBlocksToFree[64];
        int nBlocksToFree = 0;
        {
            TAKE_LOCK;

            if( bFirstIter )
                nCacheUsed += nSizeInBytes;
            GDALRasterBlock *poTarget = poOldest;
            while( nCacheUsed > nCurCacheMax )
            {
                while( poTarget != NULL && poTarget->GetLockCount() > 0 )
                    poTarget = poTarget->poPrevious;

                if( poTarget != NULL )
                {
                    GDALRasterBlock* _poPrevious = poTarget->poPrevious;

                    poTarget->Detach_unlocked();
                    poTarget->GetBand()->UnreferenceBlock(poTarget->GetXOff(),poTarget->GetYOff());

                    apoBlocksToFree[nBlocksToFree++] = poTarget;
                    if( poTarget->GetDirty() )
                    {
                        // Only free one dirty block at a time so that
                        // other dirty blocks of other bands with the same coordinates
                        // can be found with TryGetLockedBlock()
                        bLoopAgain = ( nCacheUsed > nCurCacheMax );
                        break;
                    }
                    if( nBlocksToFree == 64 )
                    {
                        CPLDebug("GDAL", "More than 64 blocks are flagged to be flushed. Not trying more");
                        break;
                    }

                    poTarget = _poPrevious;
                }
                else
                    break;
            }

            /* -------------------------------------------------------------------- */
            /*      Add this block to the list.                                     */
            /* -------------------------------------------------------------------- */
            if( !bLoopAgain )
                Touch_unlocked();
        }

        bFirstIter = FALSE;

        /* Now free blocks we have detached and removed from their band */
        for(int i=0; i<nBlocksToFree; i++)
        {
            GDALRasterBlock *poBlock = apoBlocksToFree[i];

            if( poBlock->GetDirty() )
            {
                CPLErr eErr = poBlock->Write();
                if( eErr != CE_None )
                {
                    /* Save the error for later reporting */
                    poBlock->GetBand()->SetFlushBlockErr(eErr);
                }
            }

            /* Try to recycle the data of an existing block */
            void* pDataBlock = poBlock->pData;
            if( pNewData == NULL && pDataBlock != NULL &&
                    poBlock->GetBlockSize() >= nSizeInBytes )
            {
                pNewData = pDataBlock;
                poBlock->pData = NULL;
            }

            delete poBlock;
        }
    }
    while(bLoopAgain);

    if( pNewData == NULL )
    {
        pNewData = VSIMalloc( nSizeInBytes );
        if( pNewData == NULL )
        {
            CPLError( CE_Failure, CPLE_OutOfMemory,
                      "GDALRasterBlock::Internalize : Out of memory allocating %d bytes.",
                      nSizeInBytes);
            return( CE_Failure );
        }
    }

    pData = pNewData;

    return( CE_None );
}
Пример #6
0
CPLErr GDALRasterBlock::Internalize()

{
    CPLAssert( pData == NULL );

    void        *pNewData = NULL;

    // This call will initialize the hRBLock mutex. Other call places can
    // only be called if we have go through there.
    const GIntBig nCurCacheMax = GDALGetCacheMax64();

    // No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo().
    const int nSizeInBytes = GetBlockSize();

/* -------------------------------------------------------------------- */
/*      Flush old blocks if we are nearing our memory limit.            */
/* -------------------------------------------------------------------- */
    bool bFirstIter = true;
    bool bLoopAgain = false;
    do
    {
        bLoopAgain = false;
        GDALRasterBlock* apoBlocksToFree[64] = { NULL };
        int nBlocksToFree = 0;
        {
            TAKE_LOCK;

            if( bFirstIter )
                nCacheUsed += nSizeInBytes;
            GDALRasterBlock *poTarget = poOldest;
            while( nCacheUsed > nCurCacheMax )
            {
                while( poTarget != NULL )
                {
                    if( CPLAtomicCompareAndExchange(
                            &(poTarget->nLockCount), 0, -1) )
                        break;
                    poTarget = poTarget->poPrevious;
                }

                if( poTarget != NULL )
                {
                    if( bSleepsForBockCacheDebug )
                        CPLSleep(CPLAtof(
                            CPLGetConfigOption(
                                "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK",
                                "0")));

                    GDALRasterBlock* _poPrevious = poTarget->poPrevious;

                    poTarget->Detach_unlocked();
                    poTarget->GetBand()->UnreferenceBlock(poTarget);

                    apoBlocksToFree[nBlocksToFree++] = poTarget;
                    if( poTarget->GetDirty() )
                    {
                        // Only free one dirty block at a time so that
                        // other dirty blocks of other bands with the same
                        // coordinates can be found with TryGetLockedBlock()
                        bLoopAgain = nCacheUsed > nCurCacheMax;
                        break;
                    }
                    if( nBlocksToFree == 64 )
                    {
                        bLoopAgain = ( nCacheUsed > nCurCacheMax );
                        break;
                    }

                    poTarget = _poPrevious;
                }
                else
                {
                    break;
                }
            }

        /* ------------------------------------------------------------------ */
        /*      Add this block to the list.                                   */
        /* ------------------------------------------------------------------ */
            if( !bLoopAgain )
                Touch_unlocked();
        }

        bFirstIter = false;

        // Now free blocks we have detached and removed from their band.
        for( int i = 0; i < nBlocksToFree; ++i)
        {
            GDALRasterBlock * const poBlock = apoBlocksToFree[i];

            if( poBlock->GetDirty() )
            {
                CPLErr eErr = poBlock->Write();
                if( eErr != CE_None )
                {
                    // Save the error for later reporting.
                    poBlock->GetBand()->SetFlushBlockErr(eErr);
                }
            }

            // Try to recycle the data of an existing block.
            void* pDataBlock = poBlock->pData;
            if( pNewData == NULL && pDataBlock != NULL &&
                poBlock->GetBlockSize() == nSizeInBytes )
            {
                pNewData = pDataBlock;
            }
            else
            {
                VSIFree(poBlock->pData);
            }
            poBlock->pData = NULL;

            poBlock->GetBand()->AddBlockToFreeList(poBlock);
        }
    }
    while(bLoopAgain);

    if( pNewData == NULL )
    {
        pNewData = VSI_MALLOC_VERBOSE( nSizeInBytes );
        if( pNewData == NULL )
        {
            return( CE_Failure );
        }
    }

    pData = pNewData;

    return CE_None;
}