2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-03 09:42:16 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
William E. Kempf
c09b4110d7 Fixed several bugs in the new unit test code
[SVN r14788]
2002-08-12 14:27:00 +00:00
William E. Kempf
b75a32b913 Fixed xtime bugs
[SVN r13865]
2002-05-14 21:11:36 +00:00
nobody
c6b8f21bde This commit was manufactured by cvs2svn to create branch 'RC_1_28_0'.
[SVN r13795]
2002-05-10 04:34:27 +00:00
8 changed files with 154 additions and 97 deletions

View File

@@ -62,9 +62,9 @@ lib boost_thread
#######################
# Stage the generated targets.
stage bin-stage
: <lib>boost_thread $(threadmon)
: <tag><runtime-link-static>"s"
<tag><debug>"d"
: debug release <runtime-link>static/dynamic
;
#stage bin-stage
# : <lib>boost_thread $(threadmon)
# : <tag><runtime-link-static>"s"
# <tag><debug>"d"
# : debug release <runtime-link>static/dynamic
#;

View File

@@ -39,7 +39,13 @@ struct xtime
int_fast32_t nsec;
};
int xtime_get(struct xtime* xtp, int clock_type);
int xtime_get(xtime* xtp, int clock_type);
inline int xtime_cmp(const xtime& xtp1, const xtime& xtp2)
{
int res = xtp1.sec - xtp2.sec;
if (res == 0) res = xtp1.nsec - xtp2.nsec;
return res;
}
} // namespace boost

View File

