test: expand SmartPointer and thread affinity test coverage and update build preset
This commit is contained in:
@@ -18,7 +18,7 @@ This rule provides instructions for building the uLib project using the micromam
|
|||||||
```bash
|
```bash
|
||||||
export MAMBA_EXE="/home/share/micromamba/bin/micromamba"
|
export MAMBA_EXE="/home/share/micromamba/bin/micromamba"
|
||||||
export MAMBA_ROOT_PREFIX="/home/share/micromamba"
|
export MAMBA_ROOT_PREFIX="/home/share/micromamba"
|
||||||
export PRESET="clang-make"
|
export PRESET="clang-debug"
|
||||||
eval "$(${MAMBA_EXE} shell hook --shell bash)"
|
eval "$(${MAMBA_EXE} shell hook --shell bash)"
|
||||||
micromamba activate uLib
|
micromamba activate uLib
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -10,17 +10,52 @@
|
|||||||
|
|
||||||
using namespace uLib;
|
using namespace uLib;
|
||||||
|
|
||||||
|
std::vector<int> GetAvailableCpus() {
|
||||||
|
std::vector<int> available;
|
||||||
|
#ifdef __linux__
|
||||||
|
cpu_set_t cpuset;
|
||||||
|
CPU_ZERO(&cpuset);
|
||||||
|
if (sched_getaffinity(0, sizeof(cpu_set_t), &cpuset) == 0) {
|
||||||
|
for (int i = 0; i < CPU_SETSIZE; ++i) {
|
||||||
|
if (CPU_ISSET(i, &cpuset)) {
|
||||||
|
available.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestThread : public Thread {
|
||||||
|
public:
|
||||||
|
void Run() override {
|
||||||
|
Thread::Sleep(200);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void TestThreadAffinity() {
|
void TestThreadAffinity() {
|
||||||
std::cout << "Testing Thread Affinity..." << std::endl;
|
std::cout << "Testing Thread Affinity..." << std::endl;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
Thread t;
|
auto available = GetAvailableCpus();
|
||||||
|
if (available.empty()) {
|
||||||
|
std::cout << " No CPUs available for affinity test, skipping." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int target_cpu = available[0];
|
||||||
|
std::cout << " Using CPU " << target_cpu << std::endl;
|
||||||
|
|
||||||
|
TestThread t;
|
||||||
t.Start();
|
t.Start();
|
||||||
t.SetAffinity(0); // Bind to CPU 0
|
t.SetAffinity(target_cpu);
|
||||||
|
|
||||||
cpu_set_t cpuset;
|
cpu_set_t cpuset;
|
||||||
CPU_ZERO(&cpuset);
|
CPU_ZERO(&cpuset);
|
||||||
pthread_getaffinity_np(t.GetNativeHandle(), sizeof(cpu_set_t), &cpuset);
|
int s = pthread_getaffinity_np(t.GetNativeHandle(), sizeof(cpu_set_t), &cpuset);
|
||||||
assert(CPU_ISSET(0, &cpuset));
|
if (s != 0) {
|
||||||
|
std::cerr << "Error: pthread_getaffinity_np failed with code " << s << std::endl;
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
assert(CPU_ISSET(target_cpu, &cpuset));
|
||||||
|
|
||||||
t.Join();
|
t.Join();
|
||||||
std::cout << " Passed (Thread bound to CPU 0)." << std::endl;
|
std::cout << " Passed (Thread bound to CPU 0)." << std::endl;
|
||||||
@@ -32,9 +67,15 @@ void TestThreadAffinity() {
|
|||||||
void TestTeamAffinity() {
|
void TestTeamAffinity() {
|
||||||
std::cout << "Testing Team Affinity..." << std::endl;
|
std::cout << "Testing Team Affinity..." << std::endl;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#ifdef _OPENMP
|
auto available = GetAvailableCpus();
|
||||||
|
if (available.size() < 2) {
|
||||||
|
std::cout << " Not enough CPUs available for Team affinity test, skipping." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::vector<int> cpus = {available[0], available[1]};
|
||||||
|
std::cout << " Using CPUs " << cpus[0] << ", " << cpus[1] << std::endl;
|
||||||
|
|
||||||
Team team(2);
|
Team team(2);
|
||||||
std::vector<int> cpus = {0, 1};
|
|
||||||
team.SetAffinity(cpus);
|
team.SetAffinity(cpus);
|
||||||
|
|
||||||
// We check affinity inside a parallel region
|
// We check affinity inside a parallel region
|
||||||
@@ -48,7 +89,6 @@ void TestTeamAffinity() {
|
|||||||
assert(CPU_ISSET(expected_cpu, &cpuset));
|
assert(CPU_ISSET(expected_cpu, &cpuset));
|
||||||
}
|
}
|
||||||
std::cout << " Passed (Team threads bound correctly)." << std::endl;
|
std::cout << " Passed (Team threads bound correctly)." << std::endl;
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
std::cout << " Affinity not supported on this OS, skipping." << std::endl;
|
std::cout << " Affinity not supported on this OS, skipping." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Core/Object.h"
|
||||||
#include "Core/SmartPointer.h"
|
#include "Core/SmartPointer.h"
|
||||||
#include "testing-prototype.h"
|
#include "testing-prototype.h"
|
||||||
|
|
||||||
@@ -34,12 +35,12 @@ using namespace uLib;
|
|||||||
|
|
||||||
namespace Test {
|
namespace Test {
|
||||||
|
|
||||||
struct ObjectMockInterface {
|
struct ObjectMockInterface : public Object {
|
||||||
virtual void PrintValue()=0;
|
virtual void PrintValue()=0;
|
||||||
virtual int& Value()=0;
|
virtual int& Value()=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectMock : ObjectMockInterface {
|
class ObjectMock : public ObjectMockInterface {
|
||||||
int value;
|
int value;
|
||||||
public:
|
public:
|
||||||
int& Value() { return value; }
|
int& Value() { return value; }
|
||||||
@@ -72,12 +73,15 @@ int main () {
|
|||||||
SmartPointer<Test::ObjectMock> spt(new Test::ObjectMock);
|
SmartPointer<Test::ObjectMock> spt(new Test::ObjectMock);
|
||||||
TEST1(test_smpt(spt));
|
TEST1(test_smpt(spt));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SmartPointer<Test::ObjectMock> spt;
|
SmartPointer<Test::ObjectMock> spt;
|
||||||
TEST1(test_smpt(spt));
|
TEST1(test_smpt(spt));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
SmartPointer<Test::ObjectMock> spt = new SmartPointer<Test::ObjectMock>;
|
SmartPointer<Test::ObjectMock> base_spt;
|
||||||
|
SmartPointer<Test::ObjectMock> spt = &base_spt;
|
||||||
TEST1(test_smpt(spt));
|
TEST1(test_smpt(spt));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +92,28 @@ int main () {
|
|||||||
TEST1(test_smpt(spt));
|
TEST1(test_smpt(spt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Test::ObjectMock obj;
|
||||||
|
SmartPointer<Object> spt1 = obj;
|
||||||
|
SmartPointer<Test::ObjectMock> spt2 = obj;
|
||||||
|
SmartPointer<Test::ObjectMockInterface> spt = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Test::ObjectMock *obj = new Test::ObjectMock;
|
||||||
|
SmartPointer<Test::ObjectMock> spt(obj);
|
||||||
|
SmartPointer<Test::ObjectMock> spt2(spt);
|
||||||
|
SmartPointer<Test::ObjectMock> spt3(spt);
|
||||||
|
SmartPointer<Test::ObjectMock> spt4(spt2);
|
||||||
|
spt->Value() = 123;
|
||||||
|
spt2->Value() = 456;
|
||||||
|
spt3->Value() = 789;
|
||||||
|
spt4->Value() = 101112;
|
||||||
|
TEST1(spt->Value() == 101112);
|
||||||
|
TEST1(spt2->Value() == 101112);
|
||||||
|
TEST1(spt3->Value() == 101112);
|
||||||
|
TEST1(spt4->Value() == 101112);
|
||||||
|
}
|
||||||
|
|
||||||
END_TESTING;
|
END_TESTING;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user