build; fix compilation errors under win32

win32 builds are still totally unsupported, untested, and functionally
broken.
This commit is contained in:
Danny Robson 2018-08-13 14:51:33 +10:00
parent ff5f79a858
commit b60aaccf6f
34 changed files with 259 additions and 69 deletions

View File

@ -12,7 +12,16 @@
#include "../../view.hpp"
#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 {
class malloc {

View File

@ -9,9 +9,8 @@
#include "backtrace.hpp"
#include "debug.hpp"
#include "except.hpp"
#include "types.hpp"
#include "win32/error.hpp"
#include "win32/except.hpp"
#include <windows.h>
#include <dbghelp.h>
@ -70,7 +69,7 @@ backtrace::backtrace ()
if (frame.AddrPC.Offset == frame.AddrReturn.Offset)
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 ();
struct [[gnu::packed]] {
struct {
IMAGEHLP_SYMBOL64 info;
char name[255];
} sym;
@ -93,7 +92,7 @@ debug::operator<< (std::ostream &os, const debug::backtrace &b)
// Find the symbol name
sym.info.Name[0] = '\0';
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';
os << self << '\t' << frame << '\t' << sym.info.Name << '\n';

View File

@ -68,6 +68,7 @@ warn (const char *msg)
////////////////////////////////////////////////////////////////////////////////
#if !defined(PLATFORM_WIN32)
void
cruft::debug::init [[gnu::constructor]] (void)
{
@ -94,6 +95,7 @@ debug_wait [[gnu::constructor]] (void)
await_debugger ();
}
}
#endif
///////////////////////////////////////////////////////////////////////////////

View File

@ -8,10 +8,8 @@
#include "debug.hpp"
#include "except.hpp"
#include "log.hpp"
#include "except.hpp"
#include "win32/error.hpp"
#include "win32/except.hpp"
#include <windows.h>
#include <iostream>

View File

@ -142,16 +142,20 @@ namespace cruft::encode {
// convert whole groups of symbols while we have enough bytes remaining
auto cursor = std::cbegin (src);
for (size_t i = 0, last = std::size (src) / group_bytes; i != last; ++i) {
auto tally = std::accumulate (
cursor, cursor + group_bytes,
uint_fast32_t {0},
auto const tally = std::accumulate (
cursor,
cursor + group_bytes,
uint64_t {0},
[] (auto a, auto b) { return a << 8 | b; }
);
cursor += group_bytes;
for (int j = group_symbols - 1; j >= 0; --j)
*dst++ = enc_v<Size>[tally >> (j * symbol_bits) & mask];
for (int j = group_symbols - 1; j >= 0; --j) {
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
@ -163,7 +167,7 @@ namespace cruft::encode {
auto tally = std::accumulate (
cursor,
std::cend (src),
uint_fast32_t {0},
uint64_t {0},
[] (auto a, auto b) { return a << 8 | b; }
);

View File

@ -8,8 +8,7 @@
#include "exe.hpp"
#include "except.hpp"
#incldue "win32/except.hpp"
#include "win32/except.hpp"
#include <experimental/filesystem>
#include <vector>
@ -23,7 +22,7 @@ cruft::image_path (void)
std::vector<char> resolved (256);
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)
win32::error::throw_code ();

4
io.cpp
View File

@ -43,7 +43,7 @@ cruft::slurp (const std::experimental::filesystem::path &path)
std::vector<T> buffer (size);
CHECK_GE (size, 0);
size_t remaining = cruft::cast::sign<size_t> (size);
unsigned remaining = cruft::cast::lossless<unsigned> (size);
T *cursor = buffer.data ();
while (remaining) {
@ -165,7 +165,7 @@ indenter::~indenter ()
scoped_cwd::scoped_cwd ()
{
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);
posix::error::try_code ();
}

View File

@ -9,8 +9,7 @@
#include "io_win32.hpp"
#include "debug.hpp"
#include "except.hpp"
#include "win32/error.hpp"
#include "win32/except.hpp"
#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
// detect errors it throws in that specific situation.
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 (
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
// pray the user doesn't do something stupid with the result.
if (!m_mapping) {
auto err = win32::error::last_code ();
auto err = ::cruft::win32::error::last_code ();
if (err == ERROR_FILE_INVALID && m_size == 0)
return;
win32::error::throw_code (err);
::cruft::win32::error::throw_code (err);
}
auto view = MapViewOfFile (
@ -102,7 +101,7 @@ mapped_file::mapped_file (::cruft::win32::handle &&src,
);
if (!view)
win32::error::throw_code ();
::cruft::win32::error::throw_code ();
m_data.reset (
static_cast<unsigned char*> (view)

View File

@ -3,12 +3,14 @@
* 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 2014-2016 Danny Robson <danny@nerdcruft.net>
* Copyright 2014-2018 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_IO_WIN32_HPP
#define __UTIL_IO_WIN32_HPP
#pragma once
#include "std.hpp"
#include "pointer.hpp"
#include "io.hpp"
#include "win32/handle.hpp"
#include "view.hpp"
@ -46,6 +48,14 @@ namespace cruft {
namespace detail::win32 {
class mapped_file {
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 &&,
int fflags = O_RDONLY,
int mflags = PROT_READ);
@ -105,5 +115,3 @@ namespace cruft {
typedef detail::win32::mapped_file mapped_file;
}
#endif

View File

@ -127,7 +127,7 @@ queue::reap ()
// pop and notify as many doomed tasks as we can
int count = 0;
for (task *item; m_tasks.finishing.pop (item); ++count) {
item->done.notify ();
item->done.notify_all ();
m_tasks.notified.push_back (item);
}
@ -159,7 +159,7 @@ queue::reap ()
for (auto &i: m_tasks.notified)
m_tasks.store.destroy (i);
for (auto &i: doomed)
i->done.notify ();
i->done.notify_all ();
for (auto &i: doomed)
m_tasks.store.destroy (i);
}

View File

@ -133,7 +133,7 @@ namespace cruft::job {
~task ()
{
done.notify ();
done.notify_all ();
references.acquire ();
}

View File

@ -15,10 +15,10 @@ using cruft::detail::win32::library;
///////////////////////////////////////////////////////////////////////////////
library::library (const std::experimental::filesystem::path &path):
m_handle (LoadLibraryA (path.c_str ()))
m_handle (LoadLibraryA (path.u8string ().c_str ()))
{
if (!m_handle)
win32::error::throw_code ();
::cruft::win32::error::throw_code ();
}

View File

@ -14,6 +14,8 @@
#include "cast.hpp"
#include <atomic>
#include <new>
#include <cstdlib>
#include <cstdint>

View File

@ -15,7 +15,7 @@ using cruft::posix::dir;
///////////////////////////////////////////////////////////////////////////////
dir::dir (const std::experimental::filesystem::path &p):
m_handle (::opendir (p.c_str ()))
m_handle (::opendir (p.u8string ().c_str ()))
{
if (!m_handle)
error::throw_code ();

View File

@ -9,6 +9,7 @@
#include "except.hpp"
#include "../platform.hpp"
#include "../debug.hpp"
#include <cstring>
@ -103,7 +104,11 @@ error::what (void) const noexcept
///////////////////////////////////////////////////////////////////////////////
using cruft::posix::eai;
#if !defined(PLATFORM_WIN32)
#include <netdb.h>
#else
#include <ws2tcpip.h>
#endif
//-----------------------------------------------------------------------------

View File

@ -9,6 +9,7 @@
#include "fd.hpp"
#include "except.hpp"
#include "cast.hpp"
#include <sys/stat.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):
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
fd::read (void *buffer, size_t count)
fd::read (void *buffer, std::size_t count)
{
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)
{
return error::try_value (
::write (m_fd, buffer, count)
::write (m_fd, buffer, cruft::cast::narrow<unsigned> (count))
);
}

View File

@ -8,13 +8,19 @@
#include "socket.hpp"
#include "platform.hpp"
#include "except.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#if !defined(PLATFORM_WIN32)
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#else
#include <ws2tcpip.h>
#include <winsock2.h>
#endif
using cruft::posix::socket;

View File

@ -13,8 +13,12 @@
#include "except.hpp"
#include <sys/types.h>
#include <sys/socket.h>
#if !defined(PLATFORM_WIN32)
#include <sys/types.h>
#include <sys/socket.h>
#else
#include <winsock2.h>
#endif
struct sockaddr_in;

View File

@ -41,7 +41,8 @@ namespace cruft::TAP {
{
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)
m_status = EXIT_FAILURE;

View File

@ -16,8 +16,6 @@
using cruft::term::csi::graphics;
static const std::experimental::filesystem::path DEFAULT_SEARCH_DIR = "/usr/share/terminfo";
const graphics graphics::RESET (0);
@ -48,6 +46,8 @@ static
std::experimental::filesystem::path
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.
if (const char *dir = getenv ("TERMINFO")) {
return find_terminfo_path (dir, key);

View File

@ -82,7 +82,9 @@ test_size (cruft::TAP::logger &tap)
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]
);

View File

@ -2,7 +2,7 @@
#include "tap.hpp"
#include <cstring>
#include <inttypes.h>
#include <cinttypes>
///////////////////////////////////////////////////////////////////////////////

View File

@ -81,7 +81,7 @@ main ()
producers.emplace_back (produce, std::ref (src), i * chunk_size);
}
start.notify ();
start.notify_all ();
// wait for everyone to complete
for (auto &t: producers)

View File

@ -30,7 +30,7 @@ main ()
tap.expect_eq (val, 0, "waiting actually blocks");
a.notify ();
a.notify_all ();
t.join ();
tap.expect_eq (val, 1, "notification released the lock");

View File

@ -20,7 +20,7 @@ main ()
std::this_thread::sleep_for (std::chrono::milliseconds (100));
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 ();
tap.expect_eq (value, 1, "value has been changed after wait");
@ -52,7 +52,7 @@ main ()
for (auto &row: flags) {
for (int i = 0; i < parallelism; ++i) {
if (i == idx)
row[i].notify ();
row[i].notify_all ();
else
row[i].wait ();
}

View File

@ -47,7 +47,7 @@ main ()
for (unsigned i = 0; i < std::thread::hardware_concurrency (); ++i)
contestants.emplace_back (fight, std::ref (start_flag), std::ref (l), iterations);
start_flag.notify ();
start_flag.notify_all ();
for (auto &t: contestants)
t.join ();

View File

@ -67,7 +67,7 @@ main ()
std::thread b (fight, std::ref (start_flag), std::ref (l), iterations, std::ref (b_finish));
auto start = std::chrono::high_resolution_clock::now ();
start_flag.notify ();
start_flag.notify_all ();
a.join ();
b.join ();

View File

@ -18,10 +18,14 @@ namespace cruft::thread {
public:
flag ();
/// blocks indefinitely until the flag has been set.
void wait (void);
int notify (void);
int notify (int);
/// wake all the threads waiting on the flag
void notify (void);
/// wake at most 'n' threads waiting on the flag
void notify (int);
private:
std::atomic<int> value;

View File

@ -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 ();
}

View File

@ -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;
}

View File

@ -8,11 +8,11 @@
#include "time.hpp"
#include <windows.h>
#include <thread>
///////////////////////////////////////////////////////////////////////////////
void
cruft::sleep (uint64_t ns)
{
Sleep (ns / 1'000'000UL);
std::this_thread::sleep_for (std::chrono::nanoseconds (ns));
}

View File

@ -19,7 +19,7 @@ error::error (DWORD _code):
runtime_error (code_string (_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
error::throw_code (DWORD code)
{
CHECK_NEQ (code, (DWORD)ERROR_SUCCESS);
CHECK_NEQ (code, static_cast<DWORD> (ERROR_SUCCESS));
throw error (code);
}

View File

@ -1,6 +1,6 @@
#include "handle.hpp"
#include "../except.hpp"
#include "except.hpp"
using cruft::win32::handle;

View File

@ -8,9 +8,9 @@
#include "registry.hpp"
#include "error.hpp"
#include "../cast.hpp"
#include "../debug.hpp"
#include "../except.hpp"
#include "except.hpp"
#include <string>
#include <cstdint>
@ -64,7 +64,7 @@ key::data (const char *name) const
DWORD type;
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);
return value;
@ -79,7 +79,7 @@ key::values (void) const
for (DWORD i = 0; ; ++i) {
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);
if (ERROR_NO_MORE_ITEMS == err)