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)
|
list (APPEND UTIL_FILES backtrace_execinfo.cpp)
|
||||||
elseif (HAVE_CAPTURESTACKBACKTRACE)
|
elseif (HAVE_CAPTURESTACKBACKTRACE)
|
||||||
list (APPEND UTIL_FILES backtrace_stackwalk.cpp)
|
list (APPEND UTIL_FILES backtrace_stackwalk.cpp)
|
||||||
|
target_link_libraries(cruft DbgHelp)
|
||||||
else ()
|
else ()
|
||||||
list (APPEND UTIL_FILES backtrace_null.cpp)
|
list (APPEND UTIL_FILES backtrace_null.cpp)
|
||||||
endif ()
|
endif ()
|
||||||
@ -81,8 +82,6 @@ list (
|
|||||||
posix/except.hpp
|
posix/except.hpp
|
||||||
posix/fd.cpp
|
posix/fd.cpp
|
||||||
posix/fd.hpp
|
posix/fd.hpp
|
||||||
posix/socket.cpp
|
|
||||||
posix/socket.hpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -91,13 +90,12 @@ if (LINUX)
|
|||||||
list (APPEND UTIL_FILES
|
list (APPEND UTIL_FILES
|
||||||
thread/event_linux.cpp
|
thread/event_linux.cpp
|
||||||
thread/flag_linux.cpp
|
thread/flag_linux.cpp
|
||||||
thread/semaphore_linux.cpp
|
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
##-----------------------------------------------------------------------------
|
##-----------------------------------------------------------------------------
|
||||||
if (NOT WINDOWS)
|
if (NOT WIN32)
|
||||||
list (
|
list (
|
||||||
APPEND UTIL_FILES
|
APPEND UTIL_FILES
|
||||||
memory/buffer/circular.cpp
|
memory/buffer/circular.cpp
|
||||||
@ -114,13 +112,15 @@ if (NOT WINDOWS)
|
|||||||
posix/fwd.hpp
|
posix/fwd.hpp
|
||||||
posix/map.cpp
|
posix/map.cpp
|
||||||
posix/map.hpp
|
posix/map.hpp
|
||||||
|
posix/socket.cpp
|
||||||
|
posix/socket.hpp
|
||||||
time_posix.cpp
|
time_posix.cpp
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
##-----------------------------------------------------------------------------
|
##-----------------------------------------------------------------------------
|
||||||
if (WINDOWS)
|
if (WIN32)
|
||||||
list (
|
list (
|
||||||
APPEND UTIL_FILES
|
APPEND UTIL_FILES
|
||||||
debug_win32.cpp
|
debug_win32.cpp
|
||||||
@ -128,8 +128,6 @@ if (WINDOWS)
|
|||||||
io_win32.cpp
|
io_win32.cpp
|
||||||
io_win32.hpp
|
io_win32.hpp
|
||||||
thread/event_win32.cpp
|
thread/event_win32.cpp
|
||||||
thread/flag_win32.cpp
|
|
||||||
thread/semaphore_win32.cpp
|
|
||||||
library_win32.cpp
|
library_win32.cpp
|
||||||
library_win32.hpp
|
library_win32.hpp
|
||||||
time_win32.cpp
|
time_win32.cpp
|
||||||
@ -140,6 +138,41 @@ if (WINDOWS)
|
|||||||
win32/registry.cpp
|
win32/registry.cpp
|
||||||
win32/registry.hpp
|
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 ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
@ -364,7 +397,6 @@ list (
|
|||||||
thread/flag.hpp
|
thread/flag.hpp
|
||||||
thread/monitor.cpp
|
thread/monitor.cpp
|
||||||
thread/monitor.hpp
|
thread/monitor.hpp
|
||||||
thread/semaphore.hpp
|
|
||||||
thread/ticketlock.cpp
|
thread/ticketlock.cpp
|
||||||
thread/ticketlock.hpp
|
thread/ticketlock.hpp
|
||||||
thread/spinlock.cpp
|
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)
|
add_library(cruft-util ALIAS cruft)
|
||||||
target_include_directories(cruft PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
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
|
# HACK: -ldl isn't getting discovered correctly so we add it unconditionally
|
||||||
# for the time being.
|
# 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 @@
|
|||||||
/*
|
#include "platform.hpp"
|
||||||
* 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
|
#if defined(PLATFORM_LINUX)
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
#include "event_futex.hpp"
|
||||||
*
|
#else
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
#include "event_std.hpp"
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
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 @@
|
|||||||
/*
|
#include "platform.hpp"
|
||||||
* 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
|
#if defined(PLATFORM_LINUX)
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
#include "flag_futex.hpp"
|
||||||
*
|
#else
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
#include "flag_std.hpp"
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
#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
|
|
||||||
|
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 @@
|
|||||||
/*
|
#include "platform.hpp"
|
||||||
* 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
|
#if defined(PLATFORM_LINUX)
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
#include "semaphore_linux.hpp"
|
||||||
*
|
#else
|
||||||
* Copyright 2018 Danny Robson <danny@nerdcruft.net>
|
#include "semaphore_win32.hpp"
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
#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
|
|
||||||
|
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