* Factor out explicit Config type Instead of using snmalloc::Alloc::Config, expose snmalloc::Config, which is then used to derive the allocator type. * Move globalalloc to front end. * Remove unneed template parameter from global snmalloc functions. * Remove SNMALLOC_PASS_THROUGH VeronaRT now has an abstraction layer which can easily replace the allocator. Having such a complex integration still in snmalloc does not make sense. * Take some global functions off of local alloc. * Drop comparison overloads on atomic Capptr. Performing a comparison on two atomic ptr is a complex operation, and should not be implicit. The memory model order and such things needs to be considered by the caller. * Remove function_ref and use templates The implementation prefers to use templates over the function_ref. This now only exists in the Pal for a currently unused feature. * Removing function_ref reduces stl needs. * Remove use of __is_convertible to support older g++ * Inline function that is only used once. * Remove unused function * Restrict ThreadAlloc usage to globalalloc This commit introduces various inline functions on snmalloc:: that perform allocation/deallocation using the thread local allocator. They remove all usage from a particular test. * Move cheri checks to own file. * Refactor is_owned checks. * Move alloc_size and check_size to globalalloc. * Minor simplification of dealloc path * Fix up is_owned to take a config * Improve usage of scoped allocator. * Handle Config_ in globalalloc.
95 lines
1.8 KiB
C++
95 lines
1.8 KiB
C++
#include "test/opt.h"
|
|
#include "test/setup.h"
|
|
#include "test/usage.h"
|
|
#include "test/xoroshiro.h"
|
|
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
#include <snmalloc/snmalloc.h>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
using namespace snmalloc;
|
|
|
|
std::vector<uint64_t> counters{};
|
|
|
|
template<typename F>
|
|
class ParallelTest
|
|
{
|
|
private:
|
|
std::atomic<bool> flag = false;
|
|
std::atomic<size_t> ready = 0;
|
|
uint64_t start;
|
|
uint64_t end;
|
|
std::atomic<size_t> complete = 0;
|
|
size_t cores;
|
|
F f;
|
|
|
|
void run(size_t id)
|
|
{
|
|
auto prev = ready.fetch_add(1);
|
|
if (prev + 1 == cores)
|
|
{
|
|
start = Aal::tick();
|
|
flag = true;
|
|
}
|
|
while (!flag)
|
|
Aal::pause();
|
|
|
|
f(id);
|
|
|
|
prev = complete.fetch_add(1);
|
|
if (prev + 1 == cores)
|
|
{
|
|
end = Aal::tick();
|
|
}
|
|
}
|
|
|
|
public:
|
|
ParallelTest(F&& f, size_t cores) : cores(cores), f(std::forward<F>(f))
|
|
{
|
|
std::thread* t = new std::thread[cores];
|
|
|
|
for (size_t i = 0; i < cores; i++)
|
|
{
|
|
t[i] = std::thread(&ParallelTest::run, this, i);
|
|
}
|
|
// Wait for all the threads.
|
|
for (size_t i = 0; i < cores; i++)
|
|
{
|
|
t[i].join();
|
|
}
|
|
|
|
delete[] t;
|
|
}
|
|
|
|
uint64_t time()
|
|
{
|
|
return end - start;
|
|
}
|
|
};
|
|
|
|
int main()
|
|
{
|
|
auto nthreads = std::thread::hardware_concurrency();
|
|
counters.resize(nthreads);
|
|
|
|
ParallelTest test(
|
|
[](size_t id) {
|
|
auto start = Aal::tick();
|
|
snmalloc::dealloc(snmalloc::alloc(1));
|
|
auto end = Aal::tick();
|
|
counters[id] = end - start;
|
|
},
|
|
nthreads);
|
|
|
|
std::cout << "Taken: " << test.time() << std::endl;
|
|
std::sort(counters.begin(), counters.end());
|
|
uint64_t start = 0;
|
|
for (auto counter : counters)
|
|
{
|
|
std::cout << "Thread time " << counter << " (" << counter - start << ")"
|
|
<< std::endl;
|
|
start = counter;
|
|
}
|
|
} |