Skip to content

Commit

Permalink
Add mutex and shared_mutex headers back
Browse files Browse the repository at this point in the history
  • Loading branch information
salkinium committed Apr 20, 2024
1 parent 300290d commit 4e27ef1
Show file tree
Hide file tree
Showing 6 changed files with 2,205 additions and 0 deletions.
180 changes: 180 additions & 0 deletions include/bits/error_constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Specific definitions for generic platforms -*- C++ -*-

// Copyright (C) 2007-2024 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/error_constants.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{system_error}
*/

#ifndef _GLIBCXX_ERROR_CONSTANTS
#define _GLIBCXX_ERROR_CONSTANTS 1

#include <bits/c++config.h>
#include <cerrno>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

enum class errc
{
address_family_not_supported = EAFNOSUPPORT,
address_in_use = EADDRINUSE,
address_not_available = EADDRNOTAVAIL,
already_connected = EISCONN,
argument_list_too_long = E2BIG,
argument_out_of_domain = EDOM,
bad_address = EFAULT,
bad_file_descriptor = EBADF,

#ifdef EBADMSG
bad_message = EBADMSG,
#endif

broken_pipe = EPIPE,
connection_aborted = ECONNABORTED,
connection_already_in_progress = EALREADY,
connection_refused = ECONNREFUSED,
connection_reset = ECONNRESET,
cross_device_link = EXDEV,
destination_address_required = EDESTADDRREQ,
device_or_resource_busy = EBUSY,
directory_not_empty = ENOTEMPTY,
executable_format_error = ENOEXEC,
file_exists = EEXIST,
file_too_large = EFBIG,
filename_too_long = ENAMETOOLONG,
function_not_supported = ENOSYS,
host_unreachable = EHOSTUNREACH,

#ifdef EIDRM
identifier_removed = EIDRM,
#endif

illegal_byte_sequence = EILSEQ,
inappropriate_io_control_operation = ENOTTY,
interrupted = EINTR,
invalid_argument = EINVAL,
invalid_seek = ESPIPE,
io_error = EIO,
is_a_directory = EISDIR,
message_size = EMSGSIZE,
network_down = ENETDOWN,
network_reset = ENETRESET,
network_unreachable = ENETUNREACH,
no_buffer_space = ENOBUFS,
no_child_process = ECHILD,

#ifdef ENOLINK
no_link = ENOLINK,
#endif

no_lock_available = ENOLCK,

#ifdef ENODATA
no_message_available = ENODATA,
#endif

no_message = ENOMSG,
no_protocol_option = ENOPROTOOPT,
no_space_on_device = ENOSPC,

#ifdef ENOSR
no_stream_resources = ENOSR,
#endif

no_such_device_or_address = ENXIO,
no_such_device = ENODEV,
no_such_file_or_directory = ENOENT,
no_such_process = ESRCH,
not_a_directory = ENOTDIR,
not_a_socket = ENOTSOCK,

#ifdef ENOSTR
not_a_stream = ENOSTR,
#endif

not_connected = ENOTCONN,
not_enough_memory = ENOMEM,

#ifdef ENOTSUP
not_supported = ENOTSUP,
#endif

#ifdef ECANCELED
operation_canceled = ECANCELED,
#endif

operation_in_progress = EINPROGRESS,
operation_not_permitted = EPERM,
operation_not_supported = EOPNOTSUPP,
operation_would_block = EWOULDBLOCK,

#ifdef EOWNERDEAD
owner_dead = EOWNERDEAD,
#endif

permission_denied = EACCES,

#ifdef EPROTO
protocol_error = EPROTO,
#endif

protocol_not_supported = EPROTONOSUPPORT,
read_only_file_system = EROFS,
resource_deadlock_would_occur = EDEADLK,
resource_unavailable_try_again = EAGAIN,
result_out_of_range = ERANGE,

#ifdef ENOTRECOVERABLE
state_not_recoverable = ENOTRECOVERABLE,
#endif

#ifdef ETIME
stream_timeout = ETIME,
#endif

#ifdef ETXTBSY
text_file_busy = ETXTBSY,
#endif

timed_out = ETIMEDOUT,
too_many_files_open_in_system = ENFILE,
too_many_files_open = EMFILE,
too_many_links = EMLINK,
too_many_symbolic_link_levels = ELOOP,

#ifdef EOVERFLOW
value_too_large = EOVERFLOW,
#elif defined __AVR__
value_too_large = 999,
#endif

wrong_protocol_type = EPROTOTYPE
};

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif
5 changes: 5 additions & 0 deletions include/bits/functexcept.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#include <bits/c++config.h>
#include <bits/exception_defines.h>
#include <bits/error_constants.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
Expand Down Expand Up @@ -90,6 +91,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
__throw_underflow_error(const char* __s = "") __attribute__((__noreturn__));

