Changeset 26271
- Timestamp:
- 07/05/08 21:07:31 (5 months ago)
- Location:
- haiku/branches/developer/bonefish/vm
- Files:
-
- 8 modified
-
headers/private/kernel/vm_cache.h (modified) (2 diffs)
-
headers/private/kernel/vm_types.h (modified) (5 diffs)
-
src/system/kernel/cache/file_cache.cpp (modified) (19 diffs)
-
src/system/kernel/fs/vfs.cpp (modified) (5 diffs)
-
src/system/kernel/vm/vm.cpp (modified) (57 diffs)
-
src/system/kernel/vm/vm_cache.cpp (modified) (12 diffs)
-
src/system/kernel/vm/vm_daemons.cpp (modified) (2 diffs)
-
src/system/kernel/vm/vm_page.cpp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
haiku/branches/developer/bonefish/vm/headers/private/kernel/vm_cache.h
r26175 r26271 16 16 struct kernel_args; 17 17 18 //typedef struct vm_store vm_store;19 20 18 21 19 #ifdef __cplusplus … … 24 22 25 23 status_t vm_cache_init(struct kernel_args *args); 26 void vm_cache_acquire_ref(struct VMCache *cache); 27 void vm_cache_release_ref(struct VMCache *cache); 28 struct VMCache *vm_cache_acquire_page_cache_ref(struct vm_page *page); 29 struct vm_page *vm_cache_lookup_page(struct VMCache *cache, off_t page); 30 void vm_cache_insert_page(struct VMCache *cache, struct vm_page *page, 31 off_t offset); 32 void vm_cache_remove_page(struct VMCache *cache, struct vm_page *page); 33 void vm_cache_remove_consumer(struct VMCache *cache, struct VMCache *consumer); 34 void vm_cache_add_consumer_locked(struct VMCache *cache, 35 struct VMCache *consumer); 36 status_t vm_cache_write_modified(struct VMCache *cache, bool fsReenter); 37 status_t vm_cache_set_minimal_commitment_locked(struct VMCache *cache, 38 off_t commitment); 39 status_t vm_cache_resize(struct VMCache *cache, off_t newSize); 40 status_t vm_cache_insert_area_locked(struct VMCache *cache, vm_area *area); 41 status_t vm_cache_remove_area(struct VMCache *cache, struct vm_area *area); 24 struct VMCache *vm_cache_acquire_locked_page_cache(struct vm_page *page, 25 bool dontWait); 42 26 43 27 #ifdef __cplusplus -
haiku/branches/developer/bonefish/vm/headers/private/kernel/vm_types.h
r26250 r26271 14 14 #include <condition_variable.h> 15 15 #include <kernel.h> 16 #include <lock.h> 16 17 #include <util/DoublyLinkedQueue.h> 17 18 … … 176 177 virtual void Delete(); 177 178 179 bool Lock() 180 { return mutex_lock(&fLock) == B_OK; } 181 bool TryLock() 182 { return mutex_trylock(&fLock) == B_OK; } 183 bool SwitchLock(mutex* from) 184 { return mutex_switch_lock(from, &fLock) == B_OK; } 185 void Unlock(); 186 void AssertLocked() 187 { ASSERT_LOCKED_MUTEX(&fLock); } 188 189 void AcquireRefLocked(); 190 void AcquireRef(); 191 void ReleaseRefLocked(); 192 void ReleaseRef(); 193 void ReleaseRefAndUnlock() 194 { ReleaseRefLocked(); Unlock(); } 195 196 vm_page* LookupPage(off_t offset); 197 void InsertPage(vm_page* page, off_t offset); 198 void RemovePage(vm_page* page); 199 200 void AddConsumer(VMCache* consumer); 201 202 status_t InsertAreaLocked(vm_area* area); 203 status_t RemoveArea(vm_area* area); 204 205 status_t WriteModified(bool fsReenter); 206 status_t SetMinimalCommitment(off_t commitment); 207 status_t Resize(off_t newSize); 208 209 // for debugging only 210 mutex* GetLock() 211 { return &fLock; } 212 int32 RefCount() const 213 { return fRefCount; } 214 178 215 // backing store operations 179 216 virtual status_t Commit(off_t size); … … 193 230 virtual void ReleaseStoreRef(); 194 231 232 private: 233 inline bool _IsMergeable() const; 234 235 void _MergeWithOnlyConsumer(); 236 void _RemoveConsumer(VMCache* consumer); 237 238 195 239 public: 196 mutex lock;197 240 struct vm_area *areas; 198 vint32 ref_count;199 241 struct list_link consumer_link; 200 242 struct list consumers; … … 209 251 uint32 temporary : 1; 210 252 uint32 scan_skip : 1; 211 uint32 busy : 1; 212 uint32 type : 5; 253 uint32 type : 6; 213 254 214 255 #if DEBUG_CACHE_LIST … … 216 257 struct VMCache* debug_next; 217 258 #endif 259 260 private: 261 int32 fRefCount; 262 mutex fLock; 218 263 }; 219 264 -
haiku/branches/developer/bonefish/vm/src/system/kernel/cache/file_cache.cpp
r26250 r26271 120 120 if (vm_low_memory_state() != B_NO_LOW_MEMORY) { 121 121 vm_cache *cache = ref->cache; 122 mutex_lock(&cache->lock);122 cache->Lock(); 123 123 124 124 if (list_is_empty(&cache->consumers) && cache->areas == NULL … … 145 145 if (page->state != PAGE_STATE_MODIFIED 146 146 && page->state != PAGE_STATE_BUSY) { 147 vm_cache_remove_page(cache,page);147 cache->RemovePage(page); 148 148 vm_page_set_state(page, PAGE_STATE_FREE); 149 149 left--; … … 152 152 } 153 153 } 154 mutex_unlock(&cache->lock);154 cache->Unlock(); 155 155 } 156 156 … … 195 195 busyConditions[pageIndex - 1].Publish(page, "page"); 196 196 197 vm_cache_insert_page(cache,page, offset + pos);197 cache->InsertPage(page, offset + pos); 198 198 199 199 addr_t virtualAddress; … … 207 207 208 208 push_access(ref, offset, bufferSize, false); 209 mutex_unlock(&cache->lock);209 cache->Unlock(); 210 210 vm_page_unreserve_pages(lastReservedPages); 211 211 … … 228 228 } 229 229 230 mutex_lock(&cache->lock);230 cache->Lock(); 231 231 232 232 for (int32 i = 0; i < pageIndex; i++) { 233 233 busyConditions[i].Unpublish(); 234 vm_cache_remove_page(cache,pages[i]);234 cache->RemovePage(pages[i]); 235 235 vm_page_set_state(pages[i], PAGE_STATE_FREE); 236 236 } … … 262 262 263 263 reserve_pages(ref, reservePages, false); 264 mutex_lock(&cache->lock);264 cache->Lock(); 265 265 266 266 // make the pages accessible in the cache … … 291 291 292 292 push_access(ref, offset, bufferSize, false); 293 mutex_unlock(&ref->cache->lock);293 ref->cache->Unlock(); 294 294 vm_page_unreserve_pages(lastReservedPages); 295 295 … … 299 299 reserve_pages(ref, reservePages, false); 300 300 301 mutex_lock(&ref->cache->lock);301 ref->cache->Lock(); 302 302 303 303 return status; … … 339 339 busyConditions[pageIndex - 1].Publish(page, "page"); 340 340 341 vm_cache_insert_page(ref->cache,page, offset + pos);341 ref->cache->InsertPage(page, offset + pos); 342 342 343 343 addr_t virtualAddress; … … 350 350 351 351 push_access(ref, offset, bufferSize, true); 352 mutex_unlock(&ref->cache->lock);352 ref->cache->Unlock(); 353 353 vm_page_unreserve_pages(lastReservedPages); 354 354 … … 432 432 reserve_pages(ref, reservePages, true); 433 433 434 mutex_lock(&ref->cache->lock);434 ref->cache->Lock(); 435 435 436 436 // unmap the pages again … … 481 481 482 482 push_access(ref, offset, bufferSize, true); 483 mutex_unlock(&ref->cache->lock);483 ref->cache->Unlock(); 484 484 vm_page_unreserve_pages(lastReservedPages); 485 485 … … 509 509 reserve_pages(ref, reservePages, true); 510 510 511 mutex_lock(&ref->cache->lock);511 ref->cache->Lock(); 512 512 513 513 return status; … … 605 605 606 606 reserve_pages(ref, lastReservedPages, doWrite); 607 MutexLocker locker(cache->lock);607 AutoLocker<VMCache> locker(cache); 608 608 609 609 while (bytesLeft > 0) { 610 610 // check if this page is already in memory 611 vm_page *page = vm_cache_lookup_page(cache,offset);611 vm_page *page = cache->LookupPage(offset); 612 612 if (page != NULL) { 613 613 // The page may be busy - since we need to unlock the cache sometime … … 970 970 TRACE(("file_cache_delete(ref = %p)\n", ref)); 971 971 972 vm_cache_release_ref(ref->cache);972 ref->cache->ReleaseRef(); 973 973 delete ref; 974 974 } … … 985 985 return B_OK; 986 986 987 MutexLocker _(ref->cache->lock);987 AutoLocker<VMCache> _(ref->cache); 988 988 989 989 off_t offset = ref->cache->virtual_end; … … 995 995 size = newSize - offset; 996 996 997 return vm_cache_resize(ref->cache,newSize);997 return ref->cache->Resize(newSize); 998 998 } 999 999 … … 1006 1006 return B_BAD_VALUE; 1007 1007 1008 return vm_cache_write_modified(ref->cache,true);1008 return ref->cache->WriteModified(true); 1009 1009 } 1010 1010 -
haiku/branches/developer/bonefish/vm/src/system/kernel/fs/vfs.cpp
r26250 r26271 771 771 // if we have a vm_cache attached, remove it 772 772 if (vnode->cache) 773 v m_cache_release_ref(vnode->cache);773 vnode->cache->ReleaseRef(); 774 774 775 775 vnode->cache = NULL; … … 1060 1060 1061 1061 if (vnode->cache != NULL) 1062 v m_cache_write_modified(vnode->cache,false);1062 vnode->cache->WriteModified(false); 1063 1063 1064 1064 dec_vnode_ref_count(vnode, true, false); … … 3921 3921 { 3922 3922 if (vnode->cache != NULL) { 3923 v m_cache_acquire_ref(vnode->cache);3923 vnode->cache->AcquireRef(); 3924 3924 *_cache = vnode->cache; 3925 3925 return B_OK; … … 3947 3947 } 3948 3948 3949 mutex_unlock(&sVnodeMutex); 3950 3949 3951 if (status == B_OK) { 3950 v m_cache_acquire_ref(vnode->cache);3952 vnode->cache->AcquireRef(); 3951 3953 *_cache = vnode->cache; 3952 3954 } 3953 3955 3954 mutex_unlock(&sVnodeMutex);3955 3956 return status; 3956 3957 } … … 6706 6707 6707 6708 if (vnode->cache != NULL) 6708 v m_cache_write_modified(vnode->cache,false);6709 vnode->cache->WriteModified(false); 6709 6710 6710 6711 // the next vnode might change until we lock the vnode list again, -
haiku/branches/developer/bonefish/vm/src/system/kernel/vm/vm.cpp
r26250 r26271 1240 1240 if (cache->areas == area && area->cache_next == NULL 1241 1241 && list_is_empty(&cache->consumers)) { 1242 status_t error = vm_cache_resize(cache,newSize);1242 status_t error = cache->Resize(newSize); 1243 1243 if (error != B_OK) 1244 1244 return error; … … 1299 1299 1300 1300 // We need a cache reference for the new area. 1301 vm_cache_acquire_ref(cache);1301 cache->AcquireRefLocked(); 1302 1302 1303 1303 if (_secondArea != NULL) … … 1373 1373 addressSpace, cache, *_virtualAddress, offset, size, addressSpec, 1374 1374 wiring, protection, _area, areaName)); 1375 ASSERT_LOCKED_MUTEX(&cache->lock);1375 cache->AssertLocked(); 1376 1376 1377 1377 vm_area *area = create_area_struct(addressSpace, areaName, wiring, … … 1394 1394 goto err1; 1395 1395 1396 mutex_lock(&newCache->lock);1396 newCache->Lock(); 1397 1397 newCache->temporary = 1; 1398 1398 newCache->scan_skip = cache->scan_skip; … … 1400 1400 newCache->virtual_end = offset + size; 1401 1401 1402 vm_cache_add_consumer_locked(cache,newCache);1402 cache->AddConsumer(newCache); 1403 1403 1404 1404 cache = newCache; 1405 1405 } 1406 1406 1407 status = vm_cache_set_minimal_commitment_locked(cache,size);1407 status = cache->SetMinimalCommitment(size); 1408 1408 if (status != B_OK) 1409 1409 goto err2; … … 1433 1433 1434 1434 // point the cache back to the area 1435 vm_cache_insert_area_locked(cache,area);1435 cache->InsertAreaLocked(area); 1436 1436 if (mapping == REGION_PRIVATE_MAP) 1437 mutex_unlock(&cache->lock);1437 cache->Unlock(); 1438 1438 1439 1439 // insert the area in the global area hash table … … 1452 1452 // We created this cache, so we must delete it again. Note, that we 1453 1453 // need to temporarily unlock the source cache or we'll otherwise 1454 // deadlock, since vm_cache_remove_consumer will try to lock it too. 1455 mutex_unlock(&cache->lock); 1456 mutex_unlock(&sourceCache->lock); 1457 vm_cache_release_ref(cache); 1458 mutex_lock(&sourceCache->lock); 1454 // deadlock, since VMCache::_RemoveConsumer() will try to lock it, too. 1455 sourceCache->Unlock(); 1456 cache->ReleaseRefAndUnlock(); 1457 sourceCache->Lock(); 1459 1458 } 1460 1459 err1: … … 1642 1641 } 1643 1642 1644 mutex_lock(&cache->lock);1643 cache->Lock(); 1645 1644 1646 1645 status = map_backing_store(addressSpace, cache, address, 0, size, … … 1648 1647 unmapAddressRange, kernel); 1649 1648 1650 mutex_unlock(&cache->lock);1651 1652 1649 if (status < B_OK) { 1653 vm_cache_release_ref(cache);1650 cache->ReleaseRefAndUnlock(); 1654 1651 goto err1; 1655 1652 } 1653 1654 cache->Unlock(); 1656 1655 1657 1656 locker.DegradeToReadLock(); … … 1671 1670 1672 1671 // Allocate and map all pages for this area 1673 mutex_lock(&cache->lock);1672 cache->Lock(); 1674 1673 1675 1674 off_t offset = 0; … … 1692 1691 } 1693 1692 1694 vm_cache_insert_page(cache,page, offset);1693 cache->InsertPage(page, offset); 1695 1694 vm_map_page(area, page, address, protection); 1696 1695 } 1697 1696 1698 mutex_unlock(&cache->lock);1697 cache->Unlock(); 1699 1698 vm_page_unreserve_pages(reservePages); 1700 1699 break; … … 1712 1711 panic("ALREADY_WIRED flag used outside kernel startup\n"); 1713 1712 1714 mutex_lock(&cache->lock);1713 cache->Lock(); 1715 1714 map->ops->lock(map); 1716 1715 … … 1735 1734 // TODO: needs to be atomic on all platforms! 1736 1735 vm_page_set_state(page, PAGE_STATE_WIRED); 1737 vm_cache_insert_page(cache,page, offset);1736 cache->InsertPage(page, offset); 1738 1737 } 1739 1738 1740 1739 map->ops->unlock(map); 1741 mutex_unlock(&cache->lock);1740 cache->Unlock(); 1742 1741 break; 1743 1742 } … … 1755 1754 1756 1755 vm_page_reserve_pages(reservePages); 1757 mutex_lock(&cache->lock);1756 cache->Lock(); 1758 1757 map->ops->lock(map); 1759 1758 … … 1773 1772 // TODO: needs to be atomic on all platforms! 1774 1773 vm_page_set_state(page, PAGE_STATE_WIRED); 1775 vm_cache_insert_page(cache,page, offset);1774 cache->InsertPage(page, offset); 1776 1775 } 1777 1776 1778 1777 map->ops->unlock(map); 1779 mutex_unlock(&cache->lock);1778 cache->Unlock(); 1780 1779 vm_page_unreserve_pages(reservePages); 1781 1780 break; … … 1845 1844 cache->virtual_end = size; 1846 1845 1847 mutex_lock(&cache->lock);1846 cache->Lock(); 1848 1847 1849 1848 status = map_backing_store(locker.AddressSpace(), cache, _address, … … 1851 1850 REGION_NO_PRIVATE_MAP, &area, name, false, true); 1852 1851 1853 mutex_unlock(&cache->lock);1854 1855 1852 if (status < B_OK) 1856 vm_cache_release_ref(cache); 1853 cache->ReleaseRefLocked(); 1854 1855 cache->Unlock(); 1857 1856 1858 1857 if (status >= B_OK && (addressSpec & B_MTR_MASK) != 0) { … … 1918 1917 cache->virtual_end = size; 1919 1918 1920 mutex_lock(&cache->lock);1919 cache->Lock(); 1921 1920 1922 1921 status = map_backing_store(locker.AddressSpace(), cache, address, 0, size, … … 1924 1923 false, true); 1925 1924 1926 mutex_unlock(&cache->lock);1927 1928 1925 if (status < B_OK) { 1929 vm_cache_release_ref(cache);1926 cache->ReleaseRefAndUnlock(); 1930 1927 return status; 1931 1928 } 1929 1930 cache->Unlock(); 1932 1931 1933 1932 area->cache_type = CACHE_TYPE_NULL; … … 2006 2005 return status; 2007 2006 2008 mutex_lock(&cache->lock);2007 cache->Lock();
