This repository has been archived by the owner on Jul 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
std::mutex std::timed_mutex std::recursive_mutex std::recursive_timed_mutex std::condition_variable std::condition_variable_any std::notify_all_at_thread_exit
- Loading branch information
Showing
17 changed files
with
997 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
// condition variable functions | ||
|
||
#include <cstdlib> | ||
#include <internal_shared.h> | ||
#include <type_traits> | ||
#include <xthreads.h> | ||
#include <xtimec.h> | ||
|
||
#include "primitives.hpp" | ||
|
||
struct _Cnd_internal_imp_t { // condition variable implementation for ConcRT | ||
typename std::_Aligned_storage<Concurrency::details::stl_condition_variable_max_size, | ||
Concurrency::details::stl_condition_variable_max_alignment>::type cv; | ||
|
||
[[nodiscard]] Concurrency::details::stl_condition_variable_interface* _get_cv() noexcept { | ||
// get pointer to implementation | ||
return reinterpret_cast<Concurrency::details::stl_condition_variable_interface*>(&cv); | ||
} | ||
}; | ||
|
||
static_assert(sizeof(_Cnd_internal_imp_t) <= _Cnd_internal_imp_size, "incorrect _Cnd_internal_imp_size"); | ||
static_assert(alignof(_Cnd_internal_imp_t) <= _Cnd_internal_imp_alignment, "incorrect _Cnd_internal_imp_alignment"); | ||
|
||
void _Cnd_init_in_situ(const _Cnd_t cond) { // initialize condition variable in situ | ||
Concurrency::details::create_stl_condition_variable(cond->_get_cv()); | ||
} | ||
|
||
void _Cnd_destroy_in_situ(const _Cnd_t cond) { // destroy condition variable in situ | ||
cond->_get_cv()->destroy(); | ||
} | ||
|
||
int _Cnd_init(_Cnd_t* const pcond) { // initialize | ||
*pcond = nullptr; | ||
|
||
const auto cond = static_cast<_Cnd_t>(_calloc_crt(1, sizeof(_Cnd_internal_imp_t))); | ||
if (cond == nullptr) { | ||
return _Thrd_nomem; // report alloc failed | ||
} | ||
|
||
_Cnd_init_in_situ(cond); | ||
*pcond = cond; | ||
return _Thrd_success; | ||
} | ||
|
||
void _Cnd_destroy(const _Cnd_t cond) { // clean up | ||
if (cond) { // something to do, do it | ||
_Cnd_destroy_in_situ(cond); | ||
_free_crt(cond); | ||
} | ||
} | ||
|
||
int _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) { // wait until signaled | ||
const auto cs = static_cast<Concurrency::details::stl_critical_section_interface*>(_Mtx_getconcrtcs(mtx)); | ||
_Mtx_clear_owner(mtx); | ||
cond->_get_cv()->wait(cs); | ||
_Mtx_reset_owner(mtx); | ||
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success | ||
} | ||
|
||
int _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const xtime* const target) { // wait until signaled or timeout | ||
int res = _Thrd_success; | ||
const auto cs = static_cast<Concurrency::details::stl_critical_section_interface*>(_Mtx_getconcrtcs(mtx)); | ||
if (target == nullptr) { // no target time specified, wait on mutex | ||
_Mtx_clear_owner(mtx); | ||
cond->_get_cv()->wait(cs); | ||
_Mtx_reset_owner(mtx); | ||
} else { // target time specified, wait for it | ||
xtime now; | ||
xtime_get(&now, TIME_UTC); | ||
_Mtx_clear_owner(mtx); | ||
if (!cond->_get_cv()->wait_for(cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout | ||
xtime_get(&now, TIME_UTC); | ||
if (_Xtime_diff_to_millis2(target, &now) == 0) { | ||
res = _Thrd_timedout; | ||
} | ||
} | ||
_Mtx_reset_owner(mtx); | ||
} | ||
return res; | ||
} | ||
|
||
int _Cnd_signal(const _Cnd_t cond) { // release one waiting thread | ||
cond->_get_cv()->notify_one(); | ||
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success | ||
} | ||
|
||
int _Cnd_broadcast(const _Cnd_t cond) { // release all waiting threads | ||
cond->_get_cv()->notify_all(); | ||
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success | ||
} | ||
|
||
/* | ||
* This file is derived from software bearing the following | ||
* restrictions: | ||
* | ||
* (c) Copyright William E. Kempf 2001 | ||
* | ||
* Permission to use, copy, modify, distribute and sell this | ||
* software and its documentation for any purpose is hereby | ||
* granted without fee, provided that the above copyright | ||
* notice appear in all copies and that both that copyright | ||
* notice and this permission notice appear in supporting | ||
* documentation. William E. Kempf makes no representations | ||
* about the suitability of this software for any purpose. | ||
* It is provided "as is" without express or implied warranty. | ||
*/ |
Oops, something went wrong.