109 lines
2.6 KiB
C++
109 lines
2.6 KiB
C++
#include "Core/Monitor.h"
|
|
#include <iostream>
|
|
#include <thread>
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
using namespace uLib;
|
|
|
|
void TestBasicLock() {
|
|
std::cout << "Testing basic Mutex Lock/Unlock..." << std::endl;
|
|
Mutex m;
|
|
m.Lock();
|
|
m.Unlock();
|
|
assert(m.TryLock());
|
|
m.Unlock();
|
|
std::cout << " Passed." << std::endl;
|
|
}
|
|
|
|
void TestScopedLock() {
|
|
std::cout << "Testing Mutex::ScopedLock..." << std::endl;
|
|
Mutex m;
|
|
{
|
|
Mutex::ScopedLock lock(m);
|
|
assert(!m.TryLock());
|
|
}
|
|
assert(m.TryLock());
|
|
m.Unlock();
|
|
std::cout << " Passed." << std::endl;
|
|
}
|
|
|
|
void TestTimedLock() {
|
|
std::cout << "Testing Mutex TryLockFor..." << std::endl;
|
|
Mutex m;
|
|
m.Lock();
|
|
auto start = std::chrono::steady_clock::now();
|
|
bool locked = m.TryLockFor(100);
|
|
auto end = std::chrono::steady_clock::now();
|
|
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
|
|
|
|
assert(!locked);
|
|
assert(diff >= 100);
|
|
m.Unlock();
|
|
std::cout << " Passed (waited " << diff << "ms)." << std::endl;
|
|
}
|
|
|
|
void TestMacros() {
|
|
std::cout << "Testing ULIB_STATIC_LOCK and ULIB_MUTEX_LOCK macros..." << std::endl;
|
|
|
|
int counter = 0;
|
|
auto task = [&]() {
|
|
for(int i=0; i<500; ++i) {
|
|
ULIB_STATIC_LOCK(-1) {
|
|
counter++;
|
|
}
|
|
}
|
|
};
|
|
|
|
std::vector<std::thread> threads;
|
|
for(int i=0; i<4; ++i) threads.emplace_back(task);
|
|
for(auto& t : threads) t.join();
|
|
|
|
assert(counter == 2000);
|
|
|
|
Mutex m;
|
|
int counter2 = 0;
|
|
ULIB_MUTEX_LOCK(m, -1) {
|
|
counter2++;
|
|
}
|
|
assert(counter2 == 1);
|
|
|
|
std::cout << " Passed." << std::endl;
|
|
}
|
|
|
|
void TestMonitor() {
|
|
std::cout << "Testing Monitor pattern..." << std::endl;
|
|
struct Resource {
|
|
int value = 0;
|
|
void increment() { value++; }
|
|
};
|
|
|
|
Monitor<Resource> monitor(new Resource());
|
|
|
|
auto task = [&]() {
|
|
for(int i=0; i<1000; ++i) {
|
|
monitor.Access([](Resource& r) {
|
|
r.increment();
|
|
});
|
|
}
|
|
};
|
|
|
|
std::vector<std::thread> threads;
|
|
for(int i=0; i<5; ++i) threads.emplace_back(task);
|
|
for(auto& t : threads) t.join();
|
|
|
|
int final_value = monitor.Access([](Resource& r) { return r.value; });
|
|
assert(final_value == 5000);
|
|
std::cout << " Passed (final value: " << final_value << ")." << std::endl;
|
|
}
|
|
|
|
int main() {
|
|
TestBasicLock();
|
|
TestScopedLock();
|
|
TestTimedLock();
|
|
TestMacros();
|
|
TestMonitor();
|
|
std::cout << "All Mutex and Monitor tests passed!" << std::endl;
|
|
return 0;
|
|
}
|