From 9f63f4d2b57d517f7b731ab22d2be5fe52599c5e Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 15 Oct 2013 11:43:00 -0700 Subject: [PATCH 1/5] move timespec funcs into unix.cc --- include/serial/impl/unix-timespec.h | 131 ---------------------------- src/impl/unix.cc | 101 ++++++++++++++++++++- 2 files changed, 99 insertions(+), 133 deletions(-) delete mode 100644 include/serial/impl/unix-timespec.h diff --git a/include/serial/impl/unix-timespec.h b/include/serial/impl/unix-timespec.h deleted file mode 100644 index 7fcf08b..0000000 --- a/include/serial/impl/unix-timespec.h +++ /dev/null @@ -1,131 +0,0 @@ -/*! - * \file serial/impl/unit-timespec.h - * \author Mike Purvis - * \version 0.1 - * - * \section LICENSE - * - * The MIT License - * - * Copyright (c) 2013 William Woodall - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * \section DESCRIPTION - * - * Provides helper and operator functions for concisely and reliably handling - * timespec instances on unix platforms. - */ - -#ifndef SERIAL_IMPL_UNIX_TIMESPEC_H -#define SERIAL_IMPL_UNIX_TIMESPEC_H - -#include - -/*! Smooth over platform variances in getting an accurate timespec - * representing the present moment. */ -static inline struct timespec -timespec_now () -{ - struct timespec ts; -# ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - ts.tv_sec = mts.tv_sec; - ts.tv_nsec = mts.tv_nsec; -# else - clock_gettime(CLOCK_REALTIME, &ts); -# endif - return ts; -} - -/*! Simple function to normalize the tv_nsec field to [0..1e9), carrying - * the remainder into the tv_sec field. This will not protect against the - * possibility of an overflow in the nsec field--proceed with caution. */ -static inline void -normalize(struct timespec* ts) { - while (ts->tv_nsec < 0) { - ts->tv_nsec += 1e9; - ts->tv_sec -= 1; - } - while (ts->tv_nsec >= 1e9) { - ts->tv_nsec -= 1e9; - ts->tv_sec += 1; - } -} - -/*! Return a timespec which is the sum of two other timespecs. This - * operator only makes logical sense when one or both of the arguments - * represents a duration. */ -static inline timespec -operator+ (const struct timespec &a, const struct timespec &b) { - struct timespec result = { a.tv_sec + b.tv_sec, - a.tv_nsec + b.tv_nsec }; - normalize(&result); - return result; -} - -/*! Return a timespec which is the difference of two other timespecs. - * This operator only makes logical sense when one or both of the arguments - * represents a duration. */ -static inline timespec -operator- (const struct timespec &a, const struct timespec &b) { - struct timespec result = { a.tv_sec - b.tv_sec, - a.tv_nsec - b.tv_nsec }; - normalize(&result); - return result; -} - -/*! Return a timespec which is a multiplication of a timespec and a positive - * integer. No overflow protection-- not suitable for multiplications with - * large carries, eg a <1s timespec multiplied by a large enough integer - * that the result is muliple seconds. Only makes sense when the timespec - * argument is a duration. */ -static inline timespec -operator* (const struct timespec &ts, const size_t mul) { - struct timespec result = { ts.tv_sec * mul, - ts.tv_nsec * mul }; - normalize(&result); - return result; -} - -/*! Return whichever of two timespec durations represents the shortest or most - * negative period. */ -static inline struct timespec -min (const struct timespec &a, const struct timespec &b) { - if (a.tv_sec < b.tv_sec - || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) { - return a; - } else { - return b; - } -} - -/*! Return a timespec duration set from a provided number of milliseconds. */ -static struct timespec -timespec_from_millis(const size_t millis) { - struct timespec result = { 0, millis * 1000000 }; - normalize(&result); - return result; -} - -#endif diff --git a/src/impl/unix.cc b/src/impl/unix.cc index d4f1b83..0ab52f5 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -1,4 +1,8 @@ -/* Copyright 2012 William Woodall and John Harrison */ +/* Copyright 2012 William Woodall and John Harrison + * + * Additional authors: + * - Mike Purvis, Clearpath Robotics, @mikepurvis + */ #include #include @@ -27,7 +31,6 @@ #endif #include "serial/impl/unix.h" -#include "serial/impl/unix-timespec.h" #ifndef TIOCINQ #ifdef FIONREAD @@ -49,6 +52,100 @@ using serial::SerialException; using serial::PortNotOpenedException; using serial::IOException; +/* Timespec related functions provided by @mikepurvis of Clearpath Robotics */ + +/*! Smooth over platform variances in getting an accurate timespec + * representing the present moment. */ +static inline struct timespec +timespec_now () +{ + struct timespec ts; +# ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts.tv_sec = mts.tv_sec; + ts.tv_nsec = mts.tv_nsec; +# else + clock_gettime(CLOCK_REALTIME, &ts); +# endif + return ts; +} + +/*! Simple function to normalize the tv_nsec field to [0..1e9), carrying + * the remainder into the tv_sec field. This will not protect against the + * possibility of an overflow in the nsec field--proceed with caution. */ +static inline void +normalize(struct timespec* ts) { + while (ts->tv_nsec < 0) { + ts->tv_nsec += 1e9; + ts->tv_sec -= 1; + } + while (ts->tv_nsec >= 1e9) { + ts->tv_nsec -= 1e9; + ts->tv_sec += 1; + } +} + +/*! Return a timespec which is the sum of two other timespecs. This + * operator only makes logical sense when one or both of the arguments + * represents a duration. */ +static inline timespec +operator+ (const struct timespec &a, const struct timespec &b) { + struct timespec result = { a.tv_sec + b.tv_sec, + a.tv_nsec + b.tv_nsec }; + normalize(&result); + return result; +} + +/*! Return a timespec which is the difference of two other timespecs. + * This operator only makes logical sense when one or both of the arguments + * represents a duration. */ +static inline timespec +operator- (const struct timespec &a, const struct timespec &b) { + struct timespec result = { a.tv_sec - b.tv_sec, + a.tv_nsec - b.tv_nsec }; + normalize(&result); + return result; +} + +/*! Return a timespec which is a multiplication of a timespec and a positive + * integer. No overflow protection-- not suitable for multiplications with + * large carries, eg a <1s timespec multiplied by a large enough integer + * that the result is muliple seconds. Only makes sense when the timespec + * argument is a duration. */ +static inline timespec +operator* (const struct timespec &ts, const size_t mul) { + struct timespec result = { ts.tv_sec * mul, + ts.tv_nsec * mul }; + normalize(&result); + return result; +} + +/*! Return whichever of two timespec durations represents the shortest or most + * negative period. */ +static inline struct timespec +min (const struct timespec &a, const struct timespec &b) { + if (a.tv_sec < b.tv_sec + || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) { + return a; + } else { + return b; + } +} + +/*! Return a timespec duration set from a provided number of milliseconds. */ +static struct timespec +timespec_from_millis(const size_t millis) { + struct timespec result = { 0, millis * 1000000 }; + normalize(&result); + return result; +} + +/* End timespec related functions */ + Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate, bytesize_t bytesize, From 282b79efc65edf1d37eb6362d9236365214a12cb Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 15 Oct 2013 11:45:53 -0700 Subject: [PATCH 2/5] style changes to new/old timespec functions --- src/impl/unix.cc | 75 ++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/src/impl/unix.cc b/src/impl/unix.cc index 0ab52f5..da2bfb7 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -54,13 +54,13 @@ using serial::IOException; /* Timespec related functions provided by @mikepurvis of Clearpath Robotics */ -/*! Smooth over platform variances in getting an accurate timespec +/* Smooth over platform variances in getting an accurate timespec * representing the present moment. */ static inline struct timespec timespec_now () { struct timespec ts; -# ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time +#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); @@ -68,78 +68,91 @@ timespec_now () mach_port_deallocate(mach_task_self(), cclock); ts.tv_sec = mts.tv_sec; ts.tv_nsec = mts.tv_nsec; -# else +#else clock_gettime(CLOCK_REALTIME, &ts); -# endif +#endif return ts; } -/*! Simple function to normalize the tv_nsec field to [0..1e9), carrying +/* Simple function to normalize the tv_nsec field to [0..1e9), carrying * the remainder into the tv_sec field. This will not protect against the * possibility of an overflow in the nsec field--proceed with caution. */ static inline void -normalize(struct timespec* ts) { - while (ts->tv_nsec < 0) { +normalize (struct timespec* ts) +{ + while (ts->tv_nsec < 0) + { ts->tv_nsec += 1e9; ts->tv_sec -= 1; } - while (ts->tv_nsec >= 1e9) { + while (ts->tv_nsec >= 1e9) + { ts->tv_nsec -= 1e9; ts->tv_sec += 1; } } -/*! Return a timespec which is the sum of two other timespecs. This +/* Return a timespec which is the sum of two other timespecs. This * operator only makes logical sense when one or both of the arguments * represents a duration. */ static inline timespec -operator+ (const struct timespec &a, const struct timespec &b) { - struct timespec result = { a.tv_sec + b.tv_sec, - a.tv_nsec + b.tv_nsec }; +operator+ (const struct timespec &a, const struct timespec &b) +{ + struct timespec result = { + a.tv_sec + b.tv_sec, + a.tv_nsec + b.tv_nsec + }; normalize(&result); return result; } -/*! Return a timespec which is the difference of two other timespecs. +/* Return a timespec which is the difference of two other timespecs. * This operator only makes logical sense when one or both of the arguments * represents a duration. */ static inline timespec -operator- (const struct timespec &a, const struct timespec &b) { - struct timespec result = { a.tv_sec - b.tv_sec, - a.tv_nsec - b.tv_nsec }; +operator- (const struct timespec &a, const struct timespec &b) +{ + struct timespec result = { + a.tv_sec - b.tv_sec, + a.tv_nsec - b.tv_nsec + }; normalize(&result); return result; } -/*! Return a timespec which is a multiplication of a timespec and a positive - * integer. No overflow protection-- not suitable for multiplications with - * large carries, eg a <1s timespec multiplied by a large enough integer +/* Return a timespec which is a multiplication of a timespec and a positive + * integer. No overflow protection-- not suitable for multiplications with + * large carries, eg a <1s timespec multiplied by a large enough integer * that the result is muliple seconds. Only makes sense when the timespec * argument is a duration. */ static inline timespec -operator* (const struct timespec &ts, const size_t mul) { - struct timespec result = { ts.tv_sec * mul, - ts.tv_nsec * mul }; +operator* (const struct timespec &ts, const size_t mul) +{ + struct timespec result = { + ts.tv_sec * mul, + ts.tv_nsec * mul + }; normalize(&result); return result; } -/*! Return whichever of two timespec durations represents the shortest or most +/* Return whichever of two timespec durations represents the shortest or most * negative period. */ static inline struct timespec -min (const struct timespec &a, const struct timespec &b) { - if (a.tv_sec < b.tv_sec - || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) { +min (const struct timespec &a, const struct timespec &b) +{ + if (a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) + { return a; - } else { - return b; } + return b; } -/*! Return a timespec duration set from a provided number of milliseconds. */ +/* Return a timespec duration set from a provided number of milliseconds. */ static struct timespec -timespec_from_millis(const size_t millis) { - struct timespec result = { 0, millis * 1000000 }; +timespec_from_millis (const size_t millis) +{ + struct timespec result = {0, millis * 1000000}; normalize(&result); return result; } From 17e698ce94e561bb6dfb57fde9cdb4abeb9ed1b2 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 15 Oct 2013 11:47:45 -0700 Subject: [PATCH 3/5] use pass by reference in normalize function --- src/impl/unix.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/impl/unix.cc b/src/impl/unix.cc index da2bfb7..d2ff963 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -78,17 +78,17 @@ timespec_now () * the remainder into the tv_sec field. This will not protect against the * possibility of an overflow in the nsec field--proceed with caution. */ static inline void -normalize (struct timespec* ts) +normalize (struct timespec &ts) { - while (ts->tv_nsec < 0) + while (ts.tv_nsec < 0) { - ts->tv_nsec += 1e9; - ts->tv_sec -= 1; + ts.tv_nsec += 1e9; + ts.tv_sec -= 1; } - while (ts->tv_nsec >= 1e9) + while (ts.tv_nsec >= 1e9) { - ts->tv_nsec -= 1e9; - ts->tv_sec += 1; + ts.tv_nsec -= 1e9; + ts.tv_sec += 1; } } @@ -102,7 +102,7 @@ operator+ (const struct timespec &a, const struct timespec &b) a.tv_sec + b.tv_sec, a.tv_nsec + b.tv_nsec }; - normalize(&result); + normalize(result); return result; } @@ -116,7 +116,7 @@ operator- (const struct timespec &a, const struct timespec &b) a.tv_sec - b.tv_sec, a.tv_nsec - b.tv_nsec }; - normalize(&result); + normalize(result); return result; } @@ -132,7 +132,7 @@ operator* (const struct timespec &ts, const size_t mul) ts.tv_sec * mul, ts.tv_nsec * mul }; - normalize(&result); + normalize(result); return result; } @@ -153,7 +153,7 @@ static struct timespec timespec_from_millis (const size_t millis) { struct timespec result = {0, millis * 1000000}; - normalize(&result); + normalize(result); return result; } From 80a087e606d89b34e755edcfc9412c09e134ac2e Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 15 Oct 2013 11:48:00 -0700 Subject: [PATCH 4/5] use pass by reference in operator* for timespec --- src/impl/unix.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/impl/unix.cc b/src/impl/unix.cc index d2ff963..e6e76aa 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -126,7 +126,7 @@ operator- (const struct timespec &a, const struct timespec &b) * that the result is muliple seconds. Only makes sense when the timespec * argument is a duration. */ static inline timespec -operator* (const struct timespec &ts, const size_t mul) +operator* (const struct timespec &ts, const size_t &mul) { struct timespec result = { ts.tv_sec * mul, From cb4015705baf2d69d996219401bc3e7b375ab296 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Tue, 15 Oct 2013 11:55:29 -0700 Subject: [PATCH 5/5] just use inline, not static or static inline --- src/impl/unix.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/impl/unix.cc b/src/impl/unix.cc index e6e76aa..8f84fb6 100755 --- a/src/impl/unix.cc +++ b/src/impl/unix.cc @@ -77,7 +77,7 @@ timespec_now () /* Simple function to normalize the tv_nsec field to [0..1e9), carrying * the remainder into the tv_sec field. This will not protect against the * possibility of an overflow in the nsec field--proceed with caution. */ -static inline void +inline void normalize (struct timespec &ts) { while (ts.tv_nsec < 0) @@ -95,7 +95,7 @@ normalize (struct timespec &ts) /* Return a timespec which is the sum of two other timespecs. This * operator only makes logical sense when one or both of the arguments * represents a duration. */ -static inline timespec +inline timespec operator+ (const struct timespec &a, const struct timespec &b) { struct timespec result = { @@ -109,7 +109,7 @@ operator+ (const struct timespec &a, const struct timespec &b) /* Return a timespec which is the difference of two other timespecs. * This operator only makes logical sense when one or both of the arguments * represents a duration. */ -static inline timespec +inline timespec operator- (const struct timespec &a, const struct timespec &b) { struct timespec result = { @@ -125,7 +125,7 @@ operator- (const struct timespec &a, const struct timespec &b) * large carries, eg a <1s timespec multiplied by a large enough integer * that the result is muliple seconds. Only makes sense when the timespec * argument is a duration. */ -static inline timespec +inline timespec operator* (const struct timespec &ts, const size_t &mul) { struct timespec result = { @@ -138,7 +138,7 @@ operator* (const struct timespec &ts, const size_t &mul) /* Return whichever of two timespec durations represents the shortest or most * negative period. */ -static inline struct timespec +inline struct timespec min (const struct timespec &a, const struct timespec &b) { if (a.tv_sec < b.tv_sec || (a.tv_sec == b.tv_sec && a.tv_nsec < b.tv_nsec)) @@ -149,7 +149,7 @@ min (const struct timespec &a, const struct timespec &b) } /* Return a timespec duration set from a provided number of milliseconds. */ -static struct timespec +inline struct timespec timespec_from_millis (const size_t millis) { struct timespec result = {0, millis * 1000000};