1
/* $Id: os_timestamp_posix.c 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27
#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0
30
# if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \
31
defined(_POSIX_MONOTONIC_CLOCK)
32
# define USE_POSIX_TIMERS 1
37
#if defined(PJ_HAS_PENTIUM) && PJ_HAS_PENTIUM!=0 && \
38
defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \
39
defined(PJ_M_I386) && PJ_M_I386!=0 && \
40
defined(PJ_LINUX) && PJ_LINUX!=0
41
static int machine_speed_mhz;
42
static pj_timestamp machine_speed;
44
static __inline__ unsigned long long int rdtsc()
46
unsigned long long int x;
47
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
51
/* Determine machine's CPU MHz to get the counter's frequency.
53
static int get_machine_speed_mhz()
62
/* Open /proc/cpuinfo and read the file */
63
strm = fopen("/proc/cpuinfo", "r");
66
len = fread(buf, 1, sizeof(buf), strm);
73
/* Locate the MHz digit. */
74
pos = strstr(buf, "cpu MHz");
77
pos = strchr(pos, ':');
81
while (isdigit(*end)) ++end;
84
/* Return the Mhz part, and give it a +1. */
88
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
90
if (machine_speed_mhz == 0) {
91
machine_speed_mhz = get_machine_speed_mhz();
92
if (machine_speed_mhz > 0) {
93
machine_speed.u64 = machine_speed_mhz * 1000000.0;
97
if (machine_speed_mhz == -1) {
105
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
107
if (machine_speed_mhz == 0) {
108
machine_speed_mhz = get_machine_speed_mhz();
109
if (machine_speed_mhz > 0) {
110
machine_speed.u64 = machine_speed_mhz * 1000000.0;
114
if (machine_speed_mhz == -1) {
115
freq->u64 = 1; /* return 1 to prevent division by zero in apps. */
119
freq->u64 = machine_speed.u64;
123
#elif defined(PJ_DARWINOS) && PJ_DARWINOS != 0
124
#include <mach/mach.h>
125
#include <mach/clock.h>
128
#define NSEC_PER_SEC 1000000000
130
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
136
ret = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &serv);
137
if (ret != KERN_SUCCESS) {
138
return PJ_RETURN_OS_ERROR(EINVAL);
141
ret = clock_get_time(serv, &tp);
142
if (ret != KERN_SUCCESS) {
143
return PJ_RETURN_OS_ERROR(EINVAL);
147
ts->u64 *= NSEC_PER_SEC;
148
ts->u64 += tp.tv_nsec;
153
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
156
freq->u32.lo = NSEC_PER_SEC;
161
#elif defined(USE_POSIX_TIMERS) && USE_POSIX_TIMERS != 0
162
#include <sys/time.h>
166
#define NSEC_PER_SEC 1000000000
168
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
172
if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
173
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
177
ts->u64 *= NSEC_PER_SEC;
178
ts->u64 += tp.tv_nsec;
183
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
186
freq->u32.lo = NSEC_PER_SEC;
192
#include <sys/time.h>
195
#define USEC_PER_SEC 1000000
197
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
201
if (gettimeofday(&tv, NULL) != 0) {
202
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
206
ts->u64 *= USEC_PER_SEC;
207
ts->u64 += tv.tv_usec;
212
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
215
freq->u32.lo = USEC_PER_SEC;