Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
fix(#30): update to msvc-14.37.32822
Browse files Browse the repository at this point in the history
  • Loading branch information
MiroKaku committed Oct 7, 2023
1 parent 3a5eab4 commit acf02bf
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 77 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Right click on the project and select "Manage NuGet Packages", then search for `

## 3. How to compile

IDE:Visual Studio 2019 or higher (Compiling for ARM/ARM64 requires Visual Studio 2022)
IDE:Visual Studio 2022 latest version

* `git clone --recurse-submodules https://github.com/MiroKaku/ucxxrt.git`
* Open `ucxxrt.sln` and compile.
Expand Down
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void Test$HashMap()

## 3. 怎样编译

IDE:Visual Studio 2019 或更高版本 (编译 ARM/ARM64 需要 Visual Studio 2022)
IDE:Visual Studio 2022 最新版

* `git clone --recurse-submodules https://github.com/MiroKaku/ucxxrt.git`
* 打开 `ucxxrt.sln` 进行编译。
Expand Down
25 changes: 14 additions & 11 deletions src/crt/stl/cond.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ struct _Cnd_internal_imp_t { // condition variable implementation for ConcRT
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
_EXTERN_C
void __cdecl _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
void __cdecl _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
int __cdecl _Cnd_init(_Cnd_t* const pcond) { // initialize
*pcond = nullptr;

const auto cond = static_cast<_Cnd_t>(_calloc_crt(1, sizeof(_Cnd_internal_imp_t)));
Expand All @@ -45,34 +46,35 @@ int _Cnd_init(_Cnd_t* const pcond) { // initialize
return _Thrd_success;
}

void _Cnd_destroy(const _Cnd_t cond) { // clean up
void __cdecl _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
int __cdecl _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
// wait until signaled or timeout
int __cdecl _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const _timespec64* const target) {
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);
_timespec64 now;
_Timespec64_get_sys(&now);
_Mtx_clear_owner(mtx);
if (!cond->_get_cv()->wait_for(cs, _Xtime_diff_to_millis2(target, &now))) { // report timeout
xtime_get(&now, TIME_UTC);
_Timespec64_get_sys(&now);
if (_Xtime_diff_to_millis2(target, &now) == 0) {
res = _Thrd_timedout;
}
Expand All @@ -82,15 +84,16 @@ int _Cnd_timedwait(const _Cnd_t cond, const _Mtx_t mtx, const xtime* const targe
return res;
}

int _Cnd_signal(const _Cnd_t cond) { // release one waiting thread
int __cdecl _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
int __cdecl _Cnd_broadcast(const _Cnd_t cond) { // release all waiting threads
cond->_get_cv()->notify_all();
return _Thrd_success; // TRANSITION, ABI: Always returns _Thrd_success
}
_END_EXTERN_C

/*
* This file is derived from software bearing the following
Expand Down
20 changes: 10 additions & 10 deletions src/crt/stl/cthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ _CRTIMP2_PURE int _Thrd_start(_Thrd_t* thr, _Thrd_callback_t func, void* b) { //
return thr->_Hnd == nullptr ? _Thrd_error : _Thrd_success;
}

int _Thrd_join(_Thrd_t thr, int* code) { // returns when thread terminates
int __cdecl _Thrd_join(_Thrd_t thr, int* code) { // returns when thread terminates
if (ZwWaitForSingleObject(thr._Hnd, FALSE, nullptr) != STATUS_SUCCESS) {
return _Thrd_error;
}
Expand All @@ -72,24 +72,24 @@ int _Thrd_join(_Thrd_t thr, int* code) { // returns when thread terminates
return NT_SUCCESS(ZwClose(thr._Hnd)) ? _Thrd_success : _Thrd_error;
}

int _Thrd_detach(_Thrd_t thr) { // tell OS to release thread's resources when it terminates
int __cdecl _Thrd_detach(_Thrd_t thr) { // tell OS to release thread's resources when it terminates
return NT_SUCCESS(ZwClose(thr._Hnd)) ? _Thrd_success : _Thrd_error;
}

void _Thrd_sleep(const xtime* xt) { // suspend thread until time xt
xtime now;
xtime_get(&now, TIME_UTC);
void __cdecl _Thrd_sleep(const _timespec64* xt) { // suspend thread until time xt
_timespec64 now;
_Timespec64_get_sys(&now);
do { // sleep and check time

LARGE_INTEGER wait_time{};
wait_time.QuadPart = Int32x32To64(_Xtime_diff_to_millis2(xt, &now), -10000);
(void)KeDelayExecutionThread(KernelMode, FALSE, &wait_time);

xtime_get(&now, TIME_UTC);
} while (now.sec < xt->sec || now.sec == xt->sec && now.nsec < xt->nsec);
_Timespec64_get_sys(&now);
} while (now.tv_sec < xt->tv_sec || now.tv_sec == xt->tv_sec && now.tv_nsec < xt->tv_nsec);
}

void _Thrd_yield() { // surrender remainder of timeslice
void __cdecl _Thrd_yield() { // surrender remainder of timeslice
(void)ZwYieldExecution();
}

Expand All @@ -106,11 +106,11 @@ _CRTIMP2_PURE _Thrd_t _Thrd_current() { // return _Thrd_t identifying current th
return result;
}

_Thrd_id_t _Thrd_id() { // return unique id for current thread
_Thrd_id_t __cdecl _Thrd_id() { // return unique id for current thread
return static_cast<_Thrd_id_t>(reinterpret_cast<size_t>(PsGetCurrentThreadId()));
}

unsigned int _Thrd_hardware_concurrency() { // return number of processors
unsigned int __cdecl _Thrd_hardware_concurrency() { // return number of processors
return KeQueryActiveProcessorCount(nullptr);
}

Expand Down
22 changes: 11 additions & 11 deletions src/crt/stl/mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void __cdecl _Mtx_destroy(_Mtx_t mtx) { // destroy mutex
}
}

static int mtx_do_lock(_Mtx_t mtx, const xtime* target) { // lock mutex
static int mtx_do_lock(_Mtx_t mtx, const _timespec64* target) { // lock mutex
if ((mtx->type & ~_Mtx_recursive) == _Mtx_plain) { // set the lock
if (mtx->thread_id != static_cast<long>(reinterpret_cast<size_t>(PsGetCurrentThreadId()))) { // not current thread, do lock
mtx->_get_cs()->lock();
Expand All @@ -101,7 +101,7 @@ static int mtx_do_lock(_Mtx_t mtx, const xtime* target) { // lock mutex

res = STATUS_WAIT_0;

} else if (target->sec < 0 || target->sec == 0 && target->nsec <= 0) {
} else if (target->tv_sec < 0 || target->tv_sec == 0 && target->tv_nsec <= 0) {
// target time <= 0 --> plain trylock or timed wait for time that has passed; try to lock with 0 timeout
if (mtx->thread_id != static_cast<long>(reinterpret_cast<size_t>(PsGetCurrentThreadId()))) { // not this thread, lock it
if (mtx->_get_cs()->try_lock()) {
Expand All @@ -114,9 +114,9 @@ static int mtx_do_lock(_Mtx_t mtx, const xtime* target) { // lock mutex
}

} else { // check timeout
xtime now;
xtime_get(&now, TIME_UTC);
while (now.sec < target->sec || now.sec == target->sec && now.nsec < target->nsec) { // time has not expired
_timespec64 now;
_Timespec64_get_sys(&now);
while (now.tv_sec < target->tv_sec || now.tv_sec == target->tv_sec && now.tv_nsec < target->tv_nsec) {
if (mtx->thread_id == static_cast<long>(reinterpret_cast<size_t>(PsGetCurrentThreadId()))
|| mtx->_get_cs()->try_lock_for(_Xtime_diff_to_millis2(target, &now))) { // stop waiting
res = STATUS_WAIT_0;
Expand All @@ -125,7 +125,7 @@ static int mtx_do_lock(_Mtx_t mtx, const xtime* target) { // lock mutex
res = STATUS_TIMEOUT;
}

xtime_get(&now, TIME_UTC);
_Timespec64_get_sys(&now);
}
}

Expand All @@ -146,7 +146,7 @@ static int mtx_do_lock(_Mtx_t mtx, const xtime* target) { // lock mutex
return _Thrd_success;

case STATUS_TIMEOUT:
if (target == nullptr || (target->sec == 0 && target->nsec == 0)) {
if (target == nullptr || (target->tv_sec == 0 && target->tv_nsec == 0)) {
return _Thrd_busy;
} else {
return _Thrd_timedout;
Expand Down Expand Up @@ -174,14 +174,14 @@ int __cdecl _Mtx_lock(_Mtx_t mtx) { // lock mutex
}

int __cdecl _Mtx_trylock(_Mtx_t mtx) { // attempt to lock try_mutex
xtime xt;
_timespec64 xt;
_THREAD_ASSERT((mtx->type & (_Mtx_try | _Mtx_timed)) != 0, "trylock not supported by mutex");
xt.sec = 0;
xt.nsec = 0;
xt.tv_sec = 0;
xt.tv_nsec = 0;
return mtx_do_lock(mtx, &xt);
}

int __cdecl _Mtx_timedlock(_Mtx_t mtx, const xtime* xt) { // attempt to lock timed mutex
int __cdecl _Mtx_timedlock(_Mtx_t mtx, const _timespec64* xt) { // attempt to lock timed mutex
int res;

_THREAD_ASSERT((mtx->type & _Mtx_timed) != 0, "timedlock not supported by mutex");
Expand Down
6 changes: 3 additions & 3 deletions src/crt/stl/xnotify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _EXTERN_C
void _Lock_at_thread_exit_mutex();
void _Unlock_at_thread_exit_mutex();

void _Cnd_register_at_thread_exit(
void __cdecl _Cnd_register_at_thread_exit(
_Cnd_t cnd, _Mtx_t mtx, int* p) { // register condition variable and mutex for cleanup at thread exit
// find block with available space
_At_thread_exit_block* block = &_Thread_exit_data;
Expand Down Expand Up @@ -62,7 +62,7 @@ void _Cnd_register_at_thread_exit(
_Unlock_at_thread_exit_mutex();
}

void _Cnd_unregister_at_thread_exit(_Mtx_t mtx) { // unregister condition variable/mutex for cleanup at thread exit
void __cdecl _Cnd_unregister_at_thread_exit(_Mtx_t mtx) { // unregister condition variable/mutex for cleanup at thread exit
// find condition variables waiting for this thread to exit
_At_thread_exit_block* block = &_Thread_exit_data;

Expand All @@ -80,7 +80,7 @@ void _Cnd_unregister_at_thread_exit(_Mtx_t mtx) { // unregister condition variab
_Unlock_at_thread_exit_mutex();
}

void _Cnd_do_broadcast_at_thread_exit() { // notify condition variables waiting for this thread to exit
void __cdecl _Cnd_do_broadcast_at_thread_exit() { // notify condition variables waiting for this thread to exit
// find condition variables waiting for this thread to exit
_At_thread_exit_block* block = &_Thread_exit_data;
const unsigned int currentThreadId = _Thrd_id();
Expand Down
87 changes: 47 additions & 40 deletions src/crt/stl/xtime.cpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// xtime functions
// _timespec64 functions for system time

#include <atomic>
#include <xtimec.h>

//#include "awint.hpp"
// #include "awint.hpp"

constexpr long _Nsec_per_sec = 1000000000L;
constexpr long _Nsec_per_sec = 1000000000L;
constexpr long _Nsec_per_msec = 1000000L;
constexpr int _Msec_per_sec = 1000;
constexpr int _Msec_per_sec = 1000;

static void xtime_normalize(xtime* xt) { // adjust so that 0 <= nsec < 1 000 000 000
while (xt->nsec < 0) { // normalize target time
xt->sec -= 1;
xt->nsec += _Nsec_per_sec;
static void _timespec64_normalize(_timespec64* xt) { // adjust so that 0 <= tv_nsec < 1 000 000 000
while (xt->tv_nsec < 0) { // normalize target time
xt->tv_sec -= 1;
xt->tv_nsec += _Nsec_per_sec;
}
while (_Nsec_per_sec <= xt->nsec) { // normalize target time
xt->sec += 1;
xt->nsec -= _Nsec_per_sec;
while (_Nsec_per_sec <= xt->tv_nsec) { // normalize target time
xt->tv_sec += 1;
xt->tv_nsec -= _Nsec_per_sec;
}
}

static xtime xtime_diff(const xtime* xt,
const xtime* now) { // return xtime object holding difference between xt and now, treating negative difference as 0
xtime diff = *xt;
xtime_normalize(&diff);
if (diff.nsec < now->nsec) { // avoid underflow
diff.sec -= now->sec + 1;
diff.nsec += _Nsec_per_sec - now->nsec;
} else { // no underflow
diff.sec -= now->sec;
diff.nsec -= now->nsec;
// return _timespec64 object holding difference between xt and now, treating negative difference as 0
static _timespec64 _timespec64_diff(const _timespec64* xt, const _timespec64* now) {
_timespec64 diff = *xt;
_timespec64_normalize(&diff);
if (diff.tv_nsec < now->tv_nsec) { // avoid underflow
diff.tv_sec -= now->tv_sec + 1;
diff.tv_nsec += _Nsec_per_sec - now->tv_nsec;
}
else { // no underflow
diff.tv_sec -= now->tv_sec;
diff.tv_nsec -= now->tv_nsec;
}

if (diff.sec < 0 || (diff.sec == 0 && diff.nsec <= 0)) { // time is zero
diff.sec = 0;
diff.nsec = 0;
if (diff.tv_sec < 0 || (diff.tv_sec == 0 && diff.tv_nsec <= 0)) { // time is zero
diff.tv_sec = 0;
diff.tv_nsec = 0;
}
return diff;
}


constexpr long long _Epoch = 0x19DB1DED53E8000LL;
constexpr long long _Epoch = 0x19DB1DED53E8000LL;
constexpr long _Nsec100_per_sec = _Nsec_per_sec / 100;

_EXTERN_C
Expand All @@ -54,39 +54,46 @@ _CRTIMP2_PURE long long __cdecl _Xtime_get_ticks() { // get system time in 100-n
return ((static_cast<long long>(li.HighPart)) << 32) + static_cast<long long>(li.LowPart) - _Epoch;
}

static void sys_get_time(xtime* xt) { // get system time with nanosecond resolution
// Used by several src files, but not dllexported.
void _Timespec64_get_sys(_timespec64* xt) { // get system time with nanosecond resolution
unsigned long long now = _Xtime_get_ticks();
xt->sec = static_cast<__time64_t>(now / _Nsec100_per_sec);
xt->nsec = static_cast<long>(now % _Nsec100_per_sec) * 100;
xt->tv_sec = static_cast<__time64_t>(now / _Nsec100_per_sec);
xt->tv_nsec = static_cast<long>(now % _Nsec100_per_sec) * 100;
}

_CRTIMP2_PURE long __cdecl _Xtime_diff_to_millis2(const xtime* xt1, const xtime* xt2) { // convert time to milliseconds
xtime diff = xtime_diff(xt1, xt2);
return static_cast<long>(diff.sec * _Msec_per_sec + (diff.nsec + _Nsec_per_msec - 1) / _Nsec_per_msec);
// convert time to milliseconds
_CRTIMP2_PURE long __cdecl _Xtime_diff_to_millis2(const _timespec64* xt1, const _timespec64* xt2) {
_timespec64 diff = _timespec64_diff(xt1, xt2);
return static_cast<long>(diff.tv_sec * _Msec_per_sec + (diff.tv_nsec + _Nsec_per_msec - 1) / _Nsec_per_msec);
}

_CRTIMP2_PURE long __cdecl _Xtime_diff_to_millis(const xtime* xt) { // convert time to milliseconds
xtime now;
xtime_get(&now, TIME_UTC);
// TRANSITION, ABI: preserved for binary compatibility
_CRTIMP2_PURE long __cdecl _Xtime_diff_to_millis(const _timespec64* xt) { // convert time to milliseconds
_timespec64 now;
_Timespec64_get_sys(&now);
return _Xtime_diff_to_millis2(xt, &now);
}

_CRTIMP2_PURE int __cdecl xtime_get(xtime* xt, int type) { // get current time
// TRANSITION, ABI: preserved for binary compatibility
_CRTIMP2_PURE int __cdecl xtime_get(_timespec64* xt, int type) { // get current time
if (type != TIME_UTC || xt == nullptr) {
type = 0;
} else {
sys_get_time(xt);
}
else {
_Timespec64_get_sys(xt);
}

return type;
}

_CRTIMP2_PURE long long __cdecl _Query_perf_counter() { // get current value of performance counter
return KeQueryPerformanceCounter(nullptr).QuadPart;
LARGE_INTEGER li;
KeQueryPerformanceCounter(&li); // always succeeds
return li.QuadPart;
}

_CRTIMP2_PURE long long __cdecl _Query_perf_frequency() { // get frequency of performance counter
static std::atomic<long long> freq_cached{0};
static std::atomic<long long> freq_cached{ 0 };
long long freq = freq_cached.load(std::memory_order_relaxed);
if (freq == 0) {
LARGE_INTEGER li;
Expand Down

0 comments on commit acf02bf

Please sign in to comment.