Skip to content

Commit

Permalink
Balst stacktracetestallocator num allocations drqs 174842950 (#4733)
Browse files Browse the repository at this point in the history
* balst_stacktracetestallocator: add 'numAllocations'
  • Loading branch information
lalawawa authored and GitHub Enterprise committed May 11, 2024
1 parent b56b954 commit 22fb795
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 85 deletions.
3 changes: 3 additions & 0 deletions groups/bal/balst/balst_stacktracetestallocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ StackTraceTestAllocator::StackTraceTestAllocator(
bslma::Allocator *basicAllocator)
: d_magic(k_STACK_TRACE_TEST_ALLOCATOR_MAGIC)
, d_numBlocksInUse(0)
, d_numAllocations(0)
, d_blocks(0)
, d_mutex()
, d_name("<unnamed>")
Expand Down Expand Up @@ -295,6 +296,7 @@ StackTraceTestAllocator::StackTraceTestAllocator(
bslma::Allocator *basicAllocator)
: d_magic(k_STACK_TRACE_TEST_ALLOCATOR_MAGIC)
, d_numBlocksInUse(0)
, d_numAllocations(0)
, d_blocks(0)
, d_mutex()
, d_name("<unnamed>")
Expand Down Expand Up @@ -391,6 +393,7 @@ void *StackTraceTestAllocator::allocate(size_type size)
BSLS_ASSERT(0 == ((UintPtr) ret & ((sizeof(void *) - 1) | lowBits)));

++d_numBlocksInUse;
++d_numAllocations;

return ret;
}
Expand Down
16 changes: 16 additions & 0 deletions groups/bal/balst/balst_stacktracetestallocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ BSLS_IDENT("$Id: $")
// ( balst::StackTraceTestAllocator )
// `------------------------------'
// | ctor/dtor
// | numAllocations
// | numBlocksInUse
// | reportBlocksInUse
// | setFailureHandler
Expand Down Expand Up @@ -527,6 +528,10 @@ class StackTraceTestAllocator : public bdlma::ManagedAllocator {
bsls::AtomicInt d_numBlocksInUse; // number of allocated
// blocks currently unfreed

bsls::AtomicInt64 d_numAllocations; // number of alloctions that
// have occurred since
// creation

BlockHeader *d_blocks; // list of allocated,
// unfreed blocks

Expand Down Expand Up @@ -677,6 +682,11 @@ class StackTraceTestAllocator : public bdlma::ManagedAllocator {
// Return a reference to the function that will be called when a
// failure is observered.

bsls::Types::Int64 numAllocations() const;
// Return the number of allocations from this object that have occurred
// since creation. Note that this does not count allocations of 0
// length, which return null pointers.

bsl::size_t numBlocksInUse() const;
// Return the number of blocks currently allocated from this object.

Expand Down Expand Up @@ -705,6 +715,12 @@ bsl::size_t StackTraceTestAllocator::numBlocksInUse() const
return d_numBlocksInUse;
}

inline
bsls::Types::Int64 StackTraceTestAllocator::numAllocations() const
{
return d_numAllocations;
}

} // close package namespace
} // close enterprise namespace

Expand Down
186 changes: 101 additions & 85 deletions groups/bal/balst/balst_stacktracetestallocator.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,8 @@ int main(int argc, char *argv[])
//: was filled with when allocated.
//: o Check the 'numBlocksInUse' accessor to verify that it properly
//: tracks its expected value.
//: o Check the 'numAllocations' accessor to verify that it properly
//: tracks its expected value.
//---------------------------------------------------------------------

if (verbose) cout << "ALIGNMENT & RANDOM ALLOCATE / FREE TEST\n"
Expand All @@ -1538,119 +1540,133 @@ int main(int argc, char *argv[])
const int ptrAlign = bsls::AlignmentUtil::calculateAlignmentFromSize(
sizeof(void *));

