build; fix compilation errors under win32
win32 builds are still totally unsupported, untested, and functionally broken.
This commit is contained in:
parent
ff5f79a858
commit
b60aaccf6f
@ -12,7 +12,16 @@
|
|||||||
#include "../../view.hpp"
|
#include "../../view.hpp"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WIN32)
|
||||||
|
inline int
|
||||||
|
posix_memalign (void **ptr, std::size_t align, std::size_t size)
|
||||||
|
{
|
||||||
|
*ptr = _aligned_malloc (size, align);
|
||||||
|
return *ptr ? 0 : errno;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cruft::alloc::raw {
|
namespace cruft::alloc::raw {
|
||||||
class malloc {
|
class malloc {
|
||||||
|
@ -9,9 +9,8 @@
|
|||||||
#include "backtrace.hpp"
|
#include "backtrace.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "except.hpp"
|
|
||||||
#include "types.hpp"
|
#include "types.hpp"
|
||||||
#include "win32/error.hpp"
|
#include "win32/except.hpp"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
@ -70,7 +69,7 @@ backtrace::backtrace ()
|
|||||||
if (frame.AddrPC.Offset == frame.AddrReturn.Offset)
|
if (frame.AddrPC.Offset == frame.AddrReturn.Offset)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
m_frames.push_back ((void*)frame.AddrPC.Offset);
|
m_frames.push_back (reinterpret_cast<void*> (frame.AddrPC.Offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +80,7 @@ debug::operator<< (std::ostream &os, const debug::backtrace &b)
|
|||||||
{
|
{
|
||||||
const auto self = GetCurrentProcess ();
|
const auto self = GetCurrentProcess ();
|
||||||
|
|
||||||
struct [[gnu::packed]] {
|
struct {
|
||||||
IMAGEHLP_SYMBOL64 info;
|
IMAGEHLP_SYMBOL64 info;
|
||||||
char name[255];
|
char name[255];
|
||||||
} sym;
|
} sym;
|
||||||
@ -93,7 +92,7 @@ debug::operator<< (std::ostream &os, const debug::backtrace &b)
|
|||||||
// Find the symbol name
|
// Find the symbol name
|
||||||
sym.info.Name[0] = '\0';
|
sym.info.Name[0] = '\0';
|
||||||
memset (sym.name, 0, sizeof (sym.name));
|
memset (sym.name, 0, sizeof (sym.name));
|
||||||
SymGetSymFromAddr64 (self, (uintptr_t)frame, nullptr, &sym.info);
|
SymGetSymFromAddr64 (self, reinterpret_cast<uintptr_t> (frame), nullptr, &sym.info);
|
||||||
*std::rbegin (sym.name) = '\0';
|
*std::rbegin (sym.name) = '\0';
|
||||||
|
|
||||||
os << self << '\t' << frame << '\t' << sym.info.Name << '\n';
|
os << self << '\t' << frame << '\t' << sym.info.Name << '\n';
|
||||||
|
@ -68,6 +68,7 @@ warn (const char *msg)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
#if !defined(PLATFORM_WIN32)
|
||||||
void
|
void
|
||||||
cruft::debug::init [[gnu::constructor]] (void)
|
cruft::debug::init [[gnu::constructor]] (void)
|
||||||
{
|
{
|
||||||
@ -94,6 +95,7 @@ debug_wait [[gnu::constructor]] (void)
|
|||||||
await_debugger ();
|
await_debugger ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -8,10 +8,8 @@
|
|||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
|
|
||||||
#include "except.hpp"
|
|
||||||
#include "log.hpp"
|
#include "log.hpp"
|
||||||
#include "except.hpp"
|
#include "win32/except.hpp"
|
||||||
#include "win32/error.hpp"
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -142,16 +142,20 @@ namespace cruft::encode {
|
|||||||
// convert whole groups of symbols while we have enough bytes remaining
|
// convert whole groups of symbols while we have enough bytes remaining
|
||||||
auto cursor = std::cbegin (src);
|
auto cursor = std::cbegin (src);
|
||||||
for (size_t i = 0, last = std::size (src) / group_bytes; i != last; ++i) {
|
for (size_t i = 0, last = std::size (src) / group_bytes; i != last; ++i) {
|
||||||
auto tally = std::accumulate (
|
auto const tally = std::accumulate (
|
||||||
cursor, cursor + group_bytes,
|
cursor,
|
||||||
uint_fast32_t {0},
|
cursor + group_bytes,
|
||||||
|
uint64_t {0},
|
||||||
[] (auto a, auto b) { return a << 8 | b; }
|
[] (auto a, auto b) { return a << 8 | b; }
|
||||||
);
|
);
|
||||||
|
|
||||||
cursor += group_bytes;
|
cursor += group_bytes;
|
||||||
|
|
||||||
for (int j = group_symbols - 1; j >= 0; --j)
|
for (int j = group_symbols - 1; j >= 0; --j) {
|
||||||
*dst++ = enc_v<Size>[tally >> (j * symbol_bits) & mask];
|
auto const shift = j * symbol_bits;
|
||||||
|
auto const upper = tally >> shift;
|
||||||
|
*dst++ = enc_v<Size>[upper & mask];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't need to pad the output so we can early exit
|
// we don't need to pad the output so we can early exit
|
||||||
@ -163,7 +167,7 @@ namespace cruft::encode {
|
|||||||
auto tally = std::accumulate (
|
auto tally = std::accumulate (
|
||||||
cursor,
|
cursor,
|
||||||
std::cend (src),
|
std::cend (src),
|
||||||
uint_fast32_t {0},
|
uint64_t {0},
|
||||||
[] (auto a, auto b) { return a << 8 | b; }
|
[] (auto a, auto b) { return a << 8 | b; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#include "exe.hpp"
|
#include "exe.hpp"
|
||||||
|
|
||||||
#include "except.hpp"
|
#include "win32/except.hpp"
|
||||||
#incldue "win32/except.hpp"
|
|
||||||
|
|
||||||
#include <experimental/filesystem>
|
#include <experimental/filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -23,7 +22,7 @@ cruft::image_path (void)
|
|||||||
std::vector<char> resolved (256);
|
std::vector<char> resolved (256);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
const auto written = GetModuleFileName (nullptr, resolved.data (), resolved.size ());
|
const auto written = GetModuleFileName (nullptr, resolved.data (), static_cast<DWORD> (resolved.size ()));
|
||||||
if (written == 0)
|
if (written == 0)
|
||||||
win32::error::throw_code ();
|
win32::error::throw_code ();
|
||||||
|
|
||||||
|
4
io.cpp
4
io.cpp
@ -43,7 +43,7 @@ cruft::slurp (const std::experimental::filesystem::path &path)
|
|||||||
std::vector<T> buffer (size);
|
std::vector<T> buffer (size);
|
||||||
|
|
||||||
CHECK_GE (size, 0);
|
CHECK_GE (size, 0);
|
||||||
size_t remaining = cruft::cast::sign<size_t> (size);
|
unsigned remaining = cruft::cast::lossless<unsigned> (size);
|
||||||
T *cursor = buffer.data ();
|
T *cursor = buffer.data ();
|
||||||
|
|
||||||
while (remaining) {
|
while (remaining) {
|
||||||
@ -165,7 +165,7 @@ indenter::~indenter ()
|
|||||||
scoped_cwd::scoped_cwd ()
|
scoped_cwd::scoped_cwd ()
|
||||||
{
|
{
|
||||||
m_original.resize (16);
|
m_original.resize (16);
|
||||||
while (getcwd (&m_original[0], m_original.size ()) == nullptr && errno == ERANGE)
|
while (getcwd (&m_original[0], cruft::cast::lossless<int> (m_original.size ())) == nullptr && errno == ERANGE)
|
||||||
m_original.resize (m_original.size () * 2);
|
m_original.resize (m_original.size () * 2);
|
||||||
posix::error::try_code ();
|
posix::error::try_code ();
|
||||||
}
|
}
|
||||||
|
11
io_win32.cpp
11
io_win32.cpp
@ -9,8 +9,7 @@
|
|||||||
#include "io_win32.hpp"
|
#include "io_win32.hpp"
|
||||||
|
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "except.hpp"
|
#include "win32/except.hpp"
|
||||||
#include "win32/error.hpp"
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
@ -71,7 +70,7 @@ mapped_file::mapped_file (::cruft::win32::handle &&src,
|
|||||||
// requires a check for empty files before we perform the mapping to
|
// requires a check for empty files before we perform the mapping to
|
||||||
// detect errors it throws in that specific situation.
|
// detect errors it throws in that specific situation.
|
||||||
DWORD hi_size, lo_size = GetFileSize (m_file, &hi_size);
|
DWORD hi_size, lo_size = GetFileSize (m_file, &hi_size);
|
||||||
m_size = (uint64_t)hi_size << 32 | lo_size;
|
m_size = static_cast<uint64_t> (hi_size) << 32 | lo_size;
|
||||||
|
|
||||||
m_mapping.reset (
|
m_mapping.reset (
|
||||||
CreateFileMapping (
|
CreateFileMapping (
|
||||||
@ -87,11 +86,11 @@ mapped_file::mapped_file (::cruft::win32::handle &&src,
|
|||||||
// hell. Try not to collapse, but instead bail with a null mapping and
|
// hell. Try not to collapse, but instead bail with a null mapping and
|
||||||
// pray the user doesn't do something stupid with the result.
|
// pray the user doesn't do something stupid with the result.
|
||||||
if (!m_mapping) {
|
if (!m_mapping) {
|
||||||
auto err = win32::error::last_code ();
|
auto err = ::cruft::win32::error::last_code ();
|
||||||
if (err == ERROR_FILE_INVALID && m_size == 0)
|
if (err == ERROR_FILE_INVALID && m_size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
win32::error::throw_code (err);
|
::cruft::win32::error::throw_code (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto view = MapViewOfFile (
|
auto view = MapViewOfFile (
|
||||||
@ -102,7 +101,7 @@ mapped_file::mapped_file (::cruft::win32::handle &&src,
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!view)
|
if (!view)
|
||||||
win32::error::throw_code ();
|
::cruft::win32::error::throw_code ();
|
||||||
|
|
||||||
m_data.reset (
|
m_data.reset (
|
||||||
static_cast<unsigned char*> (view)
|
static_cast<unsigned char*> (view)
|
||||||
|
18
io_win32.hpp
18
io_win32.hpp
@ -3,12 +3,14 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*
|
*
|
||||||
* Copyright 2014-2016 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2014-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __UTIL_IO_WIN32_HPP
|
#pragma once
|
||||||
#define __UTIL_IO_WIN32_HPP
|
|
||||||
|
|
||||||
|
#include "std.hpp"
|
||||||
|
|
||||||
|
#include "pointer.hpp"
|
||||||
#include "io.hpp"
|
#include "io.hpp"
|
||||||
#include "win32/handle.hpp"
|
#include "win32/handle.hpp"
|
||||||
#include "view.hpp"
|
#include "view.hpp"
|
||||||
@ -46,6 +48,14 @@ namespace cruft {
|
|||||||
namespace detail::win32 {
|
namespace detail::win32 {
|
||||||
class mapped_file {
|
class mapped_file {
|
||||||
public:
|
public:
|
||||||
|
using value_type = u08;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = const value_type&;
|
||||||
|
using iterator = value_type*;
|
||||||
|
using const_iterator = const value_type*;
|
||||||
|
using difference_type = std::iterator_traits<iterator>::difference_type;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
|
||||||
mapped_file (::cruft::win32::handle &&,
|
mapped_file (::cruft::win32::handle &&,
|
||||||
int fflags = O_RDONLY,
|
int fflags = O_RDONLY,
|
||||||
int mflags = PROT_READ);
|
int mflags = PROT_READ);
|
||||||
@ -105,5 +115,3 @@ namespace cruft {
|
|||||||
|
|
||||||
typedef detail::win32::mapped_file mapped_file;
|
typedef detail::win32::mapped_file mapped_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -127,7 +127,7 @@ queue::reap ()
|
|||||||
// pop and notify as many doomed tasks as we can
|
// pop and notify as many doomed tasks as we can
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (task *item; m_tasks.finishing.pop (item); ++count) {
|
for (task *item; m_tasks.finishing.pop (item); ++count) {
|
||||||
item->done.notify ();
|
item->done.notify_all ();
|
||||||
m_tasks.notified.push_back (item);
|
m_tasks.notified.push_back (item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ queue::reap ()
|
|||||||
for (auto &i: m_tasks.notified)
|
for (auto &i: m_tasks.notified)
|
||||||
m_tasks.store.destroy (i);
|
m_tasks.store.destroy (i);
|
||||||
for (auto &i: doomed)
|
for (auto &i: doomed)
|
||||||
i->done.notify ();
|
i->done.notify_all ();
|
||||||
for (auto &i: doomed)
|
for (auto &i: doomed)
|
||||||
m_tasks.store.destroy (i);
|
m_tasks.store.destroy (i);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ namespace cruft::job {
|
|||||||
|
|
||||||
~task ()
|
~task ()
|
||||||
{
|
{
|
||||||
done.notify ();
|
done.notify_all ();
|
||||||
references.acquire ();
|
references.acquire ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ using cruft::detail::win32::library;
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
library::library (const std::experimental::filesystem::path &path):
|
library::library (const std::experimental::filesystem::path &path):
|
||||||
m_handle (LoadLibraryA (path.c_str ()))
|
m_handle (LoadLibraryA (path.u8string ().c_str ()))
|
||||||
{
|
{
|
||||||
if (!m_handle)
|
if (!m_handle)
|
||||||
win32::error::throw_code ();
|
::cruft::win32::error::throw_code ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
2
pool.hpp
2
pool.hpp
@ -14,6 +14,8 @@
|
|||||||
#include "cast.hpp"
|
#include "cast.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ using cruft::posix::dir;
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
dir::dir (const std::experimental::filesystem::path &p):
|
dir::dir (const std::experimental::filesystem::path &p):
|
||||||
m_handle (::opendir (p.c_str ()))
|
m_handle (::opendir (p.u8string ().c_str ()))
|
||||||
{
|
{
|
||||||
if (!m_handle)
|
if (!m_handle)
|
||||||
error::throw_code ();
|
error::throw_code ();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "except.hpp"
|
#include "except.hpp"
|
||||||
|
|
||||||
|
#include "../platform.hpp"
|
||||||
#include "../debug.hpp"
|
#include "../debug.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -103,7 +104,11 @@ error::what (void) const noexcept
|
|||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
using cruft::posix::eai;
|
using cruft::posix::eai;
|
||||||
|
|
||||||
|
#if !defined(PLATFORM_WIN32)
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#else
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "fd.hpp"
|
#include "fd.hpp"
|
||||||
|
|
||||||
#include "except.hpp"
|
#include "except.hpp"
|
||||||
|
#include "cast.hpp"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -25,7 +26,7 @@ fd::fd (const std::experimental::filesystem::path &path, int flags):
|
|||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
fd::fd (const std::experimental::filesystem::path &path, int flags, mode_t mode):
|
fd::fd (const std::experimental::filesystem::path &path, int flags, mode_t mode):
|
||||||
m_fd (error::try_value (::open (path.c_str (), flags, mode)))
|
m_fd (error::try_value (::open (path.u8string ().c_str (), flags, mode)))
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
@ -141,10 +142,10 @@ fd::release (void)
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
ssize_t
|
ssize_t
|
||||||
fd::read (void *buffer, size_t count)
|
fd::read (void *buffer, std::size_t count)
|
||||||
{
|
{
|
||||||
return error::try_value (
|
return error::try_value (
|
||||||
::read (m_fd, buffer, count)
|
::read (m_fd, buffer, cruft::cast::narrow<unsigned> (count))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +155,7 @@ ssize_t
|
|||||||
fd::write (const void *buffer, size_t count)
|
fd::write (const void *buffer, size_t count)
|
||||||
{
|
{
|
||||||
return error::try_value (
|
return error::try_value (
|
||||||
::write (m_fd, buffer, count)
|
::write (m_fd, buffer, cruft::cast::narrow<unsigned> (count))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,13 +8,19 @@
|
|||||||
|
|
||||||
#include "socket.hpp"
|
#include "socket.hpp"
|
||||||
|
|
||||||
|
#include "platform.hpp"
|
||||||
#include "except.hpp"
|
#include "except.hpp"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#if !defined(PLATFORM_WIN32)
|
||||||
#include <sys/socket.h>
|
#include <sys/types.h>
|
||||||
#include <netdb.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netdb.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#else
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using cruft::posix::socket;
|
using cruft::posix::socket;
|
||||||
|
|
||||||
|
@ -13,8 +13,12 @@
|
|||||||
|
|
||||||
#include "except.hpp"
|
#include "except.hpp"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#if !defined(PLATFORM_WIN32)
|
||||||
#include <sys/socket.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#else
|
||||||
|
#include <winsock2.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct sockaddr_in;
|
struct sockaddr_in;
|
||||||
|
3
tap.hpp
3
tap.hpp
@ -41,7 +41,8 @@ namespace cruft::TAP {
|
|||||||
{
|
{
|
||||||
m_output << (test ? "ok " : "not ok ") << ++m_size
|
m_output << (test ? "ok " : "not ok ") << ++m_size
|
||||||
<< " - "
|
<< " - "
|
||||||
<< format::printf (fmt) (std::forward<Args> (args)...) << '\n';
|
<< format::printf (fmt) (std::forward<Args> (args)...)
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
if (!test)
|
if (!test)
|
||||||
m_status = EXIT_FAILURE;
|
m_status = EXIT_FAILURE;
|
||||||
|
4
term.cpp
4
term.cpp
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
using cruft::term::csi::graphics;
|
using cruft::term::csi::graphics;
|
||||||
|
|
||||||
static const std::experimental::filesystem::path DEFAULT_SEARCH_DIR = "/usr/share/terminfo";
|
|
||||||
|
|
||||||
const graphics graphics::RESET (0);
|
const graphics graphics::RESET (0);
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +46,8 @@ static
|
|||||||
std::experimental::filesystem::path
|
std::experimental::filesystem::path
|
||||||
find_terminfo_path [[gnu::unused]] (const std::string &key)
|
find_terminfo_path [[gnu::unused]] (const std::string &key)
|
||||||
{
|
{
|
||||||
|
static const std::experimental::filesystem::path DEFAULT_SEARCH_DIR = "/usr/share/terminfo";
|
||||||
|
|
||||||
// check if the path is explicitly listed. must not fall through.
|
// check if the path is explicitly listed. must not fall through.
|
||||||
if (const char *dir = getenv ("TERMINFO")) {
|
if (const char *dir = getenv ("TERMINFO")) {
|
||||||
return find_terminfo_path (dir, key);
|
return find_terminfo_path (dir, key);
|
||||||
|
@ -82,7 +82,9 @@ test_size (cruft::TAP::logger &tap)
|
|||||||
fragment
|
fragment
|
||||||
);
|
);
|
||||||
|
|
||||||
tap.expect_eq (encoded, output_v<Size>[i],
|
tap.expect_eq (
|
||||||
|
encoded,
|
||||||
|
output_v<Size>[i],
|
||||||
"%! character base%! encode; '%!' is '%!'", i, Size, encoded, output_v<Size>[i]
|
"%! character base%! encode; '%!' is '%!'", i, Size, encoded, output_v<Size>[i]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include "tap.hpp"
|
#include "tap.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <inttypes.h>
|
#include <cinttypes>
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -81,7 +81,7 @@ main ()
|
|||||||
producers.emplace_back (produce, std::ref (src), i * chunk_size);
|
producers.emplace_back (produce, std::ref (src), i * chunk_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
start.notify ();
|
start.notify_all ();
|
||||||
|
|
||||||
// wait for everyone to complete
|
// wait for everyone to complete
|
||||||
for (auto &t: producers)
|
for (auto &t: producers)
|
||||||
|
@ -30,7 +30,7 @@ main ()
|
|||||||
|
|
||||||
tap.expect_eq (val, 0, "waiting actually blocks");
|
tap.expect_eq (val, 0, "waiting actually blocks");
|
||||||
|
|
||||||
a.notify ();
|
a.notify_all ();
|
||||||
t.join ();
|
t.join ();
|
||||||
|
|
||||||
tap.expect_eq (val, 1, "notification released the lock");
|
tap.expect_eq (val, 1, "notification released the lock");
|
||||||
|
@ -20,7 +20,7 @@ main ()
|
|||||||
std::this_thread::sleep_for (std::chrono::milliseconds (100));
|
std::this_thread::sleep_for (std::chrono::milliseconds (100));
|
||||||
|
|
||||||
tap.expect_eq (value, 0, "value hasn't been set during wait");
|
tap.expect_eq (value, 0, "value hasn't been set during wait");
|
||||||
tap.expect_eq (f.notify (), 1, "notify reports one thread woke");
|
f.notify_all ();
|
||||||
|
|
||||||
t1.join ();
|
t1.join ();
|
||||||
tap.expect_eq (value, 1, "value has been changed after wait");
|
tap.expect_eq (value, 1, "value has been changed after wait");
|
||||||
@ -52,7 +52,7 @@ main ()
|
|||||||
for (auto &row: flags) {
|
for (auto &row: flags) {
|
||||||
for (int i = 0; i < parallelism; ++i) {
|
for (int i = 0; i < parallelism; ++i) {
|
||||||
if (i == idx)
|
if (i == idx)
|
||||||
row[i].notify ();
|
row[i].notify_all ();
|
||||||
else
|
else
|
||||||
row[i].wait ();
|
row[i].wait ();
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ main ()
|
|||||||
for (unsigned i = 0; i < std::thread::hardware_concurrency (); ++i)
|
for (unsigned i = 0; i < std::thread::hardware_concurrency (); ++i)
|
||||||
contestants.emplace_back (fight, std::ref (start_flag), std::ref (l), iterations);
|
contestants.emplace_back (fight, std::ref (start_flag), std::ref (l), iterations);
|
||||||
|
|
||||||
start_flag.notify ();
|
start_flag.notify_all ();
|
||||||
|
|
||||||
for (auto &t: contestants)
|
for (auto &t: contestants)
|
||||||
t.join ();
|
t.join ();
|
||||||
|
@ -67,7 +67,7 @@ main ()
|
|||||||
std::thread b (fight, std::ref (start_flag), std::ref (l), iterations, std::ref (b_finish));
|
std::thread b (fight, std::ref (start_flag), std::ref (l), iterations, std::ref (b_finish));
|
||||||
|
|
||||||
auto start = std::chrono::high_resolution_clock::now ();
|
auto start = std::chrono::high_resolution_clock::now ();
|
||||||
start_flag.notify ();
|
start_flag.notify_all ();
|
||||||
|
|
||||||
a.join ();
|
a.join ();
|
||||||
b.join ();
|
b.join ();
|
||||||
|
@ -18,10 +18,14 @@ namespace cruft::thread {
|
|||||||
public:
|
public:
|
||||||
flag ();
|
flag ();
|
||||||
|
|
||||||
|
/// blocks indefinitely until the flag has been set.
|
||||||
void wait (void);
|
void wait (void);
|
||||||
|
|
||||||
int notify (void);
|
/// wake all the threads waiting on the flag
|
||||||
int notify (int);
|
void notify (void);
|
||||||
|
|
||||||
|
/// wake at most 'n' threads waiting on the flag
|
||||||
|
void notify (int);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic<int> value;
|
std::atomic<int> value;
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
#include "flag.hpp"
|
||||||
|
|
||||||
|
#include "../win32/except.hpp"
|
||||||
|
|
||||||
|
#include <synchapi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
using cruft::thread::flag;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
flag::flag ():
|
||||||
|
fired (false)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
flag::wait (void)
|
||||||
|
{
|
||||||
|
while (!fired) {
|
||||||
|
std::unique_lock lk (m_mutex);
|
||||||
|
m_condition.wait (lk, [this] () { return !!fired; });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
void
|
||||||
|
flag::notify_one (void)
|
||||||
|
{
|
||||||
|
std::unique_lock lk (m_mutex);
|
||||||
|
fired = true;
|
||||||
|
m_condition.notify_one ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
flag::notify_all (void)
|
||||||
|
{
|
||||||
|
std::unique_lock lk (m_mutex);
|
||||||
|
fired = true;
|
||||||
|
m_condition.notify_all ();
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "semaphore_win32.hpp"
|
||||||
|
|
||||||
|
#include "../debug.hpp"
|
||||||
|
|
||||||
|
using cruft::thread::semaphore;
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
semaphore::semaphore ():
|
||||||
|
semaphore (1)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
semaphore::semaphore (int initial):
|
||||||
|
m_value (initial)
|
||||||
|
{ ; }
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
int
|
||||||
|
semaphore::acquire (int count)
|
||||||
|
{
|
||||||
|
CHECK_GE (count, 0);
|
||||||
|
|
||||||
|
do {
|
||||||
|
int now = m_value;
|
||||||
|
|
||||||
|
// if our value is positive then attempt to decrement it and return,
|
||||||
|
// else retry because someone interfered with us.
|
||||||
|
if (now - count >= 0) {
|
||||||
|
if (m_value.compare_exchange_weak (now, now - count))
|
||||||
|
return now - count;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the count doesn't appear to allow us to acquire. sleep until
|
||||||
|
// there's been a modification and retry.
|
||||||
|
std::unique_lock lk (m_mutex);
|
||||||
|
m_cv.wait (lk, [&, this] () { return m_value - count >= 0; });
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
semaphore::acquire (void)
|
||||||
|
{
|
||||||
|
return acquire (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
semaphore::release (int count)
|
||||||
|
{
|
||||||
|
auto res = m_value += count;
|
||||||
|
if (res > 0)
|
||||||
|
m_cv.notify_one();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
semaphore::release (void)
|
||||||
|
{
|
||||||
|
return release (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
int
|
||||||
|
semaphore::value (void) const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
semaphore::operator++ (void)
|
||||||
|
{
|
||||||
|
return release ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
semaphore::operator-- (void)
|
||||||
|
{
|
||||||
|
// we don't need to wake anyone because this will only serve to delay
|
||||||
|
// their wakeup.
|
||||||
|
return --m_value;
|
||||||
|
}
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
#include "time.hpp"
|
#include "time.hpp"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <thread>
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
void
|
void
|
||||||
cruft::sleep (uint64_t ns)
|
cruft::sleep (uint64_t ns)
|
||||||
{
|
{
|
||||||
Sleep (ns / 1'000'000UL);
|
std::this_thread::sleep_for (std::chrono::nanoseconds (ns));
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ error::error (DWORD _code):
|
|||||||
runtime_error (code_string (_code)),
|
runtime_error (code_string (_code)),
|
||||||
m_code (_code)
|
m_code (_code)
|
||||||
{
|
{
|
||||||
CHECK_NEQ (m_code, (DWORD)ERROR_SUCCESS);
|
CHECK_NEQ (m_code, static_cast<DWORD> (ERROR_SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ error::throw_code (void)
|
|||||||
void
|
void
|
||||||
error::throw_code (DWORD code)
|
error::throw_code (DWORD code)
|
||||||
{
|
{
|
||||||
CHECK_NEQ (code, (DWORD)ERROR_SUCCESS);
|
CHECK_NEQ (code, static_cast<DWORD> (ERROR_SUCCESS));
|
||||||
throw error (code);
|
throw error (code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "handle.hpp"
|
#include "handle.hpp"
|
||||||
|
|
||||||
#include "../except.hpp"
|
#include "except.hpp"
|
||||||
|
|
||||||
using cruft::win32::handle;
|
using cruft::win32::handle;
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
#include "registry.hpp"
|
#include "registry.hpp"
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "../cast.hpp"
|
||||||
#include "../debug.hpp"
|
#include "../debug.hpp"
|
||||||
#include "../except.hpp"
|
#include "except.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -64,7 +64,7 @@ key::data (const char *name) const
|
|||||||
DWORD type;
|
DWORD type;
|
||||||
DWORD size = sizeof (value);
|
DWORD size = sizeof (value);
|
||||||
|
|
||||||
auto err = RegGetValue (m_handle, name, &value, restrict_to_id<T> (), nullptr, &value, &size);
|
auto err = RegGetValue (m_handle, name, &value, restrict_to_id<T> (), &type, &value, &size);
|
||||||
win32::error::try_code (err);
|
win32::error::try_code (err);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@ -79,7 +79,7 @@ key::values (void) const
|
|||||||
|
|
||||||
for (DWORD i = 0; ; ++i) {
|
for (DWORD i = 0; ; ++i) {
|
||||||
std::string name (255, '\0');
|
std::string name (255, '\0');
|
||||||
DWORD size = name.size ();
|
DWORD size = cruft::cast::narrow<DWORD> (name.size ());
|
||||||
|
|
||||||
auto err = RegEnumValue (m_handle, i, &name[0], &size, nullptr, nullptr, nullptr, nullptr);
|
auto err = RegEnumValue (m_handle, i, &name[0], &size, nullptr, nullptr, nullptr, nullptr);
|
||||||
if (ERROR_NO_MORE_ITEMS == err)
|
if (ERROR_NO_MORE_ITEMS == err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user