@@ -156,6 +156,16 @@ region_reserve(struct region *region, size_t size)
156
156
slab .next_in_list );
157
157
if (size <= rslab_unused (slab ))
158
158
return (char * ) rslab_data (slab ) + slab -> used ;
159
+ /* Try to get a slab from the region cache. */
160
+ slab = rlist_last_entry (& region -> slabs .slabs ,
161
+ struct rslab ,
162
+ slab .next_in_list );
163
+ if (slab -> used == 0 && size <= rslab_unused (slab )) {
164
+ /* Move this slab to the head. */
165
+ slab_list_del (& region -> slabs , & slab -> slab , next_in_list );
166
+ slab_list_add (& region -> slabs , & slab -> slab , next_in_list );
167
+ return (char * ) rslab_data (slab );
168
+ }
159
169
}
160
170
return region_reserve_slow (region , size );
161
171
}
@@ -212,14 +222,14 @@ region_aligned_alloc(struct region *region, size_t size, size_t alignment)
212
222
213
223
/**
214
224
* Mark region as empty, but keep the blocks.
225
+ * Do not change the first slab and use previous slabs as a cache to
226
+ * use for future allocations.
215
227
*/
216
228
static inline void
217
229
region_reset (struct region * region )
218
230
{
219
- if (! rlist_empty (& region -> slabs .slabs )) {
220
- struct rslab * slab = rlist_first_entry (& region -> slabs .slabs ,
221
- struct rslab ,
222
- slab .next_in_list );
231
+ struct rslab * slab ;
232
+ rlist_foreach_entry (slab , & region -> slabs .slabs , slab .next_in_list ) {
223
233
region -> slabs .stats .used -= slab -> used ;
224
234
slab -> used = 0 ;
225
235
}
0 commit comments