// Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include #include #include #include #include #include #include "primitives.hpp" extern "C" { // TRANSITION, ABI: preserved for binary compatibility (and _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR) _CRTIMP2_PURE void __cdecl _Cnd_init_in_situ(const _Cnd_t cond) noexcept { // initialize condition variable in situ new (cond) _Cnd_internal_imp_t; } // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE void __cdecl _Cnd_destroy_in_situ(_Cnd_t) noexcept {} // destroy condition variable in situ // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_init(_Cnd_t* const pcond) noexcept { // initialize *pcond = nullptr; const auto cond = static_cast<_Cnd_t>(_calloc_crt(1, sizeof(_Cnd_internal_imp_t))); if (cond == nullptr) { return _Thrd_result::_Nomem; // report alloc failed } _Cnd_init_in_situ(cond); *pcond = cond; return _Thrd_result::_Success; } // TRANSITION, ABI: preserved for binary compatibility _CRTIMP2_PURE void __cdecl _Cnd_destroy(const _Cnd_t cond) noexcept { // clean up if (cond) { // something to do, do it _free_crt(cond); } } // TRANSITION, ABI: should be static; dllexported for binary compatibility _CRTIMP2_PURE void __cdecl _Mtx_clear_owner(_Mtx_t mtx) noexcept { // set owner to nobody mtx->_Thread_id = -1; --mtx->_Count; } // TRANSITION, ABI: should be static; dllexported for binary compatibility _CRTIMP2_PURE void __cdecl _Mtx_reset_owner(_Mtx_t mtx) noexcept { // set owner to current thread mtx->_Thread_id = static_cast(GetCurrentThreadId()); ++mtx->_Count; } _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_wait(const _Cnd_t cond, const _Mtx_t mtx) noexcept { // wait until signaled _Mtx_clear_owner(mtx); _Primitive_wait(cond, mtx); _Mtx_reset_owner(mtx); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } // TRANSITION, ABI: preserved for compatibility; wait until signaled or timeout _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_timedwait( const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const target) noexcept { _Thrd_result res = _Thrd_result::_Success; if (target == nullptr) { // no target time specified, wait on mutex _Mtx_clear_owner(mtx); _Primitive_wait(cond, mtx); _Mtx_reset_owner(mtx); } else { // target time specified, wait for it _timespec64 now; _Timespec64_get_sys(&now); _Mtx_clear_owner(mtx); if (!_Primitive_wait_for(cond, mtx, _Xtime_diff_to_millis2(target, &now))) { // report timeout _Timespec64_get_sys(&now); if (_Xtime_diff_to_millis2(target, &now) == 0) { res = _Thrd_result::_Timedout; } } _Mtx_reset_owner(mtx); } return res; } _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_signal(const _Cnd_t cond) noexcept { // release one waiting thread _Primitive_notify_one(cond); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } _CRTIMP2_PURE _Thrd_result __cdecl _Cnd_broadcast(const _Cnd_t cond) noexcept { // release all waiting threads _Primitive_notify_all(cond); return _Thrd_result::_Success; // TRANSITION, ABI: Always succeeds } } // extern "C" /* * 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. */