Skip to content
Snippets Groups Projects
threads.hpp 1.99 KiB
Newer Older
Nicolas Pope's avatar
Nicolas Pope committed
/**
 * @file threads.hpp
 * @copyright Copyright (c) 2020 University of Turku, MIT License
 * @author Nicolas Pope
 */

#pragma once

#include <mutex>
#include <shared_mutex>
#include <ftl/lib/ctpl_stl.hpp>

#define POOL_SIZE 10

// #define DEBUG_MUTEX
Nicolas Pope's avatar
Nicolas Pope committed
#define MUTEX_TIMEOUT 2

#if defined DEBUG_MUTEX
#include <ftl/lib/loguru.hpp>
#include <chrono>
#include <type_traits>

#define MUTEX std::timed_mutex
#define RECURSIVE_MUTEX std::recursive_timed_mutex
#define SHARED_MUTEX std::shared_timed_mutex

#define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::milliseconds(MUTEX_TIMEOUT)); while (!L) { LOG(ERROR) << "Mutex timeout"; L.try_lock_for(std::chrono::milliseconds(MUTEX_TIMEOUT)); };
#define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M, std::chrono::milliseconds(MUTEX_TIMEOUT)); while (!L) { LOG(ERROR) << "Mutex timeout"; L.try_lock_for(std::chrono::milliseconds(MUTEX_TIMEOUT)); };

#else
#define MUTEX std::mutex
#define RECURSIVE_MUTEX std::recursive_mutex
#define SHARED_MUTEX std::shared_mutex

#define UNIQUE_LOCK(M,L) std::unique_lock<std::remove_reference<decltype(M)>::type> L(M);
#define SHARED_LOCK(M,L) std::shared_lock<std::remove_reference<decltype(M)>::type> L(M);
#endif  // DEBUG_MUTEX

#define SHARED_LOCK_TYPE(M) std::shared_lock<M>

namespace ftl {
	extern ctpl::thread_pool pool;

namespace threads {

/** Upgrade shared lock to exclusive lock and re-acquire shared lock at end of 
 * scope. */
class _write_lock {
public:
Nicolas Pope's avatar
Nicolas Pope committed
	explicit _write_lock(std::shared_mutex& mtx) : mtx_(&mtx) {
Nicolas Pope's avatar
Nicolas Pope committed
		mtx_->unlock_shared();
		mtx_->lock();
	}

	~_write_lock() {
		mtx_->unlock();
		mtx_->lock_shared();
	}

private:
	std::shared_mutex* const mtx_;
};

/** Upgrade already acquired SHARED_LOCK to exclusive lock and re-acquire shared
 * lock at end of scope. Shared lock must be already acquired on mutex! If more
 * careful locking is required, use std::..._lock directly */
#define WRITE_LOCK(M,L) ftl::threads::_write_lock L(M);

}
}