1 // boost process_cpu_clocks.cpp -----------------------------------------------------------// 2 3 // Copyright Beman Dawes 1994, 2006, 2008 4 // Copyright Vicente J. Botet Escriba 2009 5 6 // Distributed under the Boost Software License, Version 1.0. 7 // See http://www.boost.org/LICENSE_1_0.txt 8 9 // See http://www.boost.org/libs/chrono for documentation. 10 11 //--------------------------------------------------------------------------------------// 12 13 #include <boost/chrono/config.hpp> 14 #include <boost/chrono/process_cpu_clocks.hpp> 15 #include <boost/assert.hpp> 16 17 #include <sys/time.h> //for gettimeofday and timeval 18 #include <sys/times.h> //for times 19 # include <unistd.h> 20 21 namespace boost 22 { 23 namespace chrono 24 { 25 namespace chrono_detail 26 { 27 tick_factor()28 inline long tick_factor() // multiplier to convert ticks 29 // to nanoseconds; -1 if unknown 30 { 31 long factor = 0; 32 if (!factor) 33 { 34 if ((factor = ::sysconf(_SC_CLK_TCK)) <= 0) 35 factor = -1; 36 else 37 { 38 BOOST_ASSERT(factor <= 1000000000l); // doesn't handle large ticks 39 factor = 1000000000l / factor; // compute factor 40 if (!factor) 41 factor = -1; 42 } 43 } 44 return factor; 45 } 46 } 47 48 now()49 process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT 50 { 51 #if 1 52 tms tm; 53 clock_t c = ::times(&tm); 54 if (c == clock_t(-1)) // error 55 { 56 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 57 } else 58 { 59 long factor = chrono_detail::tick_factor(); 60 if (factor != -1) 61 { 62 return time_point(nanoseconds(c * factor)); 63 } else 64 { 65 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 66 } 67 } 68 return time_point(); 69 #else 70 clock_t c = ::clock(); 71 if (c == clock_t(-1)) // error 72 { 73 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 74 } else 75 { 76 long factor = chrono_detail::tick_factor(); 77 if (factor != -1) 78 { 79 return time_point(nanoseconds(c * factor)); 80 } else 81 { 82 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 83 } 84 } 85 return time_point(); 86 #endif 87 } 88 89 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)90 process_real_cpu_clock::time_point process_real_cpu_clock::now(system::error_code & ec) 91 { 92 93 #if 1 94 tms tm; 95 clock_t c = ::times(&tm); 96 if (c == clock_t(-1)) // error 97 { 98 if (::boost::chrono::is_throws(ec)) 99 { 100 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_real_cpu_clock")); 101 } else 102 { 103 ec.assign(errno, ::boost::system::system_category()); 104 return time_point(); 105 } 106 } else 107 { 108 long factor = chrono_detail::tick_factor(); 109 if (factor != -1) 110 { 111 if (!::boost::chrono::is_throws(ec)) 112 { 113 ec.clear(); 114 } 115 return time_point(nanoseconds(c * factor)); 116 } else 117 { 118 if (::boost::chrono::is_throws(ec)) 119 { 120 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_real_cpu_clock")); 121 } else 122 { 123 ec.assign(errno, ::boost::system::system_category()); 124 return time_point(); 125 } 126 } 127 } 128 #else 129 clock_t c = ::clock(); 130 if (c == clock_t(-1)) // error 131 { 132 if (::boost::chrono::is_throws(ec)) 133 { 134 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_real_cpu_clock")); 135 } else 136 { 137 ec.assign(errno, ::boost::system::system_category()); 138 return time_point(); 139 } 140 } else 141 { 142 long factor = chrono_detail::tick_factor(); 143 if (factor != -1) 144 { 145 if (!::boost::chrono::is_throws(ec)) 146 { 147 ec.clear(); 148 } 149 return time_point(nanoseconds(c * factor)); 150 } else 151 { 152 if (::boost::chrono::is_throws(ec)) 153 { 154 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_real_cpu_clock")); 155 } else 156 { 157 ec.assign(errno, ::boost::system::system_category()); 158 return time_point(); 159 } 160 } 161 } 162 #endif 163 164 } 165 #endif 166 167 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)168 process_user_cpu_clock::time_point process_user_cpu_clock::now(system::error_code & ec) 169 { 170 tms tm; 171 clock_t c = ::times(&tm); 172 if (c == clock_t(-1)) // error 173 { 174 if (::boost::chrono::is_throws(ec)) 175 { 176 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_user_cpu_clock")); 177 } else 178 { 179 ec.assign(errno, ::boost::system::system_category()); 180 return time_point(); 181 } 182 } else 183 { 184 long factor = chrono_detail::tick_factor(); 185 if (factor != -1) 186 { 187 if (!::boost::chrono::is_throws(ec)) 188 { 189 ec.clear(); 190 } 191 return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) * factor)); 192 } else 193 { 194 if (::boost::chrono::is_throws(ec)) 195 { 196 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_user_cpu_clock")); 197 } else 198 { 199 ec.assign(errno, ::boost::system::system_category()); 200 return time_point(); 201 } 202 } 203 } 204 } 205 #endif 206 now()207 process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT 208 { 209 tms tm; 210 clock_t c = ::times(&tm); 211 if (c == clock_t(-1)) // error 212 { 213 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 214 } else 215 { 216 long factor = chrono_detail::tick_factor(); 217 if (factor != -1) 218 { 219 return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) 220 * factor)); 221 } else 222 { 223 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 224 } 225 } 226 return time_point(); 227 } now()228 process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT 229 { 230 tms tm; 231 clock_t c = ::times(&tm); 232 if (c == clock_t(-1)) // error 233 { 234 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 235 } else 236 { 237 long factor = chrono_detail::tick_factor(); 238 if (factor != -1) 239 { 240 return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) 241 * factor)); 242 } else 243 { 244 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 245 } 246 } 247 return time_point(); 248 } 249 250 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)251 process_system_cpu_clock::time_point process_system_cpu_clock::now(system::error_code & ec) 252 { 253 tms tm; 254 clock_t c = ::times(&tm); 255 if (c == clock_t(-1)) // error 256 { 257 if (::boost::chrono::is_throws(ec)) 258 { 259 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_system_cpu_clock")); 260 } else 261 { 262 ec.assign(errno, ::boost::system::system_category()); 263 return time_point(); 264 } 265 } else 266 { 267 long factor = chrono_detail::tick_factor(); 268 if (factor != -1) 269 { 270 if (!::boost::chrono::is_throws(ec)) 271 { 272 ec.clear(); 273 } 274 return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) * factor)); 275 } else 276 { 277 if (::boost::chrono::is_throws(ec)) 278 { 279 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_system_cpu_clock")); 280 } else 281 { 282 ec.assign(errno, ::boost::system::system_category()); 283 return time_point(); 284 } 285 } 286 } 287 } 288 #endif 289 now()290 process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT 291 { 292 tms tm; 293 clock_t c = ::times(&tm); 294 if (c == clock_t(-1)) // error 295 { 296 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 297 } else 298 { 299 long factor = chrono_detail::tick_factor(); 300 if (factor != -1) 301 { 302 time_point::rep 303 r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime 304 + tm.tms_cstime) * factor); 305 return time_point(duration(r)); 306 } else 307 { 308 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); 309 } 310 } 311 return time_point(); 312 } 313 314 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING now(system::error_code & ec)315 process_cpu_clock::time_point process_cpu_clock::now(system::error_code & ec) 316 { 317 318 tms tm; 319 clock_t c = ::times(&tm); 320 if (c == clock_t(-1)) // error 321 { 322 if (::boost::chrono::is_throws(ec)) 323 { 324 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_clock")); 325 } else 326 { 327 ec.assign(errno, ::boost::system::system_category()); 328 return time_point(); 329 } 330 } else 331 { 332 long factor = chrono_detail::tick_factor(); 333 if (factor != -1) 334 { 335 time_point::rep 336 r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime 337 + tm.tms_cstime) * factor); 338 return time_point(duration(r)); 339 } else 340 { 341 if (::boost::chrono::is_throws(ec)) 342 { 343 boost::throw_exception(system::system_error(errno, ::boost::system::system_category(), "chrono::process_clock")); 344 } else 345 { 346 ec.assign(errno, ::boost::system::system_category()); 347 return time_point(); 348 } 349 } 350 } 351 352 } 353 #endif 354 355 } 356 } 357