diff options
-rw-r--r-- | cpp/src/Makefile.am | 3 | ||||
-rw-r--r-- | cpp/src/qpid/sys/Time.h | 96 | ||||
-rw-r--r-- | cpp/src/qpid/sys/posix/Time.cpp | 34 | ||||
-rwxr-xr-x | cpp/src/qpid/sys/posix/Time.h | 34 | ||||
-rw-r--r-- | cpp/src/tests/latencytest.cpp | 6 |
5 files changed, 125 insertions, 48 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am index 6af68f780b..537c111b62 100644 --- a/cpp/src/Makefile.am +++ b/cpp/src/Makefile.am @@ -93,7 +93,8 @@ posix_plat_hdr = \ qpid/sys/posix/Mutex.h \ qpid/sys/posix/Fork.h \ qpid/sys/posix/PollableCondition.h \ - qpid/sys/posix/IntegerTypes.h + qpid/sys/posix/IntegerTypes.h \ + qpid/sys/posix/Time.h if HAVE_EPOLL poller = qpid/sys/epoll/EpollPoller.cpp diff --git a/cpp/src/qpid/sys/Time.h b/cpp/src/qpid/sys/Time.h index 27839e8eb3..d39be95434 100644 --- a/cpp/src/qpid/sys/Time.h +++ b/cpp/src/qpid/sys/Time.h @@ -23,6 +23,16 @@ */ #include "qpid/sys/IntegerTypes.h" +/* + * The platform defines its notion of time as a TimePrivate type. The + * platform's implementation knows how to handle this type. + */ +#if defined (_WIN32) +# include "windows/Time.h" +#else +# include "posix/Time.h" +#endif + #include <limits> #include <iosfwd> @@ -31,16 +41,20 @@ namespace sys { class Duration; -/** Class to represent an instant in time: +/** + * @class AbsTime + * + * Class to represent an instant in time. + * * The time resolution is in nanosecs, and this is held with 64 bits * giving a total time span from about 25 million years ago to 25 million * years hence. As an aside the internal time can sensibly be negative * meaning before the epoch (probably 1/1/1970 although this class doesn't * care). * - * The AbsTime class is a value class and so you don't need to add any accessors - * to its internal state. If you think you want to replace its value,i - * You need to construct a new AbsTime and assign it, viz: + * The AbsTime class is a value class and so you don't need to add any + * accessors to its internal state. If you think you want to replace its value, + * you need to construct a new AbsTime and assign it, viz: * * AbsTime when = AbsTime::now(); * ... @@ -53,32 +67,35 @@ class Duration; * * int64_t ns = Duration(now); * - * However note that the nanosecond value that is returned here is not defined to be - * anything in particular and could vary from platform to platform. + * However note that the nanosecond value that is returned here is not + * defined to be anything in particular and could vary from platform to + * platform. * - * There are some sensible operations that are currently missing from AbsTime, but - * nearly all that's needed can be done with a mixture of AbsTimes and Durations. + * There are some sensible operations that are currently missing from + * AbsTime, but nearly all that's needed can be done with a mixture of + * AbsTimes and Durations. * - * For example, convenience operators to add a Duration and AbsTime returning an AbsTime - * would fit here (although you can already perform the operation with one of the AbsTime - * constructors). However trying to add 2 AbsTimes doesn't make sense. + * For example, convenience operators to add a Duration and AbsTime returning + * an AbsTime would fit here (although you can already perform the operation + * with one of the AbsTime constructors). However trying to add 2 AbsTimes + * doesn't make sense. */ class AbsTime { - static int64_t max() { return std::numeric_limits<int64_t>::max(); } - int64_t time_ns; - friend class Duration; + + TimePrivate timepoint; public: inline AbsTime() {} - inline AbsTime(const AbsTime& time0, const Duration& duration); + AbsTime(const AbsTime& time0, const Duration& duration); // Default assignment operation fine // Default copy constructor fine static AbsTime now(); - inline static AbsTime FarFuture(); - bool operator==(const AbsTime& t) const { return t.time_ns == time_ns; } - template <class S> void serialize(S& s) { s(time_ns); } + static AbsTime FarFuture(); + const TimePrivate& getPrivate(void) const { return timepoint; } + bool operator==(const AbsTime& t) const { return t.timepoint == timepoint; } + template <class S> void serialize(S& s) { s(timepoint); } friend bool operator<(const AbsTime& a, const AbsTime& b); friend bool operator>(const AbsTime& a, const AbsTime& b); @@ -87,11 +104,14 @@ public: std::ostream& operator << (std::ostream&, const AbsTime&); -/** Class to represent the duration between instants of time: - * As AbsTime this class also uses nanosecs for its time - * resolution. For the most part a duration can be dealt with like a - * 64 bit integer, and indeed there is an implicit conversion which - * makes this quite conveient. +/** + * @class Duration + * Class to represent the duration between instants of time. + * + * As AbsTime, this class also uses nanosecs for its time + * resolution where possible. For the most part a duration can be dealt + * with like a 64 bit integer, and indeed there is an implicit conversion which + * makes this quite convenient. */ class Duration { static int64_t max() { return std::numeric_limits<int64_t>::max(); } @@ -101,36 +121,24 @@ class Duration { public: inline Duration(int64_t time0); - inline explicit Duration(const AbsTime& time0); - inline explicit Duration(const AbsTime& start, const AbsTime& finish); + explicit Duration(const AbsTime& time0); + explicit Duration(const AbsTime& start, const AbsTime& finish); inline operator int64_t() const; }; std::ostream& operator << (std::ostream&, const Duration&); -AbsTime::AbsTime(const AbsTime& t, const Duration& d) : - time_ns(d == Duration::max() ? max() : t.time_ns+d.nanosecs) -{} - -AbsTime AbsTime::FarFuture() { AbsTime ff; ff.time_ns = max(); return ff;} - inline AbsTime now() { return AbsTime::now(); } -inline bool operator<(const AbsTime& a, const AbsTime& b) { return a.time_ns < b.time_ns; } -inline bool operator>(const AbsTime& a, const AbsTime& b) { return a.time_ns > b.time_ns; } +inline bool operator<(const AbsTime& a, const AbsTime& b) +{ return a.timepoint < b.timepoint; } +inline bool operator>(const AbsTime& a, const AbsTime& b) +{ return a.timepoint > b.timepoint; } Duration::Duration(int64_t time0) : nanosecs(time0) {} -Duration::Duration(const AbsTime& time0) : - nanosecs(time0.time_ns) -{} - -Duration::Duration(const AbsTime& start, const AbsTime& finish) : - nanosecs(finish.time_ns - start.time_ns) -{} - Duration::operator int64_t() const { return nanosecs; } @@ -148,6 +156,12 @@ const Duration TIME_INFINITE = std::numeric_limits<int64_t>::max(); /** Time greater than any other time */ const AbsTime FAR_FUTURE = AbsTime::FarFuture(); + +/** Portable sleep for a number of seconds */ +void sleep(int secs); + +/** Portable sleep for a number of microseconds */ +void usleep(uint64_t usecs); }} diff --git a/cpp/src/qpid/sys/posix/Time.cpp b/cpp/src/qpid/sys/posix/Time.cpp index 8aa9fd9946..d8d0a58d2e 100644 --- a/cpp/src/qpid/sys/posix/Time.cpp +++ b/cpp/src/qpid/sys/posix/Time.cpp @@ -26,18 +26,39 @@ #include <time.h> #include <stdio.h> #include <sys/time.h> +#include <unistd.h> + +namespace { +int64_t max_abstime() { return std::numeric_limits<int64_t>::max(); } +} namespace qpid { namespace sys { +AbsTime::AbsTime(const AbsTime& t, const Duration& d) : + timepoint(d == Duration::max() ? max_abstime() : t.timepoint+d.nanosecs) +{} + +AbsTime AbsTime::FarFuture() { + AbsTime ff; ff.timepoint = max_abstime(); return ff; +} + AbsTime AbsTime::now() { struct timespec ts; ::clock_gettime(CLOCK_REALTIME, &ts); AbsTime time_now; - time_now.time_ns = toTime(ts).nanosecs; + time_now.timepoint = toTime(ts).nanosecs; return time_now; } +Duration::Duration(const AbsTime& time0) : + nanosecs(time0.timepoint) +{} + +Duration::Duration(const AbsTime& start, const AbsTime& finish) : + nanosecs(finish.timepoint - start.timepoint) +{} + struct timespec& toTimespec(struct timespec& ts, const Duration& t) { ts.tv_sec = t / TIME_SEC; ts.tv_nsec = t % TIME_SEC; @@ -63,7 +84,7 @@ std::ostream& operator<<(std::ostream& o, const AbsTime& t) { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" }; struct tm * timeinfo; - time_t rawtime(t.time_ns/TIME_SEC); + time_t rawtime(t.timepoint/TIME_SEC); timeinfo = localtime (&rawtime); char time_string[100]; sprintf ( time_string, @@ -78,5 +99,12 @@ std::ostream& operator<<(std::ostream& o, const AbsTime& t) { return o << time_string; } -}} +void sleep(int secs) { + ::sleep(secs); +} +void usleep(uint64_t usecs) { + ::usleep(usecs); +} + +}} diff --git a/cpp/src/qpid/sys/posix/Time.h b/cpp/src/qpid/sys/posix/Time.h new file mode 100755 index 0000000000..62d734c816 --- /dev/null +++ b/cpp/src/qpid/sys/posix/Time.h @@ -0,0 +1,34 @@ +#ifndef QPID_SYS_POSIX_TIME_H +#define QPID_SYS_POSIX_TIME_H + +/* + * + * Copyright (c) 2006 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "qpid/sys/IntegerTypes.h" + +namespace qpid { +namespace sys { + +/** + * Class to represent an instant in time. + */ +typedef int64_t TimePrivate; + +}} // namespace qpid::sys + +#endif /*!QPID_SYS_POSIX_TIME_H*/ diff --git a/cpp/src/tests/latencytest.cpp b/cpp/src/tests/latencytest.cpp index a980a43322..763ce5a85a 100644 --- a/cpp/src/tests/latencytest.cpp +++ b/cpp/src/tests/latencytest.cpp @@ -26,13 +26,13 @@ #include <memory> #include <sstream> #include <vector> -#include <unistd.h> #include "TestOptions.h" #include "qpid/client/Connection.h" #include "qpid/client/Message.h" #include "qpid/client/AsyncSession.h" #include "qpid/client/SubscriptionManager.h" +#include "qpid/sys/Time.h" using namespace qpid; using namespace qpid::client; @@ -342,7 +342,7 @@ void Sender::sendByRate() uint64_t timeTaken = (now - start_msg) / TIME_USEC; if (timeTaken < interval) { - usleep(interval - timeTaken); + qpid::sys::usleep(interval - timeTaken); } else if (timeTaken > interval && !opts.csv && !opts.cumulative) { // Don't be so verbose in this case, we're piping the results to another program std::cout << "Could not achieve desired rate! (Took " << timeTaken @@ -411,7 +411,7 @@ int main(int argc, char** argv) } if (opts.rate && !opts.timeLimit) { while (true) { - usleep(opts.reportFrequency * 1000); + qpid::sys::usleep(opts.reportFrequency * 1000); //print latency report: for (boost::ptr_vector<Test>::iterator i = tests.begin(); i != tests.end(); i++) { i->report(); |