@@ -17,6 +17,8 @@
#include <cassert>
#include "timeconv.inl"
#include <iostream>
#if defined(BOOST_HAS_WINTHREADS)
# ifndef NOMINMAX
# define NOMINMAX
@@ -242,71 +244,103 @@ void condition::do_wait()
}
}
//#define DOFIX
bool condition::do_timed_wait(const xtime& xt)
{
unsigned milliseconds;
to_duration(xt, milliseconds);
bool ret = false;
unsigned int res = 0;
unsigned int res = 0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), milliseconds);
assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
#if defined(DOFIX)
for (;;)
{
#endif
int milliseconds;
to_duration(xt, milliseconds);
if (milliseconds < 0)
std::cout << "milliseconds < 0" << std::endl;
if (milliseconds > 10000)
std::cout << "milliseconds > 10000" << std::endl;
// assert(milliseconds > 0);
bool ret = (res == WAIT_OBJECT_0);
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), milliseconds);
assert(res != WAIT_FAILED && res != WAIT_ABANDONED);
unsigned was_waiting=0;
unsigned was_gone=0;
ret = (res == WAIT_OBJECT_0);
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (!ret) // timeout
{
if (m_blocked != 0)
--m_blocked;
else
++m_gone; // count spurious wakeups
}
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); // open m_gate
assert(res);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == (std::numeric_limits<unsigned>::max() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
m_blocked -= m_gone;
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
m_gone = 0;
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
#if defined(DOFIX)
if (ret)
break;
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE);
assert(res == WAIT_OBJECT_0);
}
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
xtime now;
xtime_get(&now, TIME_UTC);
if (xtime_cmp(xt, now) >= 0)
break;
}
#endif
unsigned was_waiting=0;
unsigned was_gone=0;
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), INFINITE);
assert(res == WAIT_OBJECT_0);
was_waiting = m_waiting;
was_gone = m_gone;
if (was_waiting != 0)
{
if (!ret) // timeout?
{
if (m_blocked != 0)
--m_blocked;
else
++m_gone; // count spurious wakeups
}
if (--m_waiting == 0)
{
if (m_blocked != 0)
{
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0); // open m_gate
assert(res);
was_waiting = 0;
}
else if (m_gone != 0)
m_gone = 0;
}
}
else if (++m_gone == (std::numeric_limits<unsigned>::max() / 2))
{
// timeout occured, normalize the m_gone count
// this may occur if many calls to wait with a timeout are made and
// no call to notify_* is made
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_gate), INFINITE);
assert(res == WAIT_OBJECT_0);
m_blocked -= m_gone;
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
m_gone = 0;
}
res = ReleaseMutex(reinterpret_cast<HANDLE>(m_mutex));
assert(res);
if (was_waiting == 1)
{
for (/**/ ; was_gone; --was_gone)
{
// better now than spurious later
res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_queue), INFINITE);
assert(res == WAIT_OBJECT_0);
}
res = ReleaseSemaphore(reinterpret_cast<HANDLE>(m_gate), 1, 0);
assert(res);
}
// if (!ret)
// {
// xtime now;
// xtime_get(&now, TIME_UTC);
// if (xtime_cmp(xt, now) >= 0)
// break;
// }
return ret;
}
@@ -571,7 +605,7 @@ void condition::do_wait()
bool condition::do_timed_wait(const xtime& xt)
{
unsigned milliseconds;
int milliseconds;
to_duration(xt, milliseconds);
OSStatus lStatus = noErr;

View File

@@ -145,7 +145,7 @@ bool timed_mutex::do_trylock()
bool timed_mutex::do_timedlock(const xtime& xt)
{
unsigned milliseconds;
int milliseconds;
to_duration(xt, milliseconds);
unsigned int res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), milliseconds);
@@ -500,7 +500,7 @@ bool timed_mutex::do_trylock()
bool timed_mutex::do_timedlock(const xtime& xt)
{
unsigned microseconds;
int microseconds;
to_microduration(xt, microseconds);
Duration lDuration = kDurationMicrosecond * microseconds;

View File

@@ -195,7 +195,7 @@ bool recursive_timed_mutex::do_trylock()
bool recursive_timed_mutex::do_timedlock(const xtime& xt)
{
unsigned milliseconds;
int milliseconds;
to_duration(xt, milliseconds);
unsigned int res = 0;
@@ -936,7 +936,7 @@ bool recursive_timed_mutex::do_trylock()
bool recursive_timed_mutex::do_timedlock(const xtime& xt)
{
unsigned microseconds;
int microseconds;
to_microduration(xt, microseconds);
Duration lDuration = kDurationMicrosecond * microseconds;

View File

@@ -12,6 +12,8 @@
#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/thread/condition.hpp>
#include <exception>
#include <cassert>
#if defined(BOOST_HAS_WINTHREADS)
@@ -72,6 +74,8 @@ static OSStatus thread_proxy(void* param)
}
catch (...)
{
using namespace std;
terminate();
}
#if defined(BOOST_HAS_MPTASKS)
::boost::detail::thread_cleanup();
@@ -192,13 +196,13 @@ void thread::join()
void thread::sleep(const xtime& xt)
{
#if defined(BOOST_HAS_WINTHREADS)
unsigned milliseconds;
int milliseconds;
to_duration(xt, milliseconds);
Sleep(milliseconds);
#elif defined(BOOST_HAS_PTHREADS)
# if defined(BOOST_HAS_PTHREAD_DELAY_NP)
timespec ts;
to_timespec(xt, ts);
to_timespec_duration(xt, ts);
int res = 0;
res = pthread_delay_np(&ts);
assert(res == 0);
@@ -216,7 +220,7 @@ void thread::sleep(const xtime& xt)
cond.timed_wait(lock, xt);
# endif
#elif defined(BOOST_HAS_MPTASKS)
unsigned microseconds;
int microseconds;
to_microduration(xt, microseconds);
Duration lMicroseconds(kDurationMicrosecond * microseconds);
AbsoluteTime sWakeTime(DurationToAbsolute(lMicroseconds));

View File

@@ -10,14 +10,14 @@
// It is provided "as is" without express or implied warranty.
namespace {
const unsigned MILLISECONDS_PER_SECOND = 1000;
const unsigned NANOSECONDS_PER_SECOND = 1000000000;
const unsigned NANOSECONDS_PER_MILLISECOND = 1000000;
const int MILLISECONDS_PER_SECOND = 1000;
const int NANOSECONDS_PER_SECOND = 1000000000;
const int NANOSECONDS_PER_MILLISECOND = 1000000;
const unsigned MICROSECONDS_PER_SECOND = 1000000;
const unsigned NANOSECONDS_PER_MICROSECOND = 1000;
const int MICROSECONDS_PER_SECOND = 1000000;
const int NANOSECONDS_PER_MICROSECOND = 1000;
inline void to_time(unsigned milliseconds, boost::xtime& xt)
inline void to_time(int milliseconds, boost::xtime& xt)
{
int res = 0;
res = boost::xtime_get(&xt, boost::TIME_UTC);
@@ -45,7 +45,7 @@ namespace {
}
}
inline void to_time(unsigned milliseconds, timespec& ts)
inline void to_time(int milliseconds, timespec& ts)
{
boost::xtime xt;
to_time(milliseconds, xt);
@@ -59,7 +59,7 @@ namespace {
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (xt.sec < cur.sec || (xt.sec == cur.sec && xt.nsec < cur.nsec))
if (boost::xtime_cmp(xt, cur) < 0)
{
ts.tv_sec = 0;
ts.tv_nsec = 0;
@@ -83,37 +83,37 @@ namespace {
}
#endif
inline void to_duration(const boost::xtime& xt, unsigned& milliseconds)
inline void to_duration(const boost::xtime& xt, int& milliseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (xt.sec < cur.sec || (xt.sec == cur.sec && xt.nsec < cur.nsec))
if (boost::xtime_cmp(xt, cur) <= 0)
milliseconds = 0;
else
{
milliseconds = static_cast<unsigned>(((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
milliseconds = ((xt.sec - cur.sec) * MILLISECONDS_PER_SECOND) +
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MILLISECOND/2)) /
NANOSECONDS_PER_MILLISECOND));
NANOSECONDS_PER_MILLISECOND);
}
}
inline void to_microduration(const boost::xtime& xt, unsigned& microseconds)
inline void to_microduration(const boost::xtime& xt, int& microseconds)
{
boost::xtime cur;
int res = 0;
res = boost::xtime_get(&cur, boost::TIME_UTC);
assert(res == boost::TIME_UTC);
if (xt.sec < cur.sec || (xt.sec == cur.sec && xt.nsec < cur.nsec))
if (boost::xtime_cmp(xt, cur) <= 0)
microseconds = 0;
else
{
microseconds = static_cast<unsigned long>(((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
microseconds = ((xt.sec - cur.sec) * MICROSECONDS_PER_SECOND) +
(((xt.nsec - cur.nsec) + (NANOSECONDS_PER_MICROSECOND/2)) /
NANOSECONDS_PER_MICROSECOND));
NANOSECONDS_PER_MICROSECOND);
}
}
}

View File

@@ -42,6 +42,10 @@ void test_lock(M* dummy=0)
BOOST_TEST(condition.timed_wait(lock, xt) == false);
BOOST_TEST(lock);
// boost::xtime now;
// BOOST_TEST(boost::xtime_get(&now, boost::TIME_UTC) == boost::TIME_UTC);
// BOOST_TEST(boost::xtime_cmp(xt, now) >= 0);
// Test the lock and unlock methods.
lock.unlock();
BOOST_TEST(!lock);
@@ -438,14 +442,23 @@ void test_once()
int test_main(int, char*[])
{
for (int i = 0; i < 100; ++i)
{
boost::xtime xt1, xt2;
BOOST_TEST(boost::xtime_get(&xt1, boost::TIME_UTC) == boost::TIME_UTC);
// for (int j = 0; j < 1000000000; ++j) ;
BOOST_TEST(boost::xtime_get(&xt2, boost::TIME_UTC) == boost::TIME_UTC);
BOOST_TEST(boost::xtime_cmp(xt1, xt2) <= 0);
}
test_mutex();
test_try_mutex();
test_timed_mutex();
test_recursive_mutex();
test_recursive_try_mutex();
test_recursive_timed_mutex();
test_condition();
test_tss();
test_once();
// test_try_mutex();
// test_timed_mutex();
// test_recursive_mutex();
// test_recursive_try_mutex();
// test_recursive_timed_mutex();
// test_condition();
// test_tss();
// test_once();
return 0;
}