Reputation: 3930
From the guide Understanding The Linux Kernel, 3rd Edition , chapter 8.2.12. Allocating a Slab Object , there is the following piece of code:
void * kmem_cache_alloc(kmem_cache_t *cachep, int flags)
{
unsigned long save_flags;
void *objp;
struct array_cache *ac;
local_irq_save(save_flags);
ac = cache_p->array[smp_processor_id()];
if (ac->avail)
{
ac->touched = 1;
objp = ((void**)(ac+1))[--ac->avail];
} else
objp = cache_alloc_refill(cachep, flags);
local_irq_restore(save_flags); return objp;
}
Now, look at the line ((void**)(ac+1))[--ac->avail]
, according to the guide:
Because the local cache array is stored right after the ac descriptor, ((void**)(ac+1))[--ac->avail] gets the address of that free object and decreases the value of ac->avail.
But, since ac
is a pointer to type struct array_cache
which contains the following fields (in this order)-
[type] unsigned int
[name] avail
[description] Number of pointers to available objects in the local cache. The field also acts as the index of the first free slot in the cache.
[type] unsigned int
[name] limit
[description] Size of the local cache that is, the maximum number of pointers in the local cache.
[type] unsigned int
[name] batch_count
[description] Chunk size for local cache refill or emptying.
[type] unsigned int
[name] touched
[description] Flag set to 1 if the local cache has been recently used.
so ac+1
will point to to the second byte of avail
value (or 3rd byte in opposite Endian case) which makes no sense at all.
Am I getting this the wrong way?
Upvotes: 1
Views: 909
Reputation: 399803
Yes, you're mistaken.
Pointer arithmetic is in terms of the type being pointed at, not bytes.
Consider this:
int a[2], *p = a;
++p;
This leaves p
equal to &a[1]
, not ((char *) &a[0]) + 1
. So that increment will increment the actual pointer value by sizeof *p
, i.e. sizeof (int)
.
Remember that array indexing works through pointer arithmetic, so it has to be this way for that reason too.
It's quite common when implementing various data structures in C that you have a block of memory that starts with an instance of some struct
, and then comes other data (often described by field in the struct
). The first byte of that data is then at sp + 1
, assuming sp
is a pointer to the struct
, just as the code you showed.
Upvotes: 3