diff --git a/test/.gitignore b/test/.gitignore index 4d4eac615..b4f79d35e 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,5 +1,6 @@ -# ignore object files +# ignore object and executable files *.o +tests # ignore the library, download your own copy via install.sh catch.hpp diff --git a/test/Makefile b/test/Makefile index 912226508..d9d91324a 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,7 +1,8 @@ TARGET = tests LIBS = -lm CC = c++ -CFLAGS = -g -Wall +CFLAGS = -g -Wall -std=c++1y +INCLUDE = "../" .PHONY: default all clean @@ -12,13 +13,17 @@ OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp)) HEADERS = $(wildcard *.hpp) %.o: %.cpp $(HEADERS) - $(CC) $(CFLAGS) -c $< -o $@ + $(CC) $(CFLAGS) -I $(INCLUDE) -c $< -o $@ .PRECIOUS: $(TARGET) $(OBJECTS) $(TARGET): $(OBJECTS) - $(CC) $(OBJECTS) -Wall $(LIBS) -o $@ + $(CC) $(OBJECTS) -Wall $(LIBS) -o $@ clean: - -rm -f *.o - -rm -f $(TARGET) + -rm -f *.o + -rm -f $(TARGET) + +test: + make + ./tests --success diff --git a/test/spinlock.cpp b/test/spinlock.cpp new file mode 100644 index 000000000..2d6519259 --- /dev/null +++ b/test/spinlock.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +#include "catch.hpp" +#include "utils/sync/spinlock.hpp" + +#include + +TEST_CASE("a thread can acquire and release the lock", "[spinlock]") +{ + SpinLock lock; + + lock.acquire(); + // i have a lock + lock.release(); + + REQUIRE(true); +} + +int x = 0; + +SpinLock lock; + +void test_lock() +{ + using namespace std::literals; + + lock.acquire(); + x++; + + REQUIRE(x < 2); + std::this_thread::sleep_for(1s); + + x--; + lock.release(); +} + +TEST_CASE("only one thread at a time can own the lock", "[spinlock]") +{ + std::vector threads; + + for(int i = 0; i < 10; ++i) + threads.push_back(std::thread(test_lock)); + + for(auto& thread : threads){ + thread.join(); + } +} diff --git a/utils/sync/spinlock.hpp b/utils/sync/spinlock.hpp index bc46e63b8..f9acb75af 100644 --- a/utils/sync/spinlock.hpp +++ b/utils/sync/spinlock.hpp @@ -19,7 +19,7 @@ public: } private: - std::atomic_flag lock; + std::atomic_flag lock = ATOMIC_FLAG_INIT; }; #endif