// Helpers for exception objects in <system_error>
void
__throw_system_error(int) __attribute__((__noreturn__));

// Helpers for exception objects in <functional>
void
__throw_bad_function_call() __attribute__((__noreturn__));
Expand Down
176 changes: 176 additions & 0 deletions include/bits/std_mutex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// std::mutex implementation -*- C++ -*-

// Copyright (C) 2003-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/std_mutex.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{mutex}
*/

#ifndef _GLIBCXX_MUTEX_H
#define _GLIBCXX_MUTEX_H 1

#pragma GCC system_header

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <bits/functexcept.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

/**
* @defgroup mutexes Mutexes
* @ingroup concurrency
*
* Classes for mutex support.
* @{
*/

#ifdef _GLIBCXX_HAS_GTHREADS
// Common base class for std::mutex and std::timed_mutex
class __mutex_base
{
protected:
typedef __gthread_mutex_t __native_type;

#ifdef __GTHREAD_MUTEX_INIT
__native_type _M_mutex = __GTHREAD_MUTEX_INIT;

constexpr __mutex_base() noexcept = default;
#else
__native_type _M_mutex;

__mutex_base() noexcept
{
// XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
__GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
}

~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
#endif

__mutex_base(const __mutex_base&) = delete;
__mutex_base& operator=(const __mutex_base&) = delete;
};

/// The standard mutex type.
class mutex : private __mutex_base
{
public:
typedef __native_type* native_handle_type;

#ifdef __GTHREAD_MUTEX_INIT
constexpr
#endif
mutex() noexcept = default;
~mutex() = default;

mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;

void
lock()
{
int __e = __gthread_mutex_lock(&_M_mutex);

// EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
if (__e)
__throw_system_error(__e);
}

bool
try_lock() noexcept
{
// XXX EINVAL, EAGAIN, EBUSY
return !__gthread_mutex_trylock(&_M_mutex);
}

void
unlock()
{
// XXX EINVAL, EAGAIN, EPERM
__gthread_mutex_unlock(&_M_mutex);
}

native_handle_type
native_handle() noexcept
{ return &_M_mutex; }
};

#endif // _GLIBCXX_HAS_GTHREADS

/// Do not acquire ownership of the mutex.
struct defer_lock_t { explicit defer_lock_t() = default; };

/// Try to acquire ownership of the mutex without blocking.
struct try_to_lock_t { explicit try_to_lock_t() = default; };

/// Assume the calling thread has already obtained mutex ownership
/// and manage it.
struct adopt_lock_t { explicit adopt_lock_t() = default; };

/// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
_GLIBCXX17_INLINE constexpr defer_lock_t defer_lock { };

/// Tag used to prevent a scoped lock from blocking if a mutex is locked.
_GLIBCXX17_INLINE constexpr try_to_lock_t try_to_lock { };

/// Tag used to make a scoped lock take ownership of a locked mutex.
_GLIBCXX17_INLINE constexpr adopt_lock_t adopt_lock { };

/** @brief A simple scoped lock type.
*
* A lock_guard controls mutex ownership within a scope, releasing
* ownership in the destructor.
*/
template<typename _Mutex>
class lock_guard
{
public:
typedef _Mutex mutex_type;

explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }

lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
{ } // calling thread owns mutex

~lock_guard()
{ _M_device.unlock(); }

lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;

private:
mutex_type& _M_device;
};

// @} group mutexes
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif // _GLIBCXX_MUTEX_H
Loading

0 comments on commit 4e27ef1

Please sign in to comment.