blob: 4031be0917128c2701b948b442f453fc4d142cc5 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Mark Sleef5f2be42006-09-05 21:05:31 +00007#ifndef _THRIFT_CONCURRENCY_UTIL_H_
8#define _THRIFT_CONCURRENCY_UTIL_H_ 1
Marc Slemko0e53ccd2006-07-17 23:51:05 +00009
Mark Sleea8de4892008-02-09 00:02:26 +000010#ifdef HAVE_CONFIG_H
Marc Slemkoc7782972006-07-25 02:26:35 +000011#include <config.h>
Mark Sleea8de4892008-02-09 00:02:26 +000012#endif
Marc Slemkoc7782972006-07-25 02:26:35 +000013
Marc Slemko0e53ccd2006-07-17 23:51:05 +000014#include <assert.h>
Marc Slemko03dedd92006-07-20 00:58:47 +000015#include <stddef.h>
Marc Slemkoe6889de2006-08-12 00:32:53 +000016#if defined(HAVE_CLOCK_GETTIME)
17#include <time.h>
18#else // defined(HAVE_CLOCK_GETTIME)
Marc Slemkod42a2c22006-08-10 03:30:18 +000019#include <sys/time.h>
Marc Slemkoe6889de2006-08-12 00:32:53 +000020#endif // defined(HAVE_CLOCK_GETTIME)
Marc Slemko0e53ccd2006-07-17 23:51:05 +000021
David Reiss0c90f6f2008-02-06 22:18:40 +000022namespace facebook { namespace thrift { namespace concurrency {
Marc Slemko0e53ccd2006-07-17 23:51:05 +000023
Mark Sleef5f2be42006-09-05 21:05:31 +000024/**
25 * Utility methods
26 *
27 * This class contains basic utility methods for converting time formats,
28 * and other common platform-dependent concurrency operations.
29 * It should not be included in API headers for other concurrency library
30 * headers, since it will, by definition, pull in all sorts of horrid
David Reiss0c90f6f2008-02-06 22:18:40 +000031 * platform dependent crap. Rather it should be inluded directly in
Mark Sleef5f2be42006-09-05 21:05:31 +000032 * concurrency library implementation source.
33 *
34 * @author marc
35 * @version $Id:$
36 */
Marc Slemko0e53ccd2006-07-17 23:51:05 +000037class Util {
38
Mark Slee9b82d272007-05-23 05:16:07 +000039 static const int64_t NS_PER_S = 1000000000LL;
David Reiss631dcb42008-03-05 07:51:40 +000040 static const int64_t US_PER_S = 1000000LL;
Mark Slee9b82d272007-05-23 05:16:07 +000041 static const int64_t MS_PER_S = 1000LL;
David Reiss631dcb42008-03-05 07:51:40 +000042
43 static const int64_t NS_PER_MS = NS_PER_S / MS_PER_S;
44 static const int64_t US_PER_MS = US_PER_S / MS_PER_S;
Marc Slemkoc7782972006-07-25 02:26:35 +000045
Marc Slemko0e53ccd2006-07-17 23:51:05 +000046 public:
47
Mark Sleef5f2be42006-09-05 21:05:31 +000048 /**
David Reiss631dcb42008-03-05 07:51:40 +000049 * Converts millisecond timestamp into a timespec struct
Mark Sleef5f2be42006-09-05 21:05:31 +000050 *
51 * @param struct timespec& result
52 * @param time or duration in milliseconds
53 */
Mark Slee9b82d272007-05-23 05:16:07 +000054 static void toTimespec(struct timespec& result, int64_t value) {
David Reiss0c90f6f2008-02-06 22:18:40 +000055 result.tv_sec = value / MS_PER_S; // ms to s
Marc Slemkoc7782972006-07-25 02:26:35 +000056 result.tv_nsec = (value % MS_PER_S) * NS_PER_MS; // ms to ns
Marc Slemko0e53ccd2006-07-17 23:51:05 +000057 }
58
David Reiss631dcb42008-03-05 07:51:40 +000059 static void toTimeval(struct timeval& result, int64_t value) {
60 result.tv_sec = value / MS_PER_S; // ms to s
61 result.tv_usec = (value % MS_PER_S) * US_PER_MS; // ms to us
62 }
63
Mark Sleef5f2be42006-09-05 21:05:31 +000064 /**
David Reiss631dcb42008-03-05 07:51:40 +000065 * Converts struct timespec to milliseconds
Mark Sleef5f2be42006-09-05 21:05:31 +000066 */
Mark Slee9b82d272007-05-23 05:16:07 +000067 static const void toMilliseconds(int64_t& result, const struct timespec& value) {
David Reiss631dcb42008-03-05 07:51:40 +000068 result = (value.tv_sec * MS_PER_S) + (value.tv_nsec / NS_PER_MS);
69 // round up -- int64_t cast is to avoid a compiler error for some GCCs
70 if (int64_t(value.tv_nsec) % NS_PER_MS >= (NS_PER_MS / 2)) {
71 ++result;
72 }
73 }
74
75 /**
76 * Converts struct timeval to milliseconds
77 */
78 static const void toMilliseconds(int64_t& result, const struct timeval& value) {
79 result = (value.tv_sec * MS_PER_S) + (value.tv_usec / US_PER_MS);
80 // round up -- int64_t cast is to avoid a compiler error for some GCCs
81 if (int64_t(value.tv_usec) % US_PER_MS >= (US_PER_MS / 2)) {
82 ++result;
83 }
Marc Slemko0e53ccd2006-07-17 23:51:05 +000084 }
85
Mark Sleef5f2be42006-09-05 21:05:31 +000086 /**
87 * Get current time as milliseconds from epoch
88 */
Mark Slee9b82d272007-05-23 05:16:07 +000089 static const int64_t currentTime() {
David Reiss631dcb42008-03-05 07:51:40 +000090 int64_t result;
91
Marc Slemkoc7782972006-07-25 02:26:35 +000092#if defined(HAVE_CLOCK_GETTIME)
Marc Slemkoc7782972006-07-25 02:26:35 +000093 struct timespec now;
Aditya Agarwal9dc57402007-03-31 17:45:12 +000094 int ret = clock_gettime(CLOCK_REALTIME, &now);
Aditya Agarwal3f234da2007-04-01 01:19:57 +000095 assert(ret == 0);
David Reiss631dcb42008-03-05 07:51:40 +000096 toMilliseconds(result, now);
Marc Slemkoc7782972006-07-25 02:26:35 +000097#elif defined(HAVE_GETTIMEOFDAY)
Marc Slemko9f27a4e2006-07-19 20:02:22 +000098 struct timeval now;
Aditya Agarwal9dc57402007-03-31 17:45:12 +000099 int ret = gettimeofday(&now, NULL);
Aditya Agarwal3f234da2007-04-01 01:19:57 +0000100 assert(ret == 0);
David Reiss631dcb42008-03-05 07:51:40 +0000101 toMilliseconds(result, now);
Marc Slemkoc7782972006-07-25 02:26:35 +0000102#endif // defined(HAVE_GETTIMEDAY)
David Reiss631dcb42008-03-05 07:51:40 +0000103
104 return result;
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000105 }
Mark Sleef5f2be42006-09-05 21:05:31 +0000106
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000107};
108
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000109}}} // facebook::thrift::concurrency
110
Mark Sleef5f2be42006-09-05 21:05:31 +0000111#endif // #ifndef _THRIFT_CONCURRENCY_UTIL_H_