Lines Matching refs:cache

285 								BlockWriter(block_cache* cache,
300 static status_t WriteBlock(block_cache* cache,
330 inline bool Lock(block_cache* cache)
332 mutex_lock(&cache->lock);
334 while (cache->busy_writing_count != 0) {
337 cache->busy_writing_condition.Add(&entry);
338 cache->busy_writing_waiters = true;
340 mutex_unlock(&cache->lock);
344 mutex_lock(&cache->lock);
350 inline void Unlock(block_cache* cache)
352 mutex_unlock(&cache->lock);
366 Action(block_cache* cache, cached_block* block)
368 fCache(cache),
384 out.Print("block cache %p, %s %" B_PRIu64 ", %c%c%c transaction %" B_PRId32
404 Get(block_cache* cache, cached_block* block)
406 Action(cache, block)
416 Put(block_cache* cache, cached_block* block)
418 Action(cache, block)
428 Read(block_cache* cache, cached_block* block)
430 Action(cache, block)
440 Write(block_cache* cache, cached_block* block)
442 Action(cache, block)
452 Flush(block_cache* cache, cached_block* block, bool getUnused = false)
454 Action(cache, block),
469 Error(block_cache* cache, uint64 blockNumber, const char* message,
472 fCache(cache),
482 out.Print("block cache %p, error %" B_PRIu64 ", %s%s%s",
503 BlockData(block_cache* cache, cached_block* block, const char* message)
505 fCache(cache),
506 fSize(cache->block_size),
524 out.Print("block cache %p, block %" B_PRIu64 ", data %c%c%c: %s",
637 Action(const char* label, block_cache* cache,
640 fCache(cache),
653 out.Print("block cache %p, %s transaction %p (id %" B_PRId32 ")%s"
670 Detach(block_cache* cache, cache_transaction* transaction,
673 fCache(cache),
685 out.Print("block cache %p, detach transaction %p (id %" B_PRId32 ")"
702 Abort(block_cache* cache, cache_transaction* transaction)
704 fCache(cache),
732 out.Print("block cache %p, abort transaction "
771 = MUTEX_INITIALIZER("block cache notifications");
820 flush_pending_notifications(block_cache* cache)
827 cache_notification* notification = cache->pending_notifications.Head();
835 cache->pending_notifications.Remove(notification);
858 Must not be called with a cache lock held.
867 block_cache* cache = iterator.Next();
869 flush_pending_notifications(cache);
911 add_notification(block_cache* cache, cache_notification* notification,
923 cache->pending_notifications.Add(notification);
941 notify_transaction_listeners(block_cache* cache, cache_transaction* transaction,
944 T(Action("notify", cache, transaction));
959 add_notification(cache, listener, event, remove);
970 remove_transaction_listeners(block_cache* cache, cache_transaction* transaction)
983 add_transaction_listener(block_cache* cache, cache_transaction* transaction,
1024 delete_transaction(block_cache* cache, cache_transaction* transaction)
1026 if (cache->last_transaction == transaction)
1027 cache->last_transaction = NULL;
1029 remove_transaction_listeners(cache, transaction);
1035 lookup_transaction(block_cache* cache, int32 id)
1037 return cache->transaction_hash->Lookup(id);
1063 write_blocks_in_previous_transaction(block_cache* cache,
1066 BlockWriter writer(cache);
1095 BlockWriter::BlockWriter(block_cache* cache, size_t max)
1097 fCache(cache),
1255 BlockWriter::WriteBlock(block_cache* cache, cached_block* block)
1257 BlockWriter writer(cache);
1332 TRACE(("cache transaction %" B_PRId32 " finished!\n", previous->id));
1421 /*! Should be called with the cache's lock held. */
1438 busy_reading_condition.Init(this, "cache block busy_reading");
1439 busy_writing_condition.Init(this, "cache block busy writing");
1440 condition_variable.Init(this, "cache transaction sync");
1441 mutex_init(&lock, "block cache");
1443 buffer_cache = create_object_cache_etc("block cache buffers", block_size,
1643 block_cache* cache = (block_cache*)data;
1644 if (cache->unused_block_count <= 1)
1653 free = cache->unused_block_count / 4;
1657 free = cache->unused_block_count / 2;
1661 free = cache->unused_block_count - 1;
1666 MutexLocker locker(&cache->lock);
1676 uint32 oldUnused = cache->unused_block_count;
1679 cache->RemoveUnusedBlocks(free, secondsOld);
1682 cache, oldUnused, cache->unused_block_count));
1724 mark_block_busy_reading(block_cache* cache, cached_block* block)
1727 cache->busy_reading_count++;
1734 mark_block_unbusy_reading(block_cache* cache, cached_block* block)
1737 cache->busy_reading_count--;
1739 if ((cache->busy_reading_waiters && cache->busy_reading_count == 0)
1741 cache->busy_reading_waiters = false;
1743 cache->busy_reading_condition.NotifyAll();
1751 wait_for_busy_reading_block(block_cache* cache, cached_block* block)
1756 cache->busy_reading_condition.Add(&entry);
1759 mutex_unlock(&cache->lock);
1763 mutex_lock(&cache->lock);
1771 wait_for_busy_reading_blocks(block_cache* cache)
1773 while (cache->busy_reading_count != 0) {
1776 cache->busy_reading_condition.Add(&entry);
1777 cache->busy_reading_waiters = true;
1779 mutex_unlock(&cache->lock);
1783 mutex_lock(&cache->lock);
1791 wait_for_busy_writing_block(block_cache* cache, cached_block* block)
1796 cache->busy_writing_condition.Add(&entry);
1799 mutex_unlock(&cache->lock);
1803 mutex_lock(&cache->lock);
1811 wait_for_busy_writing_blocks(block_cache* cache)
1813 while (cache->busy_writing_count != 0) {
1816 cache->busy_writing_condition.Add(&entry);
1817 cache->busy_writing_waiters = true;
1819 mutex_unlock(&cache->lock);
1823 mutex_lock(&cache->lock);
1834 put_cached_block(block_cache* cache, cached_block* block)
1838 && memcmp(block->current_data, block->compare, cache->block_size)) {
1843 BlockWriter::WriteBlock(cache, block);
1846 cache->Free(block->compare);
1850 TB(Put(cache, block));
1853 panic("Invalid ref_count for block %p, cache %p\n", block, cache);
1863 cache->RemoveBlock(block);
1870 cache->unused_blocks.Add(block);
1871 cache->unused_block_count++;
1878 put_cached_block(block_cache* cache, off_t blockNumber)
1880 if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
1882 blockNumber, cache->max_blocks - 1);
1885 cached_block* block = cache->hash->Lookup(blockNumber);
1887 put_cached_block(cache, block);
1889 TB(Error(cache, blockNumber, "put unknown"));
1896 You need to have the cache locked when calling this function.
1901 not already in the cache. The block you retrieve may contain random
1902 data. If \c true, the cache will be temporarily unlocked while the
1906 get_cached_block(block_cache* cache, off_t blockNumber, bool* _allocated,
1909 ASSERT_LOCKED_MUTEX(&cache->lock);
1911 if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
1913 blockNumber, cache->max_blocks - 1);
1918 cached_block* block = cache->hash->Lookup(blockNumber);
1922 // put block into cache
1923 block = cache->NewBlock(blockNumber);
1927 cache->hash->Insert(block);
1931 wait_for_busy_reading_block(cache, block);
1938 cache->unused_blocks.Remove(block);
1939 cache->unused_block_count--;
1943 // read block into cache
1944 int32 blockSize = cache->block_size;
1946 mark_block_busy_reading(cache, block);
1947 mutex_unlock(&cache->lock);
1949 ssize_t bytesRead = read_pos(cache->fd, blockNumber * blockSize,
1952 mutex_lock(&cache->lock);
1954 cache->RemoveBlock(block);
1955 TB(Error(cache, blockNumber, "read failed", bytesRead));
1961 TB(Read(cache, block));
1963 mark_block_unbusy_reading(cache, block);
1982 get_writable_cached_block(block_cache* cache, off_t blockNumber, off_t base,
1988 if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
1990 blockNumber, cache->max_blocks - 1);
1996 status_t status = get_cached_block(cache, blockNumber, &allocated,
2002 wait_for_busy_writing_block(cache, block);
2009 mark_block_busy_reading(cache, block);
2010 mutex_unlock(&cache->lock);
2012 memset(block->current_data, 0, cache->block_size);
2014 mutex_lock(&cache->lock);
2015 mark_block_unbusy_reading(cache, block);
2021 cache->num_dirty_blocks++;
2026 TB(Get(cache, block));
2038 put_cached_block(cache, block);
2043 transaction = lookup_transaction(cache, transactionID);
2047 put_cached_block(cache, block);
2052 put_cached_block(cache, block);
2071 block->original_data = cache->Allocate();
2073 TB(Error(cache, blockNumber, "allocate original failed"));
2075 put_cached_block(cache, block);
2079 mark_block_busy_reading(cache, block);
2080 mutex_unlock(&cache->lock);
2082 memcpy(block->original_data, block->current_data, cache->block_size);
2084 mutex_lock(&cache->lock);
2085 mark_block_unbusy_reading(cache, block);
2089 block->parent_data = cache->Allocate();
2093 TB(Error(cache, blockNumber, "allocate parent failed"));
2095 put_cached_block(cache, block);
2099 mark_block_busy_reading(cache, block);
2100 mutex_unlock(&cache->lock);
2102 memcpy(block->parent_data, block->current_data, cache->block_size);
2104 mutex_lock(&cache->lock);
2105 mark_block_unbusy_reading(cache, block);
2113 mark_block_busy_reading(cache, block);
2114 mutex_unlock(&cache->lock);
2116 memset(block->current_data, 0, cache->block_size);
2118 mutex_lock(&cache->lock);
2119 mark_block_unbusy_reading(cache, block);
2123 TB(Get(cache, block));
2124 TB2(BlockData(cache, block, "get writable"));
2237 block_cache* cache = (struct block_cache*)(addr_t)parse_expression(argv[i]);
2238 if (cache == NULL) {
2239 kprintf("invalid cache address\n");
2246 cached_block* block = cache->hash->Lookup(blockNumber);
2254 kprintf("BLOCK CACHE: %p\n", cache);
2256 kprintf(" fd: %d\n", cache->fd);
2257 kprintf(" max_blocks: %" B_PRIdOFF "\n", cache->max_blocks);
2258 kprintf(" block_size: %zu\n", cache->block_size);
2259 kprintf(" next_transaction_id: %" B_PRId32 "\n", cache->next_transaction_id);
2260 kprintf(" buffer_cache: %p\n", cache->buffer_cache);
2261 kprintf(" busy_reading: %" B_PRIu32 ", %s waiters\n", cache->busy_reading_count,
2262 cache->busy_reading_waiters ? "has" : "no");
2263 kprintf(" busy_writing: %" B_PRIu32 ", %s waiters\n", cache->busy_writing_count,
2264 cache->busy_writing_waiters ? "has" : "no");
2266 if (!cache->pending_notifications.IsEmpty()) {
2270 = cache->pending_notifications.GetIterator();
2284 TransactionTable::Iterator iterator(cache->transaction_hash);
2306 BlockTable::Iterator iterator(cache->hash);
2324 count, dirty, discarded, referenced, cache->busy_reading_count,
2325 cache->unused_block_count);
2350 block_cache* cache = (block_cache*)(addr_t)parse_expression(argv[i]);
2352 transaction = lookup_transaction(cache, id);
2411 block_cache* cache = i.Next();
2412 if (cache == (block_cache*)&sMarkCache)
2415 kprintf(" %p\n", cache);
2530 /*! Traverses through the block_cache list, and returns one cache after the
2531 other. The cache returned is automatically locked when you get it, and
2541 block_cache* cache;
2545 cache = sCaches.GetNext((block_cache*)&sMarkCache);
2548 cache = sCaches.Head();
2550 if (cache != NULL) {
2551 mutex_lock(&cache->lock);
2552 sCaches.InsertBefore(sCaches.GetNext(cache), (block_cache*)&sMarkCache);
2555 return cache;
2561 Every two seconds, it will also write back up to 64 blocks per cache.
2589 block_cache* cache = NULL;
2590 while ((cache = get_next_locked_block_cache(cache)) != NULL) {
2594 const bigtime_t next = cache->last_block_write
2595 + cache->last_block_write_duration * 2 * 64;
2596 if (cache->busy_writing_count > 16 || system_time() < next) {
2597 if (cache->last_block_write_duration > 0) {
2599 cache->last_block_write_duration * 2 * 64);
2604 BlockWriter writer(cache, 64);
2608 object_cache_get_usage(cache->buffer_cache, &cacheUsedMemory);
2611 if (cache->num_dirty_blocks) {
2612 // This cache is not using transactions, we'll scan the blocks
2614 BlockTable::Iterator iterator(cache->hash);
2624 TransactionTable::Iterator iterator(cache->transaction_hash);
2632 notify_transaction_listeners(cache, transaction,
2649 if (hasMoreBlocks && cache->last_block_write_duration > 0) {
2653 cache->last_block_write_duration * 2 * 64);
2660 cache->RemoveUnusedBlocks(1000, 10);
2677 block_cache* cache = (block_cache*)_cache;
2679 cache->condition_variable.NotifyOne();
2685 is_valid_cache(block_cache* cache)
2691 if (cache == iterator.Next())
2701 You must not hold the \a cache lock when calling this function.
2704 wait_for_notifications(block_cache* cache)
2711 if (is_valid_cache(cache))
2712 flush_pending_notifications(cache);
2719 cache);
2722 cache->condition_variable.Add(&entry);
2724 add_notification(cache, &notification, TRANSACTION_WRITTEN, false);
2740 sCacheNotificationCache = create_object_cache("cache notifications",
2748 sEventSemaphore = create_sem(0, "block cache event");
2761 "dumps a specific block cache",
2762 "[-bt] <cache-address> [block-number]\n"
2768 "dumps a specific transaction", "[-b] ((<cache> <id>) | <transaction>)\n"
2769 "Either use a block cache pointer and an ID or a pointer to the transaction.\n"
2804 block_cache* cache = (block_cache*)_cache;
2805 TransactionLocker locker(cache);
2807 if (cache->last_transaction && cache->last_transaction->open) {
2809 cache->last_transaction->id);
2816 transaction->id = atomic_add(&cache->next_transaction_id, 1);
2817 cache->last_transaction = transaction;
2820 T(Action("start", cache, transaction));
2822 cache->transaction_hash->Insert(transaction);
2831 block_cache* cache = (block_cache*)_cache;
2837 TransactionLocker locker(cache);
2840 BlockWriter writer(cache);
2841 TransactionTable::Iterator iterator(cache->transaction_hash);
2853 T(Action("sync", cache, transaction));
2871 wait_for_notifications(cache);
2882 block_cache* cache = (block_cache*)_cache;
2883 TransactionLocker locker(cache);
2887 cache_transaction* transaction = lookup_transaction(cache, id);
2894 status_t status = write_blocks_in_previous_transaction(cache, transaction);
2898 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
2901 && add_transaction_listener(cache, transaction, TRANSACTION_WRITTEN,
2906 T(Action("end", cache, transaction));
2918 cache->DiscardBlock(block);
2924 cache->Free(block->original_data);
2929 cache->FreeBlockParentData(block);
2948 block_cache* cache = (block_cache*)_cache;
2949 TransactionLocker locker(cache);
2953 cache_transaction* transaction = lookup_transaction(cache, id);
2959 T(Abort(cache, transaction));
2960 notify_transaction_listeners(cache, transaction, TRANSACTION_ABORTED);
2973 cache->block_size);
2974 cache->Free(block->original_data);
2978 cache->FreeBlockParentData(block);
2987 cache->transaction_hash->Remove(transaction);
2988 delete_transaction(cache, transaction);
3001 block_cache* cache = (block_cache*)_cache;
3002 TransactionLocker locker(cache);
3006 cache_transaction* transaction = lookup_transaction(cache, id);
3016 status_t status = write_blocks_in_previous_transaction(cache, transaction);
3025 newTransaction->id = atomic_add(&cache->next_transaction_id, 1);
3026 T(Detach(cache, transaction, newTransaction));
3028 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
3030 if (add_transaction_listener(cache, transaction, TRANSACTION_WRITTEN, hook,
3044 cache->DiscardBlock(block);
3053 cache->Free(block->original_data);
3094 cache->transaction_hash->Insert(newTransaction);
3095 cache->last_transaction = newTransaction;
3104 block_cache* cache = (block_cache*)_cache;
3105 TransactionLocker locker(cache);
3109 cache_transaction* transaction = lookup_transaction(cache, id);
3117 T(Abort(cache, transaction));
3118 notify_transaction_listeners(cache, transaction, TRANSACTION_ABORTED);
3135 cache->block_size);
3148 cache->Free(block->original_data);
3155 cache->unused_blocks.Add(block);
3156 cache->unused_block_count++;
3167 cache->block_size);
3168 cache->Free(block->parent_data);
3189 block_cache* cache = (block_cache*)_cache;
3190 TransactionLocker locker(cache);
3194 cache_transaction* transaction = lookup_transaction(cache, id);
3201 notify_transaction_listeners(cache, transaction, TRANSACTION_ENDED);
3214 cache->FreeBlockParentData(block);
3223 cache->block_size);
3225 cache->Free(block->original_data);
3240 T(Action("start-sub", cache, transaction));
3254 block_cache* cache = (block_cache*)_cache;
3255 TransactionLocker locker(cache);
3257 cache_transaction* transaction = lookup_transaction(cache, id);
3261 return add_transaction_listener(cache, transaction, events, hook, data);
3269 block_cache* cache = (block_cache*)_cache;
3270 TransactionLocker locker(cache);
3272 cache_transaction* transaction = lookup_transaction(cache, id);
3285 cache->pending_notifications.Remove(listener);
3301 block_cache* cache = (block_cache*)_cache;
3302 TransactionLocker locker(cache);
3304 cache_transaction* transaction = lookup_transaction(cache, id);
3343 block_cache* cache = (block_cache*)_cache;
3344 TransactionLocker locker(cache);
3346 cache_transaction* transaction = lookup_transaction(cache, id);
3361 block_cache* cache = (block_cache*)_cache;
3362 TransactionLocker locker(cache);
3364 cache_transaction* transaction = lookup_transaction(cache, id);
3378 block_cache* cache = (block_cache*)_cache;
3379 TransactionLocker locker(cache);
3381 cache_transaction* transaction = lookup_transaction(cache, id);
3394 block_cache* cache = (block_cache*)_cache;
3395 TransactionLocker locker(cache);
3397 cached_block* block = cache->hash->Lookup(blockNumber);
3404 // #pragma mark - public block cache API
3410 block_cache* cache = (block_cache*)_cache;
3413 block_cache_sync(cache);
3416 sCaches.Remove(cache);
3419 mutex_lock(&cache->lock);
3422 wait_for_busy_reading_blocks(cache);
3423 wait_for_busy_writing_blocks(cache);
3427 cached_block* block = cache->hash->Clear(true);
3430 cache->FreeBlock(block);
3436 cache_transaction* transaction = cache->transaction_hash->Clear(true);
3443 delete cache;
3450 block_cache* cache = new(std::nothrow) block_cache(fd, numBlocks, blockSize,
3452 if (cache == NULL)
3455 if (cache->Init() != B_OK) {
3456 delete cache;
3461 sCaches.Add(cache);
3463 return cache;
3470 block_cache* cache = (block_cache*)_cache;
3475 MutexLocker locker(&cache->lock);
3477 BlockWriter writer(cache);
3478 BlockTable::Iterator iterator(cache->hash);
3490 wait_for_notifications(cache);
3500 block_cache* cache = (block_cache*)_cache;
3505 if (blockNumber < 0 || blockNumber >= cache->max_blocks) {
3508 blockNumber, cache->max_blocks - 1);
3512 MutexLocker locker(&cache->lock);
3513 BlockWriter writer(cache);
3516 cached_block* block = cache->hash->Lookup(blockNumber);
3528 wait_for_notifications(cache);
3535 /*! Discards a block from the current transaction or from the cache.
3537 might be reclaimed by the file cache in order to make sure they won't
3544 block_cache* cache = (block_cache*)_cache;
3545 TransactionLocker locker(cache);
3547 BlockWriter writer(cache);
3550 cached_block* block = cache->hash->Lookup(blockNumber);
3562 cached_block* block = cache->hash->Lookup(blockNumber);
3569 cache->unused_blocks.Remove(block);
3570 cache->unused_block_count--;
3571 cache->RemoveBlock(block);
3589 block_cache* cache = (block_cache*)_cache;
3590 MutexLocker locker(&cache->lock);
3592 if (cache->read_only) {
3593 panic("tried to make block writable on a read-only cache!");
3599 status_t status = get_writable_cached_block(cache, blockNumber,
3614 block_cache* cache = (block_cache*)_cache;
3615 MutexLocker locker(&cache->lock);
3619 if (cache->read_only)
3620 panic("tried to get writable block on a read-only cache!");
3622 return get_writable_cached_block(cache, blockNumber, base, length,
3642 block_cache* cache = (block_cache*)_cache;
3643 MutexLocker locker(&cache->lock);
3647 if (cache->read_only)
3648 panic("tried to get empty writable block on a read-only cache!");
3663 block_cache* cache = (block_cache*)_cache;
3664 MutexLocker locker(&cache->lock);
3668 status_t status = get_cached_block(cache, blockNumber, &allocated, true,
3675 block->compare = cache->Allocate();
3677 memcpy(block->compare, block->current_data, cache->block_size);
3679 TB(Get(cache, block));
3709 block_cache* cache = (block_cache*)_cache;
3710 MutexLocker locker(&cache->lock);
3712 cached_block* block = cache->hash->Lookup(blockNumber);
3731 block_cache* cache = (block_cache*)_cache;
3732 MutexLocker locker(&cache->lock);
3734 put_cached_block(cache, blockNumber);