blob: ba070b62ef17f891e9bcddebb2715fcf3862402d [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Mark Sleef5f2be42006-09-05 21:05:31 +000020#ifndef _THRIFT_CONCURRENCY_UTIL_H_
21#define _THRIFT_CONCURRENCY_UTIL_H_ 1
Marc Slemko0e53ccd2006-07-17 23:51:05 +000022
23#include <assert.h>
Marc Slemko03dedd92006-07-20 00:58:47 +000024#include <stddef.h>
David Reiss53f18f02008-07-11 00:45:29 +000025#include <stdint.h>
Marc Slemkoe6889de2006-08-12 00:32:53 +000026#include <time.h>
Roger Meier2fa9c312011-09-05 19:15:53 +000027
28#ifdef HAVE_SYS_TIME_H
Marc Slemkod42a2c22006-08-10 03:30:18 +000029#include <sys/time.h>
Roger Meier2fa9c312011-09-05 19:15:53 +000030#endif
Marc Slemko0e53ccd2006-07-17 23:51:05 +000031
Roger Meier7158d332013-06-29 12:48:05 +020032#include <thrift/transport/PlatformSocket.h>
33
Konrad Grochowski16a23a62014-11-13 15:33:38 +010034namespace apache {
35namespace thrift {
36namespace concurrency {
Marc Slemko0e53ccd2006-07-17 23:51:05 +000037
Mark Sleef5f2be42006-09-05 21:05:31 +000038/**
39 * Utility methods
40 *
41 * This class contains basic utility methods for converting time formats,
42 * and other common platform-dependent concurrency operations.
43 * It should not be included in API headers for other concurrency library
44 * headers, since it will, by definition, pull in all sorts of horrid
David Reiss3bb5e052010-01-25 19:31:31 +000045 * platform dependent stuff. Rather it should be inluded directly in
Mark Sleef5f2be42006-09-05 21:05:31 +000046 * concurrency library implementation source.
47 *
Mark Sleef5f2be42006-09-05 21:05:31 +000048 * @version $Id:$
49 */
Marc Slemko0e53ccd2006-07-17 23:51:05 +000050class Util {
51
Mark Slee9b82d272007-05-23 05:16:07 +000052 static const int64_t NS_PER_S = 1000000000LL;
David Reiss631dcb42008-03-05 07:51:40 +000053 static const int64_t US_PER_S = 1000000LL;
Mark Slee9b82d272007-05-23 05:16:07 +000054 static const int64_t MS_PER_S = 1000LL;
David Reiss631dcb42008-03-05 07:51:40 +000055
56 static const int64_t NS_PER_MS = NS_PER_S / MS_PER_S;
David Reiss7a2065d2010-03-09 05:20:04 +000057 static const int64_t NS_PER_US = NS_PER_S / US_PER_S;
David Reiss631dcb42008-03-05 07:51:40 +000058 static const int64_t US_PER_MS = US_PER_S / MS_PER_S;
Marc Slemkoc7782972006-07-25 02:26:35 +000059
Konrad Grochowski16a23a62014-11-13 15:33:38 +010060public:
Mark Sleef5f2be42006-09-05 21:05:31 +000061 /**
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -040062 * Converts millisecond timestamp into a THRIFT_TIMESPEC struct
Mark Sleef5f2be42006-09-05 21:05:31 +000063 *
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -040064 * @param struct THRIFT_TIMESPEC& result
Mark Sleef5f2be42006-09-05 21:05:31 +000065 * @param time or duration in milliseconds
66 */
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -040067 static void toTimespec(struct THRIFT_TIMESPEC& result, int64_t value) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010068 result.tv_sec = value / MS_PER_S; // ms to s
Marc Slemkoc7782972006-07-25 02:26:35 +000069 result.tv_nsec = (value % MS_PER_S) * NS_PER_MS; // ms to ns
Marc Slemko0e53ccd2006-07-17 23:51:05 +000070 }
71
David Reiss631dcb42008-03-05 07:51:40 +000072 static void toTimeval(struct timeval& result, int64_t value) {
Konrad Grochowski16a23a62014-11-13 15:33:38 +010073 result.tv_sec = static_cast<uint32_t>(value / MS_PER_S); // ms to s
Roger Meier82525772012-11-16 00:38:27 +000074 result.tv_usec = static_cast<uint32_t>((value % MS_PER_S) * US_PER_MS); // ms to us
David Reiss631dcb42008-03-05 07:51:40 +000075 }
76
Konrad Grochowski16a23a62014-11-13 15:33:38 +010077 static void toTicks(int64_t& result,
78 int64_t secs,
79 int64_t oldTicks,
80 int64_t oldTicksPerSec,
81 int64_t newTicksPerSec) {
David Reiss7a2065d2010-03-09 05:20:04 +000082 result = secs * newTicksPerSec;
83 result += oldTicks * newTicksPerSec / oldTicksPerSec;
84
85 int64_t oldPerNew = oldTicksPerSec / newTicksPerSec;
86 if (oldPerNew && ((oldTicks % oldPerNew) >= (oldPerNew / 2))) {
87 ++result;
88 }
89 }
90 /**
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -040091 * Converts struct THRIFT_TIMESPEC to arbitrary-sized ticks since epoch
David Reiss7a2065d2010-03-09 05:20:04 +000092 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +010093 static void toTicks(int64_t& result, const struct THRIFT_TIMESPEC& value, int64_t ticksPerSec) {
David Reiss7a2065d2010-03-09 05:20:04 +000094 return toTicks(result, value.tv_sec, value.tv_nsec, NS_PER_S, ticksPerSec);
95 }
96
97 /**
98 * Converts struct timeval to arbitrary-sized ticks since epoch
99 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100100 static void toTicks(int64_t& result, const struct timeval& value, int64_t ticksPerSec) {
David Reiss7a2065d2010-03-09 05:20:04 +0000101 return toTicks(result, value.tv_sec, value.tv_usec, US_PER_S, ticksPerSec);
102 }
103
Mark Sleef5f2be42006-09-05 21:05:31 +0000104 /**
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -0400105 * Converts struct THRIFT_TIMESPEC to milliseconds
Mark Sleef5f2be42006-09-05 21:05:31 +0000106 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100107 static void toMilliseconds(int64_t& result, const struct THRIFT_TIMESPEC& value) {
David Reiss7a2065d2010-03-09 05:20:04 +0000108 return toTicks(result, value, MS_PER_S);
David Reiss631dcb42008-03-05 07:51:40 +0000109 }
110
111 /**
112 * Converts struct timeval to milliseconds
113 */
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100114 static void toMilliseconds(int64_t& result, const struct timeval& value) {
David Reiss7a2065d2010-03-09 05:20:04 +0000115 return toTicks(result, value, MS_PER_S);
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000116 }
117
Mark Sleef5f2be42006-09-05 21:05:31 +0000118 /**
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -0400119 * Converts struct THRIFT_TIMESPEC to microseconds
David Reiss7a2065d2010-03-09 05:20:04 +0000120 */
Carl Yeksigian7cb7fc82013-06-07 07:33:01 -0400121 static void toUsec(int64_t& result, const struct THRIFT_TIMESPEC& value) {
David Reiss7a2065d2010-03-09 05:20:04 +0000122 return toTicks(result, value, US_PER_S);
123 }
124
125 /**
126 * Converts struct timeval to microseconds
127 */
Roger Meier3b771a12010-11-17 22:11:26 +0000128 static void toUsec(int64_t& result, const struct timeval& value) {
David Reiss7a2065d2010-03-09 05:20:04 +0000129 return toTicks(result, value, US_PER_S);
130 }
131
132 /**
133 * Get current time as a number of arbitrary-size ticks from epoch
134 */
Roger Meier3b771a12010-11-17 22:11:26 +0000135 static int64_t currentTimeTicks(int64_t ticksPerSec);
David Reiss7a2065d2010-03-09 05:20:04 +0000136
137 /**
Mark Sleef5f2be42006-09-05 21:05:31 +0000138 * Get current time as milliseconds from epoch
139 */
Roger Meier3b771a12010-11-17 22:11:26 +0000140 static int64_t currentTime() { return currentTimeTicks(MS_PER_S); }
David Reiss7a2065d2010-03-09 05:20:04 +0000141
142 /**
143 * Get current time as micros from epoch
144 */
Roger Meier3b771a12010-11-17 22:11:26 +0000145 static int64_t currentTimeUsec() { return currentTimeTicks(US_PER_S); }
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000146};
Konrad Grochowski16a23a62014-11-13 15:33:38 +0100147}
148}
149} // apache::thrift::concurrency
Marc Slemko0e53ccd2006-07-17 23:51:05 +0000150
Mark Sleef5f2be42006-09-05 21:05:31 +0000151#endif // #ifndef _THRIFT_CONCURRENCY_UTIL_H_