Skip to content

Commit

Permalink
Merge branch 'work'
Browse files Browse the repository at this point in the history
  • Loading branch information
oktonion committed Mar 26, 2021
2 parents 23ad638 + 72f4230 commit 41da83c
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 104 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ All notable changes to stdex library project will be documented in this file.

visit [https://github.com/oktonion/stdex](https://github.com/oktonion/stdex) for the latest version of stdex library

## [0.2.9] - 2021-xx-xx
## [0.2.9] - 2021-03-26

### Added

### Changed

- pthreads-win32 library with fresh fixes (affects Windows only)
- dynamic load of 'ntdll.dll' (no more need for 'ntdll.lib' linkage)
- when using `big_int` as internal implementation for `stdex::chrono::system_clock` and `stdex::chrono::steady_clock` duration counter define duration as `stdex::chrono::nanoseconds`

### Fixed

- static analysis warnings about uninitialized variables and negating unsigned values
- `stdex::condition_variable::wait_for`


## [0.2.8] - 2021-01-26

Expand Down
2 changes: 1 addition & 1 deletion pthread-win32
Submodule pthread-win32 updated 162 files
2 changes: 1 addition & 1 deletion stdex/build_lib.bat
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ if ["%~1"]==["debug"] (
)

echo "compiling %VisualStudioVersion% pthread-win32"
cl -EHsc -W4 -Fo.\stdex\obj\pthread.obj -D HAVE_CONFIG_H -c ".\pthread-win32\pthread.c" %build_opt%
cl -EHsc -W4 -Fo.\stdex\obj\pthread.obj -D HAVE_CONFIG_H -D PTW32_STATIC_LIB -c ".\pthread-win32\pthread.c" %build_opt%
if ERRORLEVEL 1 set "build_ok=0"
if /I "%build_ok%" NEQ "1" (
echo "failed"
Expand Down
6 changes: 4 additions & 2 deletions stdex/include/chrono.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,8 @@ namespace stdex
{
typedef
stdex::conditional<
(sizeof(stdex::intmax_t) * CHAR_BIT >= 64),
(sizeof(chrono::nanoseconds::rep) * CHAR_BIT >= 64) ||
(detail::_use_big_int<chrono::nanoseconds::rep, chrono::nanoseconds::period>::value == bool(true)),
chrono::nanoseconds,
chrono::microseconds
>::type duration;
Expand Down Expand Up @@ -1313,7 +1314,8 @@ namespace stdex
{
typedef
stdex::conditional<
(sizeof(stdex::intmax_t)* CHAR_BIT >= 64),
(sizeof(chrono::nanoseconds::rep) * CHAR_BIT >= 64) ||
(detail::_use_big_int<chrono::nanoseconds::rep, chrono::nanoseconds::period>::value == bool(true)),
chrono::nanoseconds,
chrono::microseconds
>::type duration;
Expand Down
91 changes: 58 additions & 33 deletions stdex/include/condition_variable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ namespace stdex

class condition_variable
{
typedef chrono::system_clock clock_t;

public:
typedef pthread_cond_t* native_handle_type;

Expand Down Expand Up @@ -134,20 +132,10 @@ namespace stdex
wait(_lock);
}

template<class _Duration>
cv_status wait_until(unique_lock<mutex> &_lock, const chrono::time_point<clock_t, _Duration> &_atime)
{
return wait_until_impl(_lock, _atime);
}

template<class _Clock, class _Duration>
cv_status wait_until(unique_lock<mutex> &_lock, const chrono::time_point<_Clock, _Duration> &_atime)
{
// DR 887 - Sync unknown clock to known clock.
const typename _Clock::time_point _c_entry = _Clock::now();
const clock_t::time_point _s_entry = clock_t::now();

return wait_until_impl(_lock, (_s_entry + (_atime - _c_entry)));
return wait_until_impl(_lock, _atime);
}

template<class _Clock, class _Duration, class _Predicate>
Expand All @@ -162,24 +150,22 @@ namespace stdex
template<class _Rep, class _Period>
cv_status wait_for(unique_lock<mutex> &_lock, const chrono::duration<_Rep, _Period> &_rtime)
{
chrono::duration<_Rep, _Period> _rt = _rtime;
if (ratio_greater<clock_t::period, _Period>::value)
++_rt;
return wait_for_impl(_lock, _rt);
return wait_for_impl(_lock, _rtime);
}

template<class _Rep, class _Period, class _Predicate>
bool wait_for(unique_lock<mutex> &_lock, const chrono::duration<_Rep, _Period> &_rtime, _Predicate _p)
{
chrono::duration<_Rep, _Period> _rt = _rtime;
if (ratio_greater<clock_t::period, _Period>::value)
++_rt;
typedef chrono::system_clock sync_clock;

sync_clock::time_point _atime =
sync_clock::now() + chrono::duration_cast<sync_clock::duration>(_rtime);

// exactly the same as wait_until with predicate
while (!_p())
if (wait_for_impl(_lock, _rtime) == cv_status::timeout)
if (wait_until(_lock, _atime) == cv_status::timeout)
return _p();
return true;
return wait_until(_lock, clock_t::now() + chrono::duration_cast<clock_t::duration>(_rt), _p);
}

native_handle_type native_handle()
Expand All @@ -199,14 +185,47 @@ namespace stdex

private:

template<class _Dur>
cv_status wait_until_impl(unique_lock<mutex> &_lock, const chrono::time_point<clock_t, _Dur> &_atime)
template<class _Clock, class _Dur>
cv_status wait_until_impl(unique_lock<mutex> &_lock, const chrono::time_point<_Clock, _Dur> &_atime)
{
if (!detail::_lock_owns_lock(_lock))
std::terminate();

typedef chrono::system_clock wait_until_clock;

// DR 887 - Sync unknown clock to known clock.
struct lambdas
{
typedef _Clock _Clock_local;
typedef _Dur _Dur_local;
typedef typename _Clock_local::time_point _Clock_time_point;

static chrono::time_point<wait_until_clock, _Dur_local> sync_clock_tp(const chrono::time_point<_Clock_local, _Dur_local>& _atime, ...)
{
const _Clock_time_point _c_entry = _Clock_local::now();
const wait_until_clock::time_point _s_entry = wait_until_clock::now();

_Dur_local _delta = (_atime - _c_entry);
return (_s_entry + stdex::chrono::duration_cast<wait_until_clock::duration>(_delta));
}

static const chrono::time_point<wait_until_clock, _Dur_local>& sync_clock_tp(const chrono::time_point<wait_until_clock, _Dur_local>& _atime, int)
{
return _atime;
}
};

wait_until_clock::time_point _tp = chrono::time_point_cast<wait_until_clock::duration>(
lambdas::sync_clock_tp(_atime, 0)
);

if (_tp < wait_until_clock::now())
return cv_status::timeout;

stdex::timespec _tp_as_ts =
clock_t::to_timespec(chrono::time_point_cast<clock_t::duration>(_atime));
wait_until_clock::to_timespec(
_tp
);

::timespec _ts;

Expand All @@ -228,31 +247,37 @@ namespace stdex
}
#endif

return (clock_t::now() < _atime
return (wait_until_clock::now() < _tp
? cv_status::no_timeout : cv_status::timeout);
}

template<class _Rep, class _Period>
cv_status wait_for_impl(unique_lock<mutex> &_lock, const chrono::duration<_Rep, _Period> &_rtime)
cv_status wait_for_impl(unique_lock<mutex> &_lock, chrono::duration<_Rep, _Period> _rtime)
{
if (!detail::_lock_owns_lock(_lock))
std::terminate();

if (_rtime.count() < 0)
return cv_status::timeout;

clock_t::time_point
_start_time_point = clock_t::now(),
_end_time_point = _start_time_point + stdex::chrono::duration_cast<clock_t::duration>(_rtime);
typedef chrono::system_clock time_measurment_clock;
typedef chrono::system_clock wait_for_clock;

if (ratio_greater<time_measurment_clock::period, _Period>::value)
++_rtime;

time_measurment_clock::time_point
_start_time_point = time_measurment_clock::now(),
_end_time_point = _start_time_point + stdex::chrono::duration_cast<time_measurment_clock::duration>(_rtime);

stdex::timespec _tp_as_ts =
clock_t::to_timespec(_end_time_point);
wait_for_clock::to_timespec(wait_for_clock::now() + stdex::chrono::duration_cast<wait_for_clock::duration>(_rtime));

::timespec _ts;
_ts.tv_sec = _tp_as_ts.tv_sec;
_ts.tv_nsec = _tp_as_ts.tv_nsec;

if ((clock_t::now() - _start_time_point) > _rtime)
if ((time_measurment_clock::now() - _start_time_point) > _rtime)
return cv_status::timeout;

int _err =
Expand All @@ -270,7 +295,7 @@ namespace stdex
}
#endif

return (clock_t::now() - _start_time_point < _rtime
return (time_measurment_clock::now() - _start_time_point < _rtime
? cv_status::no_timeout : cv_status::timeout);
}

Expand Down
23 changes: 13 additions & 10 deletions stdex/include/mutex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,15 +450,18 @@ namespace stdex
unique_lock& operator=(const unique_lock&) _STDEX_DELETED_FUNCTION;
};

class timed_mutex;
class timed_mutex;
class recursive_timed_mutex;

namespace detail
{
void* pthread_mutex_timedlock(...); // dummy


namespace mutex_type_traits
{
#ifndef PTW32_VERSION
static float* pthread_mutex_timedlock(...); // dummy
#endif

template<class _Tp>
_Tp declval();

Expand All @@ -471,7 +474,7 @@ namespace stdex
sizeof(
_pthread_func_tester(
pthread_mutex_timedlock(
declval<pthread_mutex_t*>(),
declval< ::pthread_mutex_t*>(),
declval< ::timespec* >()
)
)
Expand All @@ -497,8 +500,8 @@ namespace stdex
return try_lock_until1(_mutex_handle, _clock::now() + _rt);
}

template<class _Duration>
static bool try_lock_until1(pthread_mutex_t& _mutex_handle,
template<class _Duration, class _MtxHandle>
static bool try_lock_until1(_MtxHandle& _mutex_handle,
const chrono::time_point<chrono::system_clock, _Duration>& _atime)
{
stdex::timespec _tp_as_ts =
Expand Down Expand Up @@ -891,8 +894,8 @@ namespace stdex
template<>
class _timed_mutex_impl<timed_mutex> :
public _timed_mutex_impl_base<
_mutex_base,
mutex_type_traits::_has_pthread_mutex_timedlock::value
_mutex_base,
mutex_type_traits::_has_pthread_mutex_timedlock::value
>
{
protected:
Expand All @@ -903,8 +906,8 @@ namespace stdex
template<>
class _timed_mutex_impl<recursive_timed_mutex> :
public _timed_mutex_impl_base<
_recursive_mutex_base,
mutex_type_traits::_has_pthread_mutex_timedlock::value
_recursive_mutex_base,
mutex_type_traits::_has_pthread_mutex_timedlock::value
>
{
protected:
Expand Down
1 change: 1 addition & 0 deletions stdex/include/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ namespace stdex
};

template<class _ArgT>
inline
void _swprintf4_std_impl(wchar_t* ws, cstddef::size_t len, const wchar_t* format, _ArgT arg)
{
_swprintf_impl<_has_4arg_swprintf::value>::call(ws, len, format, arg);
Expand Down
Loading

0 comments on commit 41da83c

Please sign in to comment.