are built around it.
Last time we saw the memory allocating process, which further formulates slabs and the derivative “free lists” (a.k.a., slots
). This time we will examine how to take advantage of the established data structures to “slab allocate / release” memory chunks which will be used to store items.
Slab alloc
Firstly, we look at
do_slabs_alloc
which is opposite to the discussed do_slabs_free
.
Note that the “public” interface of do_slabs_alloc
is slabs_alloc which is basically a thread-safe wrapper that locks the core data structures manipulated by the Memcached instance that is configured as multithreaded.
void *slabs_alloc(size_t size, unsigned int id, unsigned int *total_chunks, |
... |
static void *do_slabs_alloc(const size_t size, unsigned int id, unsigned int *total_chunks, |
1) For item allocation, id
indicates the slab class that suits the requested item size best. In other words, id
is selected using the actual item size, the process of which will be discussed very soon.
2) total_chunks
is the parameter that outputs the total number of memory chunks (entries in the free list) available for the slab class. if (total_chunks != NULL)
suggests that the argument is optional.
*) As the name indicates, SLABS_ALLOC_NO_NEWPAGE
(flags
) prevents this method to allocate new slab when there is no memory chunk available. This option is not used in the normal path of item allocation, hence is ignored for now.
3) When there is no free memory chunk, allocate a new slab. Here p->sl_curr
indicates the number of available chunks, whose value decreases each time this method got called (in step 5 below).
Conversely, this field is increased in do_slabs_free. Note that new slab has also been covered from here.
4) Remove the front element (f) from the free list, and set it to it
.
In do_slabs_free, an element is added to the front of the free list.
5) Clear the ITEM_SLABBED
for the chuck (f), set its reference count to 1, and reduce p->sl_curr
by 1
.
Likewise, this flag is set in do_slabs_free.
6) Return (f).
Next, we look at the process of determining the id
based on item size, the workhorse method of which is
slabs_clsid
unsigned int slabs_clsid(const size_t size) { |
slabs_clsid
consists mainly of a while
loop that linear search the possible smallest slab class that can contain the requested size
. This method is called from do_item_alloc before slabs_alloc
. We will discuss do_item_alloc in the following post.
item *do_item_alloc(char *key, const size_t nkey, const unsigned int flags, |