MCPcopy Create free account
hub / github.com/beefytech/Beef / do_memalign

Function do_memalign

BeefRT/gperftools/src/tcmalloc.cc:1328–1400  ·  view source on GitHub ↗

For use by exported routines below that want specific alignments Note: this code can be slow for alignments > 16, and can significantly fragment memory. The expectation is that memalign/posix_memalign/valloc/pvalloc will not be invoked very often. This requirement simplifies our implementation and allows us to tune for expected allocation patterns.

Source from the content-addressed store, hash-verified

1326// often. This requirement simplifies our implementation and allows
1327// us to tune for expected allocation patterns.
1328void* do_memalign(size_t align, size_t size) {
1329 ASSERT((align & (align - 1)) == 0);
1330 ASSERT(align > 0);
1331 if (size + align < size) return NULL; // Overflow
1332
1333 // Fall back to malloc if we would already align this memory access properly.
1334 if (align <= AlignmentForSize(size)) {
1335 void* p = do_malloc(size);
1336 ASSERT((reinterpret_cast<uintptr_t>(p) % align) == 0);
1337 return p;
1338 }
1339
1340 if (UNLIKELY(Static::pageheap() == NULL)) ThreadCache::InitModule();
1341
1342 // Allocate at least one byte to avoid boundary conditions below
1343 if (size == 0) size = 1;
1344
1345 if (size <= kMaxSize && align < kPageSize) {
1346 // Search through acceptable size classes looking for one with
1347 // enough alignment. This depends on the fact that
1348 // InitSizeClasses() currently produces several size classes that
1349 // are aligned at powers of two. We will waste time and space if
1350 // we miss in the size class array, but that is deemed acceptable
1351 // since memalign() should be used rarely.
1352 int cl = Static::sizemap()->SizeClass(size);
1353 while (cl < kNumClasses &&
1354 ((Static::sizemap()->class_to_size(cl) & (align - 1)) != 0)) {
1355 cl++;
1356 }
1357 if (cl < kNumClasses) {
1358 ThreadCache* heap = ThreadCache::GetCache();
1359 size = Static::sizemap()->class_to_size(cl);
1360 return CheckedMallocResult(heap->Allocate(size, cl));
1361 }
1362 }
1363
1364 // We will allocate directly from the page heap
1365 SpinLockHolder h(Static::pageheap_lock());
1366
1367 if (align <= kPageSize) {
1368 // Any page-level allocation will be fine
1369 // TODO: We could put the rest of this page in the appropriate
1370 // TODO: cache but it does not seem worth it.
1371 Span* span = Static::pageheap()->New(TCMALLOC_NAMESPACE::pages(size));
1372 return UNLIKELY(span == NULL) ? NULL : SpanToMallocResult(span);
1373 }
1374
1375 // Allocate extra pages and carve off an aligned portion
1376 const Length alloc = TCMALLOC_NAMESPACE::pages(size + align);
1377 Span* span = Static::pageheap()->New(alloc);
1378 if (UNLIKELY(span == NULL)) return NULL;
1379
1380 // Skip starting portion so that we end up aligned
1381 Length skip = 0;
1382 while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) {
1383 skip++;
1384 }
1385 ASSERT(skip < alloc);

Callers 2

cpp_memalignFunction · 0.70

Calls 12

AlignmentForSizeFunction · 0.70
do_mallocFunction · 0.70
InitModuleFunction · 0.70
CheckedMallocResultFunction · 0.70
pagesFunction · 0.70
SpanToMallocResultFunction · 0.70
SizeClassMethod · 0.45
class_to_sizeMethod · 0.45
AllocateMethod · 0.45
NewMethod · 0.45
SplitMethod · 0.45
DeleteMethod · 0.45

Tested by

no test coverage detected