memset(blocks, 0, sizeof(blocks));
for (int i = 0; i < MAX_NUM_BLOCKS; ++i) {
Block& s = blocks[i];
s.d_len = i / 2;

// 'AlignmentUtil' fails if passed an argument of 0
// The 'ia' loop is to create 'Obj ta' with both c'tors.

s.d_align = !s.d_len
? 8
: bsls::AlignmentUtil::calculateAlignmentFromSize(
s.d_len);
s.d_align = bsl::max<int>(s.d_align, ptrAlign);
for (int ia = 0; ia < 2; ++ia) {
memset(blocks, 0, sizeof(blocks));
for (int i = 0; i < MAX_NUM_BLOCKS; ++i) {
Block& s = blocks[i];
s.d_len = i / 2;

// verify one bit of alignment set

ASSERT(0 == (s.d_align & (s.d_align - 1)));
}
// 'AlignmentUtil' fails if passed an argument of 0

Obj ta;
int randNum;
bdlb::Random::generate15(&randNum, 987654321);
s.d_align = !s.d_len
? 8
: bsls::AlignmentUtil::calculateAlignmentFromSize(
s.d_len);
s.d_align = bsl::max<int>(s.d_align, ptrAlign);

// allocate 100% of the blocks, in random order
// verify one bit of alignment set

for (int i = 0; i < MAX_NUM_BLOCKS; ++i) {
int index = bdlb::Random::generate15(&randNum) % MAX_NUM_BLOCKS;
while (blocks[index].d_alloced) {
index = (index + 1) % MAX_NUM_BLOCKS;
ASSERT(0 == (s.d_align & (s.d_align - 1)));
}

Block& s = blocks[index];

s.d_ptr = (char *) ta.allocate(s.d_len);
s.d_alloced = true;
s.d_fill = (char) bdlb::Random::generate15(&randNum);
memset(s.d_ptr, s.d_fill, s.d_len);

ASSERT(!s.d_ptr == !s.d_len);

// verify block aligned
Obj ta0;
Obj ta1(20);
Obj& ta = 0 == ia ? ta0 : ta1;
int randNum;
bdlb::Random::generate15(&randNum, 987654321);

LOOP3_ASSERT((void *) s.d_ptr, s.d_len, s.d_align,
0 == ((UintPtr) s.d_ptr & (s.d_align - 1)));
}
int numBlocks = MAX_NUM_BLOCKS;
int numBlocksInUse = numBlocks - 2;
ASSERT((int) ta.numBlocksInUse() == numBlocksInUse);

// Now go around chosing blocks at random to be allocated or freed in
// random order.

for (int i = 0; i < ITERATIONS; ++i) {
const bool alloc = numBlocks > 3 * QUARTER_BLOCKS
? false
: numBlocks < QUARTER_BLOCKS
? true
: (bdlb::Random::generate15(&randNum) & 1);

// Steer the # of blocks allocated to be at around half the
// slots, give or take a quarter.

int index = bdlb::Random::generate15(&randNum) % MAX_NUM_BLOCKS;
while (alloc == blocks[index].d_alloced) {
index = (index + 1) % MAX_NUM_BLOCKS;
}
Block& s = blocks[index];
// allocate 100% of the blocks, in random order

if (alloc) {
// allocate
int numAllocations = 0;
for (int i = 0; i < MAX_NUM_BLOCKS; ++i) {
int index =
bdlb::Random::generate15(&randNum) % MAX_NUM_BLOCKS;
while (blocks[index].d_alloced) {
index = (index + 1) % MAX_NUM_BLOCKS;
}

ASSERT(!s.d_alloced);
ASSERT(!s.d_ptr);
Block& s = blocks[index];

s.d_ptr = (char *) ta.allocate(s.d_len);
s.d_alloced = true;
++numBlocks;
s.d_fill = (char) bdlb::Random::generate15(&randNum);
if (s.d_ptr) {
++numBlocksInUse;
memset(s.d_ptr, s.d_fill, s.d_len);
++numAllocations;
}

ASSERT(!s.d_ptr == !s.d_len);
s.d_fill = (char) bdlb::Random::generate15(&randNum);
memset(s.d_ptr, s.d_fill, s.d_len);

// verify block aligned

LOOP3_ASSERT((void *) s.d_ptr, s.d_len, s.d_align,
0 == ((UintPtr) s.d_ptr & (s.d_align - 1)));
}
else {
// free
int numBlocksInUse = MAX_NUM_BLOCKS - 2;
ASSERT(numAllocations == numBlocksInUse);
ASSERT((int) ta.numBlocksInUse() == numBlocksInUse);
ASSERT(ta.numAllocations() == numAllocations);

ASSERT(s.d_alloced);
ASSERT(!s.d_ptr == !s.d_len);
// Now go around chosing blocks at random to be allocated or freed
// in random order.

for (int i = 0; i < ITERATIONS; ++i) {
const bool alloc = numBlocksInUse > 3 * QUARTER_BLOCKS
? false
: numBlocksInUse < QUARTER_BLOCKS
? true
: (bdlb::Random::generate15(&randNum) & 1);

// Steer the # of blocks allocated to be at around half the
// slots, give or take a quarter.

int index =
bdlb::Random::generate15(&randNum) % MAX_NUM_BLOCKS;
while (alloc == blocks[index].d_alloced) {
index = (index + 1) % MAX_NUM_BLOCKS;
}
Block& s = blocks[index];

if (alloc) {
// allocate

ASSERT(!s.d_alloced);
ASSERT(!s.d_ptr);

s.d_ptr = (char *) ta.allocate(s.d_len);
s.d_alloced = true;

ASSERT(!s.d_ptr == !s.d_len);
s.d_fill = (char) bdlb::Random::generate15(&randNum);
if (s.d_ptr) {
++numBlocksInUse;
++numAllocations;
memset(s.d_ptr, s.d_fill, s.d_len);
}

char *end = s.d_ptr + s.d_len;
char *f = bsl::find_if(s.d_ptr, end, TC::NotEqual(s.d_fill));
ASSERT(f == end);
memset(s.d_ptr, ~s.d_fill, s.d_len);

ta.deallocate(s.d_ptr);
s.d_ptr = 0;
s.d_alloced = false;
--numBlocks;
if (s.d_len) {
--numBlocksInUse;
// verify block aligned

LOOP3_ASSERT((void *) s.d_ptr, s.d_len, s.d_align,
0 == ((UintPtr) s.d_ptr & (s.d_align - 1)));
}
else {
// free

ASSERT(s.d_alloced);
ASSERT(!s.d_ptr == !s.d_len);

char *end = s.d_ptr + s.d_len;
char *f =
bsl::find_if(s.d_ptr, end, TC::NotEqual(s.d_fill));
ASSERT(f == end);
memset(s.d_ptr, ~s.d_fill, s.d_len);

ta.deallocate(s.d_ptr);
s.d_ptr = 0;
s.d_alloced = false;
if (s.d_len) {
--numBlocksInUse;
}
}

ASSERT(numBlocksInUse <= numAllocations);
ASSERT((int) ta.numBlocksInUse() == numBlocksInUse);
ASSERT(ta.numAllocations() == numAllocations);
}

ASSERT((int) ta.numBlocksInUse() == numBlocksInUse);
ta.release();
}

ta.release();
} break;
case 16: {
//---------------------------------------------------------------------
Expand Down

0 comments on commit 22fb795

Please sign in to comment.