build; add (untested) paths for win32 builds
This commit is contained in:
parent
42cdad1263
commit
ff5f79a858
@ -30,7 +30,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
###############################################################################
|
||||
set (UTIL_FILES)
|
||||
add_library(cruft)
|
||||
|
||||
|
||||
###############################################################################
|
||||
@ -44,6 +44,7 @@ if (BACKTRACE_LIB_FOUND)
|
||||
list (APPEND UTIL_FILES backtrace_execinfo.cpp)
|
||||
elseif (HAVE_CAPTURESTACKBACKTRACE)
|
||||
list (APPEND UTIL_FILES backtrace_stackwalk.cpp)
|
||||
target_link_libraries(cruft DbgHelp)
|
||||
else ()
|
||||
list (APPEND UTIL_FILES backtrace_null.cpp)
|
||||
endif ()
|
||||
@ -81,8 +82,6 @@ list (
|
||||
posix/except.hpp
|
||||
posix/fd.cpp
|
||||
posix/fd.hpp
|
||||
posix/socket.cpp
|
||||
posix/socket.hpp
|
||||
)
|
||||
|
||||
|
||||
@ -91,13 +90,12 @@ if (LINUX)
|
||||
list (APPEND UTIL_FILES
|
||||
thread/event_linux.cpp
|
||||
thread/flag_linux.cpp
|
||||
thread/semaphore_linux.cpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
if (NOT WINDOWS)
|
||||
if (NOT WIN32)
|
||||
list (
|
||||
APPEND UTIL_FILES
|
||||
memory/buffer/circular.cpp
|
||||
@ -114,13 +112,15 @@ if (NOT WINDOWS)
|
||||
posix/fwd.hpp
|
||||
posix/map.cpp
|
||||
posix/map.hpp
|
||||
posix/socket.cpp
|
||||
posix/socket.hpp
|
||||
time_posix.cpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
if (WINDOWS)
|
||||
if (WIN32)
|
||||
list (
|
||||
APPEND UTIL_FILES
|
||||
debug_win32.cpp
|
||||
@ -128,8 +128,6 @@ if (WINDOWS)
|
||||
io_win32.cpp
|
||||
io_win32.hpp
|
||||
thread/event_win32.cpp
|
||||
thread/flag_win32.cpp
|
||||
thread/semaphore_win32.cpp
|
||||
library_win32.cpp
|
||||
library_win32.hpp
|
||||
time_win32.cpp
|
||||
@ -140,6 +138,41 @@ if (WINDOWS)
|
||||
win32/registry.cpp
|
||||
win32/registry.hpp
|
||||
)
|
||||
|
||||
target_link_libraries (cruft ws2_32)
|
||||
endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
list (APPEND UTIL_FILES
|
||||
thread/event.hpp
|
||||
thread/semaphore.hpp
|
||||
thread/flag.hpp
|
||||
)
|
||||
|
||||
if (LINUX)
|
||||
list (APPEND UTIL_FILES
|
||||
thread/event_futex.cpp
|
||||
thread/event_futex.hpp
|
||||
thread/semaphore_linux.hpp
|
||||
thread/semaphore_linux.cpp
|
||||
thread/flag_futex.cpp
|
||||
thread/flag_futex.hpp
|
||||
)
|
||||
elseif (WIN32)
|
||||
list (APPEND UTIL_FILES
|
||||
thread/event_std.cpp
|
||||
thread/event_std.hpp
|
||||
thread/semaphore_win32.hpp
|
||||
thread/semaphore_win32.cpp
|
||||
thread/flag_std.cpp
|
||||
thread/flag_std.hpp
|
||||
)
|
||||
else ()
|
||||
list (APPEND UTIL_FILES
|
||||
thread/flag_std.cpp
|
||||
thread/flag_std.hpp
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
@ -364,7 +397,6 @@ list (
|
||||
thread/flag.hpp
|
||||
thread/monitor.cpp
|
||||
thread/monitor.hpp
|
||||
thread/semaphore.hpp
|
||||
thread/ticketlock.cpp
|
||||
thread/ticketlock.hpp
|
||||
thread/spinlock.cpp
|
||||
@ -420,7 +452,7 @@ DEPENDS
|
||||
|
||||
|
||||
###############################################################################
|
||||
add_library(cruft ${UTIL_FILES})
|
||||
target_sources(cruft PRIVATE ${UTIL_FILES})
|
||||
add_library(cruft-util ALIAS cruft)
|
||||
target_include_directories(cruft PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
@ -437,7 +469,9 @@ target_link_libraries(cruft ${MATH_LIBS})
|
||||
|
||||
# HACK: -ldl isn't getting discovered correctly so we add it unconditionally
|
||||
# for the time being.
|
||||
target_link_libraries(cruft dl)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(cruft dl)
|
||||
endif ()
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
159
memory/buffer/paged_win32.cpp
Normal file
159
memory/buffer/paged_win32.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2015 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "paged.hpp"
|
||||
|
||||
#include "../../cast.hpp"
|
||||
#include "../../maths.hpp"
|
||||
#include "../../pointer.hpp"
|
||||
#include "../../posix/except.hpp"
|
||||
#include "../system.hpp"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
using cruft::memory::buffer::paged;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
paged::paged (size_t bytes, size_t _window):
|
||||
m_window (round_up (_window, pagesize ()))
|
||||
{
|
||||
// reserve the address region with no access permissions
|
||||
m_begin = reinterpret_cast<char*> (
|
||||
mmap (nullptr, bytes, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)
|
||||
);
|
||||
|
||||
if (m_begin == MAP_FAILED)
|
||||
posix::error::throw_code ();
|
||||
|
||||
// remap the initial window with read/write permissions
|
||||
m_cursor = m_begin + round_up (min (m_window, bytes), pagesize ());
|
||||
if (MAP_FAILED == mmap (m_begin,
|
||||
m_cursor - m_begin,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))
|
||||
posix::error::throw_code ();
|
||||
|
||||
// record the nominal end address
|
||||
m_end = m_begin + round_up (bytes, pagesize ());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
paged::~paged ()
|
||||
{
|
||||
// ignore errors in production; we don't want to double throw.
|
||||
auto res = munmap (m_begin, m_end - m_begin);
|
||||
(void)res;
|
||||
CHECK_ZERO (res);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
char*
|
||||
paged::begin (void)&
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
char*
|
||||
paged::end (void)&
|
||||
{
|
||||
return m_end;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
paged::access (char *cursor)
|
||||
{
|
||||
if (cursor < m_cursor)
|
||||
release (cursor);
|
||||
else
|
||||
commit (cursor);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
paged::commit (char *cursor)
|
||||
{
|
||||
// bail if it's already mapped
|
||||
if (cursor <= m_cursor)
|
||||
return;
|
||||
|
||||
if (cursor > m_end || cursor < m_begin)
|
||||
throw std::out_of_range ("invalid commit cursor");
|
||||
|
||||
// bump the request up to page aligned and tack on a little to amortize
|
||||
// syscall overheads
|
||||
cursor = align (cursor, pagesize ()) + m_window;
|
||||
cursor = min (cursor, m_end);
|
||||
|
||||
if (MAP_FAILED == mmap (m_cursor,
|
||||
cursor - m_cursor,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0))
|
||||
posix::error::throw_code ();
|
||||
|
||||
m_cursor = cursor;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
paged::release (char *desired)
|
||||
{
|
||||
if (desired > m_end || desired < m_begin)
|
||||
throw std::out_of_range ("invalid release cursor");
|
||||
|
||||
align (desired, pagesize ());
|
||||
|
||||
// bail if the region is alread unmapped, or if it's not sufficiently
|
||||
// behind the current cursor.
|
||||
if (desired >= m_cursor || cruft::cast::sign<size_t> (m_cursor - desired) < m_window)
|
||||
return;
|
||||
|
||||
desired += m_window;
|
||||
|
||||
if (MAP_FAILED == mmap (desired,
|
||||
m_end - desired,
|
||||
PROT_NONE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
-1, 0))
|
||||
posix::error::throw_code ();
|
||||
|
||||
m_cursor = desired;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
size_t
|
||||
paged::size (void) const
|
||||
{
|
||||
return m_cursor - m_begin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
paged::capacity (void) const
|
||||
{
|
||||
return m_end - m_begin;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
size_t
|
||||
paged::window (void) const
|
||||
{
|
||||
return m_window;
|
||||
}
|
@ -1,53 +1,7 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_EVENT_HPP
|
||||
#define CRUFT_UTIL_THREAD_EVENT_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a reusable synchronisation object that allows threads to wait until
|
||||
/// notify is called.
|
||||
///
|
||||
/// there is no internal state so it is easy to create races between wait
|
||||
/// and notify calls. this makes the class mostly suitable for recurring
|
||||
/// events.
|
||||
///
|
||||
/// the user should ensure no callers are waiting at destruction time
|
||||
/// otherwise they may remain blocked indefinitely.
|
||||
///
|
||||
/// the address of the object is important so it must _never_ be
|
||||
/// relocated in any manner if any caller may be waiting. it may be safe
|
||||
/// to do so if there are no callers waiting (but the relevant functions
|
||||
/// are deleted for safety anyway).
|
||||
class event {
|
||||
public:
|
||||
event ();
|
||||
|
||||
event (const event&) = delete;
|
||||
event (event&&) = delete;
|
||||
event& operator= (const event&) = delete;
|
||||
event& operator= (event&&) = delete;
|
||||
|
||||
/// block until notified
|
||||
void wait (void);
|
||||
|
||||
/// wake all threads that are waiting
|
||||
int notify (void);
|
||||
|
||||
/// wait `count' threads that are waiting
|
||||
int notify (int count);
|
||||
|
||||
private:
|
||||
alignas (4) std::atomic<int> value;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#include "platform.hpp"
|
||||
|
||||
#if defined(PLATFORM_LINUX)
|
||||
#include "event_futex.hpp"
|
||||
#else
|
||||
#include "event_std.hpp"
|
||||
#endif
|
53
thread/event_futex.hpp
Normal file
53
thread/event_futex.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_EVENT_HPP
|
||||
#define CRUFT_UTIL_THREAD_EVENT_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a reusable synchronisation object that allows threads to wait until
|
||||
/// notify is called.
|
||||
///
|
||||
/// there is no internal state so it is easy to create races between wait
|
||||
/// and notify calls. this makes the class mostly suitable for recurring
|
||||
/// events.
|
||||
///
|
||||
/// the user should ensure no callers are waiting at destruction time
|
||||
/// otherwise they may remain blocked indefinitely.
|
||||
///
|
||||
/// the address of the object is important so it must _never_ be
|
||||
/// relocated in any manner if any caller may be waiting. it may be safe
|
||||
/// to do so if there are no callers waiting (but the relevant functions
|
||||
/// are deleted for safety anyway).
|
||||
class event {
|
||||
public:
|
||||
event ();
|
||||
|
||||
event (const event&) = delete;
|
||||
event (event&&) = delete;
|
||||
event& operator= (const event&) = delete;
|
||||
event& operator= (event&&) = delete;
|
||||
|
||||
/// block until notified
|
||||
void wait (void);
|
||||
|
||||
/// wake all threads that are waiting
|
||||
int notify (void);
|
||||
|
||||
/// wait `count' threads that are waiting
|
||||
int notify (int count);
|
||||
|
||||
private:
|
||||
alignas (4) std::atomic<int> value;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
36
thread/event_std.cpp
Normal file
36
thread/event_std.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "event_std.hpp"
|
||||
|
||||
using cruft::thread::event;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
event::event ():
|
||||
m_value (0)
|
||||
{ ; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
event::wait (void)
|
||||
{
|
||||
int const now = m_value;
|
||||
std::unique_lock lk (m_mutex);
|
||||
m_cv.wait (lk, [&,this] () { return now != m_value; });
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
event::notify_one (void)
|
||||
{
|
||||
++m_value;
|
||||
m_cv.notify_one ();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void event::notify_all()
|
||||
{
|
||||
++m_value;
|
||||
m_cv.notify_all ();
|
||||
}
|
55
thread/event_std.hpp
Normal file
55
thread/event_std.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a reusable synchronisation object that allows threads to wait until
|
||||
/// notify is called.
|
||||
///
|
||||
/// there is no internal state so it is easy to create races between wait
|
||||
/// and notify calls. this makes the class mostly suitable for recurring
|
||||
/// events.
|
||||
///
|
||||
/// the user should ensure no callers are waiting at destruction time
|
||||
/// otherwise they may remain blocked indefinitely.
|
||||
///
|
||||
/// the address of the object is important so it must _never_ be
|
||||
/// relocated in any manner if any caller may be waiting. it may be safe
|
||||
/// to do so if there are no callers waiting (but the relevant functions
|
||||
/// are deleted for safety anyway).
|
||||
class event {
|
||||
public:
|
||||
event ();
|
||||
|
||||
event (const event&) = delete;
|
||||
event (event&&) = delete;
|
||||
event& operator= (const event&) = delete;
|
||||
event& operator= (event&&) = delete;
|
||||
|
||||
/// block until notified
|
||||
void wait (void);
|
||||
|
||||
/// wake all threads that are waiting
|
||||
void notify_one (void);
|
||||
|
||||
/// wait `count' threads that are waiting
|
||||
void notify_all (void);
|
||||
|
||||
private:
|
||||
std::atomic<int> m_value;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cv;
|
||||
};
|
||||
}
|
||||
|
@ -1,31 +1,7 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_FLAG_HPP
|
||||
#define CRUFT_UTIL_THREAD_FLAG_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a fire-once event that users can wait upon. if already fired then
|
||||
/// waiting will be a noop.
|
||||
class flag {
|
||||
public:
|
||||
flag ();
|
||||
|
||||
void wait (void);
|
||||
|
||||
int notify (void);
|
||||
int notify (int);
|
||||
|
||||
private:
|
||||
std::atomic<int> value;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "platform.hpp"
|
||||
|
||||
#if defined(PLATFORM_LINUX)
|
||||
#include "flag_futex.hpp"
|
||||
#else
|
||||
#include "flag_std.hpp"
|
||||
#endif
|
||||
|
31
thread/flag_futex.hpp
Normal file
31
thread/flag_futex.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_FLAG_HPP
|
||||
#define CRUFT_UTIL_THREAD_FLAG_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a fire-once event that users can wait upon. if already fired then
|
||||
/// waiting will be a noop.
|
||||
class flag {
|
||||
public:
|
||||
flag ();
|
||||
|
||||
void wait (void);
|
||||
|
||||
int notify (void);
|
||||
int notify (int);
|
||||
|
||||
private:
|
||||
std::atomic<int> value;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
39
thread/flag_std.hpp
Normal file
39
thread/flag_std.hpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// a fire-once event that users can wait upon. if already fired then
|
||||
/// waiting will be a noop.
|
||||
class flag {
|
||||
public:
|
||||
flag ();
|
||||
|
||||
/// blocks indefinitely until the flag has been set.
|
||||
void wait (void);
|
||||
|
||||
/// wake one thread waiting on the flag.
|
||||
///
|
||||
/// it may be possible, through spurious wakeups, that more threads
|
||||
/// are release than requested. though this should not be typical.
|
||||
void notify_one (void);
|
||||
|
||||
/// wake all threads waiting on the flag
|
||||
void notify_all (void);
|
||||
|
||||
private:
|
||||
std::atomic<bool> fired;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_condition;
|
||||
};
|
||||
}
|
@ -1,44 +1,7 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_SEMAPHORE_HPP
|
||||
#define CRUFT_UTIL_THREAD_SEMAPHORE_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// Explicitly does not conform to BasicLockable.
|
||||
class semaphore {
|
||||
public:
|
||||
semaphore (int initial);
|
||||
semaphore ();
|
||||
|
||||
semaphore (const semaphore&) = delete;
|
||||
semaphore& operator= (const semaphore&) = delete;
|
||||
semaphore (semaphore&&) = delete;
|
||||
semaphore& operator= (semaphore&&) = delete;
|
||||
|
||||
int acquire (void);
|
||||
int acquire (int count);
|
||||
int release (void);
|
||||
int release (int count);
|
||||
|
||||
auto lock (void) { return acquire (); }
|
||||
auto unlock (void) { return release (); }
|
||||
|
||||
int value (void) const;
|
||||
|
||||
int operator++ (void);
|
||||
int operator-- (void);
|
||||
|
||||
private:
|
||||
std::atomic<int> m_value;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
#include "platform.hpp"
|
||||
|
||||
#if defined(PLATFORM_LINUX)
|
||||
#include "semaphore_linux.hpp"
|
||||
#else
|
||||
#include "semaphore_win32.hpp"
|
||||
#endif
|
||||
|
44
thread/semaphore_linux.hpp
Normal file
44
thread/semaphore_linux.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#ifndef CRUFT_UTIL_THREAD_SEMAPHORE_HPP
|
||||
#define CRUFT_UTIL_THREAD_SEMAPHORE_HPP
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace cruft::thread {
|
||||
/// Explicitly does not conform to BasicLockable.
|
||||
class semaphore {
|
||||
public:
|
||||
semaphore (int initial);
|
||||
semaphore ();
|
||||
|
||||
semaphore (const semaphore&) = delete;
|
||||
semaphore& operator= (const semaphore&) = delete;
|
||||
semaphore (semaphore&&) = delete;
|
||||
semaphore& operator= (semaphore&&) = delete;
|
||||
|
||||
int acquire (void);
|
||||
int acquire (int count);
|
||||
int release (void);
|
||||
int release (int count);
|
||||
|
||||
auto lock (void) { return acquire (); }
|
||||
auto unlock (void) { return release (); }
|
||||
|
||||
int value (void) const;
|
||||
|
||||
int operator++ (void);
|
||||
int operator-- (void);
|
||||
|
||||
private:
|
||||
std::atomic<int> m_value;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
46
thread/semaphore_win32.hpp
Normal file
46
thread/semaphore_win32.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
namespace cruft::thread {
|
||||
/// Explicitly does not conform to BasicLockable.
|
||||
class semaphore {
|
||||
public:
|
||||
semaphore (int initial);
|
||||
semaphore ();
|
||||
|
||||
semaphore (const semaphore&) = delete;
|
||||
semaphore& operator= (const semaphore&) = delete;
|
||||
semaphore (semaphore&&) = delete;
|
||||
semaphore& operator= (semaphore&&) = delete;
|
||||
|
||||
int acquire (void);
|
||||
int acquire (int count);
|
||||
int release (void);
|
||||
int release (int count);
|
||||
|
||||
auto lock (void) { return acquire (); }
|
||||
auto unlock (void) { return release (); }
|
||||
|
||||
int value (void) const;
|
||||
|
||||
int operator++ (void);
|
||||
int operator-- (void);
|
||||
|
||||
private:
|
||||
std::atomic<int> m_value;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cv;
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user