vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / slab / SmallObjectCache.cpp
blob7953ceaa7133b48769bb411178f9988156e5edda
1 /*
2 * Copyright 2008, Axel Dörfler. All Rights Reserved.
3 * Copyright 2007, Hugo Santos. All Rights Reserved.
5 * Distributed under the terms of the MIT License.
6 */
9 #include "SmallObjectCache.h"
11 #include "MemoryManager.h"
12 #include "slab_private.h"
15 RANGE_MARKER_FUNCTION_BEGIN(SlabSmallObjectCache)
18 static inline slab *
19 slab_in_pages(const void *pages, size_t slab_size)
21 return (slab *)(((uint8 *)pages) + slab_size - sizeof(slab));
25 /*static*/ SmallObjectCache*
26 SmallObjectCache::Create(const char* name, size_t object_size,
27 size_t alignment, size_t maximum, size_t magazineCapacity,
28 size_t maxMagazineCount, uint32 flags, void* cookie,
29 object_cache_constructor constructor, object_cache_destructor destructor,
30 object_cache_reclaimer reclaimer)
32 void* buffer = slab_internal_alloc(sizeof(SmallObjectCache), flags);
33 if (buffer == NULL)
34 return NULL;
36 SmallObjectCache* cache = new(buffer) SmallObjectCache();
38 if (cache->Init(name, object_size, alignment, maximum, magazineCapacity,
39 maxMagazineCount, flags, cookie, constructor, destructor,
40 reclaimer) != B_OK) {
41 cache->Delete();
42 return NULL;
45 if ((flags & CACHE_LARGE_SLAB) != 0)
46 cache->slab_size = 1024 * object_size;
47 else
48 cache->slab_size = SLAB_CHUNK_SIZE_SMALL;
50 cache->slab_size = MemoryManager::AcceptableChunkSize(cache->slab_size);
52 return cache;
56 void
57 SmallObjectCache::Delete()
59 this->~SmallObjectCache();
60 slab_internal_free(this, 0);
64 slab*
65 SmallObjectCache::CreateSlab(uint32 flags)
67 if (!check_cache_quota(this))
68 return NULL;
70 void* pages;
72 Unlock();
73 status_t error = MemoryManager::Allocate(this, flags, pages);
74 Lock();
76 if (error != B_OK)
77 return NULL;
79 slab* newSlab = slab_in_pages(pages, slab_size);
80 size_t byteCount = slab_size - sizeof(slab);
81 if (AllocateTrackingInfos(newSlab, byteCount, flags) != B_OK) {
82 MemoryManager::Free(pages, flags);
83 return NULL;
86 return InitSlab(newSlab, pages, byteCount, flags);
90 void
91 SmallObjectCache::ReturnSlab(slab* slab, uint32 flags)
93 UninitSlab(slab);
95 Unlock();
96 FreeTrackingInfos(slab, flags);
97 MemoryManager::Free(slab->pages, flags);
98 Lock();
102 slab*
103 SmallObjectCache::ObjectSlab(void* object) const
105 return slab_in_pages(lower_boundary(object, slab_size), slab_size);
109 RANGE_MARKER_FUNCTION_END(SlabSmallObjectCache)