@@ -96,19 +96,20 @@ TestResult ConcurrencyTest::run() {
9696 std::cerr << " Concurrent allocations test failed: " << result1.error_message << std::endl;
9797 return false ;
9898 }
99+ std::cout << " Concurrent allocations test passed" << std::endl;
99100
100101 auto result2 = testConcurrentDeviceSwitching ();
101102 if (!result2.passed ) {
102103 std::cerr << " Concurrent device switching test failed: " << result2.error_message << std::endl;
103104 return false ;
104105 }
105-
106+ std::cout << " Concurrent device switching test passed " << std::endl;
106107 auto result3 = testMemoryAllocationRace ();
107108 if (!result3.passed ) {
108109 std::cerr << " Memory allocation race test failed: " << result3.error_message << std::endl;
109110 return false ;
110111 }
111-
112+ std::cout << " Memory allocation race test passed " << std::endl;
112113 return true ;
113114 } catch (const std::exception &e) {
114115 std::cerr << " ConcurrencyTest failed with exception: " << e.what () << std::endl;
@@ -119,19 +120,20 @@ TestResult ConcurrencyTest::run() {
119120
120121TestResult ConcurrencyTest::testConcurrentAllocations () {
121122 return measureTime (" ConcurrentAllocations" , [this ]() -> bool {
122- const int num_threads = 8 ;
123123 const int allocations_per_thread = 100 ;
124124 std::vector<std::thread> threads;
125125 std::atomic<int > success_count{0 };
126126 std::atomic<int > failure_count{0 };
127127
128- for (int i = 0 ; i < num_threads ; ++i) {
128+ for (int i = 0 ; i < num_threads_ ; ++i) {
129129 threads.emplace_back ([&, i]() {
130130 try {
131131 for (int j = 0 ; j < allocations_per_thread; ++j) {
132132 // Allocate memory of random size
133133 size_t size = 64 + (j % 1024 );
134+ spdlog::debug (" Thread {}: ConcurrentAllocations: Allocating memory of size {}" , i, size);
134135 auto memory = context::allocateMemory (size);
136+ spdlog::debug (" Thread {}: ConcurrentAllocations: Memory allocated successfully" , i);
135137 if (memory && memory->size () == size) {
136138 success_count++;
137139 } else {
@@ -152,7 +154,7 @@ TestResult ConcurrencyTest::testConcurrentAllocations() {
152154 thread.join ();
153155 }
154156
155- int total_expected = num_threads * allocations_per_thread;
157+ int total_expected = num_threads_ * allocations_per_thread;
156158 if (success_count.load () != total_expected) {
157159 std::cerr << " Concurrent allocation test failed: expected " << total_expected
158160 << " successes, got " << success_count.load ()
@@ -166,7 +168,6 @@ TestResult ConcurrencyTest::testConcurrentAllocations() {
166168
167169TestResult ConcurrencyTest::testConcurrentDeviceSwitching () {
168170 return measureTime (" ConcurrentDeviceSwitching" , [this ]() -> bool {
169- const int num_threads = 4 ;
170171 std::vector<std::thread> threads;
171172 std::atomic<int > success_count{0 };
172173 std::atomic<int > failure_count{0 };
@@ -185,7 +186,7 @@ TestResult ConcurrencyTest::testConcurrentDeviceSwitching() {
185186 return true ;
186187 }
187188
188- for (int i = 0 ; i < num_threads ; ++i) {
189+ for (int i = 0 ; i < num_threads_ ; ++i) {
189190 threads.emplace_back ([&, i, devices]() {
190191 try {
191192 for (int j = 0 ; j < 50 ; ++j) {
@@ -239,22 +240,23 @@ TestResult ConcurrencyTest::testConcurrentDeviceSwitching() {
239240TestResult ConcurrencyTest::testMemoryAllocationRace () {
240241 return measureTime (" MemoryAllocationRace" , [this ]() -> bool {
241242 const int num_threads = 16 ;
242- const int allocations_per_thread = 1000 ;
243+ const int allocations_per_thread = 1024 ;
243244 std::vector<std::thread> threads;
244245 std::atomic<int > success_count{0 };
245246 std::atomic<int > failure_count{0 };
246- std::vector<std::shared_ptr< Memory> > all_allocations;
247+ std::vector<Memory> all_allocations;
247248 std::mutex allocations_mutex;
248249
249250 for (int i = 0 ; i < num_threads; ++i) {
250251 threads.emplace_back ([&, i]() {
251- std::vector<std::shared_ptr< Memory> > thread_allocations;
252+ std::vector<Memory> thread_allocations;
252253 try {
253254 for (int j = 0 ; j < allocations_per_thread; ++j) {
254255 size_t size = 64 + (j % 1024 );
255256 auto memory = context::allocateMemory (size);
256257 if (memory) {
257- thread_allocations.push_back (memory);
258+ // Copy the Memory object - reference counting will handle the lifecycle
259+ thread_allocations.push_back (*memory);
258260 success_count++;
259261 } else {
260262 failure_count++;
@@ -264,9 +266,11 @@ TestResult ConcurrencyTest::testMemoryAllocationRace() {
264266 if (j % 10 == 0 && !thread_allocations.empty ()) {
265267 thread_allocations.pop_back ();
266268 }
269+ spdlog::debug (" Thread {} iteration {}: Memory allocation race: Allocated memory of size {} done" , i, j, size);
267270 }
268271
269- // Store remaining allocations
272+ // Store remaining allocations - copying Memory objects with reference counting
273+ // prevents double-free while maintaining the original test logic
270274 std::lock_guard<std::mutex> lock (allocations_mutex);
271275 all_allocations.insert (all_allocations.end (),
272276 thread_allocations.begin (),
@@ -284,7 +288,7 @@ TestResult ConcurrencyTest::testMemoryAllocationRace() {
284288
285289 // Verify all allocations are valid
286290 for (const auto &memory : all_allocations) {
287- if (!memory || !memory-> data ()) {
291+ if (!memory. data ()) {
288292 std::cerr << " Invalid memory allocation found" << std::endl;
289293 return false ;
290294 }
@@ -297,6 +301,7 @@ TestResult ConcurrencyTest::testMemoryAllocationRace() {
297301 return false ;
298302 }
299303
304+ spdlog::debug (" Memory allocation race test: All allocations: {}" , all_allocations.size ());
300305 return true ;
301306 });
302307}
@@ -778,7 +783,7 @@ TestResult StressTest::run() {
778783TestResult StressTest::testHighFrequencyAllocations () {
779784 return measureTime (" HighFrequencyAllocations" , [this ]() -> bool {
780785 try {
781- const int num_allocations = 100000 ;
786+ const int num_allocations = iterations_ ;
782787 std::vector<std::shared_ptr<Memory>> memories;
783788 memories.reserve (num_allocations);
784789
0 commit comments