void* operator new (std::size_t len) throw(std::bad_alloc) { void* data = nullptr; if (enable_buffer_protection) { // Allocate requested memory + enough to fit checksum at start and end data = malloc(len + sizeof(buffer_protection_checksum) * 2); // Write checksums auto* temp = reinterpret_cast<char*>(data); memcpy(temp, &buffer_protection_checksum, sizeof(buffer_protection_checksum)); memcpy(temp + sizeof(buffer_protection_checksum) + len, &buffer_protection_checksum, sizeof(buffer_protection_checksum)); } else { data = malloc(len); } if (enable_debugging_verbose) { DPRINTF("malloc(%llu bytes) == %p\n", (unsigned long long) len, data); safe_print_symbol(1, __builtin_return_address(0)); safe_print_symbol(2, __builtin_return_address(1)); } if (UNLIKELY(!data)) { print_backtrace(); DPRINTF("malloc(%llu bytes): FAILED\n", (unsigned long long) len); throw std::bad_alloc(); } if (enable_debugging) { if (!free_allocs.empty()) { auto* x = free_allocs.pop(); new(x) allocation((char*) data, len, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); } else if (!allocs.free_capacity()) { DPRINTF("[WARNING] Internal fixed vectors are FULL, expect bogus double free messages\n"); } else { allocs.emplace((char*) data, len, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); } } if (enable_buffer_protection) { // We need to return a pointer to the allocated memory + 4 // e.g. after our first checksum return reinterpret_cast<void*>(reinterpret_cast<char*>(data) + sizeof(buffer_protection_checksum)); } else { return data; } }
void add(void* ra) { // need free space to take more samples if (samplerq->free_capacity()) samplerq->add((uintptr_t) ra); // return when its not our turn if (lockless) return; // transfer all the built up samplings transferq->copy(samplerq->first(), samplerq->size()); samplerq->clear(); lockless = 1; }