@@ -242,8 +242,33 @@ public:
242242 }
243243
244244 void freeExtent (ref CachedExtentMap emap, Extent* e) shared {
245- emap.clear(e);
246- freePages(e);
245+ assert (e.arenaIndex == arena.index, " Invalid arena!" );
246+ batchFreeExtents(emap, (&e)[0 .. 1 ]);
247+ }
248+
249+ void batchFreeExtents (ref CachedExtentMap emap, Extent* [] extents) shared {
250+ // FIXME: in contract.
251+ foreach (e; extents) {
252+ assert (e.arenaIndex == arena.index, " Invalid arena!" );
253+ }
254+
255+ // Avoid locking if there is nothing to do.
256+ if (extents.length == 0 ) {
257+ return ;
258+ }
259+
260+ // Clear the emap.
261+ foreach (e; extents) {
262+ emap.clear(e);
263+ }
264+
265+ // Free the pages.
266+ mutex.lock();
267+ scope (exit) mutex.unlock();
268+
269+ foreach (e; extents) {
270+ (cast (PageFiller* ) &this ).freePagesImpl(e);
271+ }
247272 }
248273
249274 void freePages (Extent* e) shared {
@@ -342,6 +367,16 @@ private:
342367 return e.at(ptr, npages, block);
343368 }
344369
370+ void freePagesImpl (Extent* e) {
371+ assert (mutex.isHeld(), " Mutex not held!" );
372+ assert (isAligned(e.address, PageSize), " Invalid extent address!" );
373+
374+ uint n = e.blockIndex;
375+ uint pages = modUp(e.npages, PagesInBlock);
376+
377+ freePagesImpl(e, n, pages);
378+ }
379+
345380 void freePagesImpl (Extent* e, uint n, uint pages) {
346381 assert (mutex.isHeld(), " Mutex not held!" );
347382 assert (pages > 0 && pages <= PagesInBlock, " Invalid number of pages!" );
@@ -1030,11 +1065,7 @@ private:
10301065 assert (isAligned(e.address, PageSize), " Invalid extent address!" );
10311066
10321067 emap.clear(e);
1033-
1034- uint n = e.blockIndex;
1035- uint pages = modUp(e.npages, PagesInBlock);
1036-
1037- (cast (PageFiller* ) &this ).freePagesImpl(e, n, pages);
1068+ freePagesImpl(e);
10381069 }
10391070}
10401071
0 commit comments