~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject/pjlib/src/pj/os_timestamp_posix.c

  • Committer: Package Import Robot
  • Author(s): Francois Marier
  • Date: 2011-11-25 13:24:12 UTC
  • mfrom: (4.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20111125132412-dc4qvhyosk74cd42
Tags: 1.0.1-4
Don't assume that arch:all packages will get built (closes: #649726)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: os_timestamp_posix.c 3553 2011-05-05 06:14:19Z nanang $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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 
 
19
 */
 
20
#include <pj/os.h>
 
21
#include <pj/errno.h>
 
22
#include <stdio.h>
 
23
#include <string.h>
 
24
#include <stdlib.h>
 
25
#include <ctype.h>
 
26
 
 
27
#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H != 0
 
28
#   include <unistd.h>
 
29
 
 
30
#   if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && \
 
31
       defined(_POSIX_MONOTONIC_CLOCK)
 
32
#       define USE_POSIX_TIMERS 1
 
33
#   endif
 
34
 
 
35
#endif
 
36
 
 
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;
 
43
 
 
44
static __inline__ unsigned long long int rdtsc()
 
45
{
 
46
    unsigned long long int x;
 
47
    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
 
48
    return x;
 
49
}
 
50
 
 
51
/* Determine machine's CPU MHz to get the counter's frequency.
 
52
 */
 
53
static int get_machine_speed_mhz()
 
54
{
 
55
    FILE *strm;
 
56
    char buf[512];
 
57
    int len;
 
58
    char *pos, *end;
 
59
        
 
60
    PJ_CHECK_STACK();
 
61
        
 
62
    /* Open /proc/cpuinfo and read the file */
 
63
    strm = fopen("/proc/cpuinfo", "r");
 
64
    if (!strm)
 
65
        return -1;
 
66
    len = fread(buf, 1, sizeof(buf), strm);
 
67
    fclose(strm);
 
68
    if (len < 1) {
 
69
        return -1;
 
70
    }
 
71
    buf[len] = '\0';
 
72
 
 
73
    /* Locate the MHz digit. */
 
74
    pos = strstr(buf, "cpu MHz");
 
75
    if (!pos)
 
76
        return -1;
 
77
    pos = strchr(pos, ':');
 
78
    if (!pos)
 
79
        return -1;
 
80
    end = (pos += 2);
 
81
    while (isdigit(*end)) ++end;
 
82
    *end = '\0';
 
83
 
 
84
    /* Return the Mhz part, and give it a +1. */
 
85
    return atoi(pos)+1;
 
86
}
 
87
 
 
88
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
 
89
{
 
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;
 
94
        }
 
95
    }
 
96
    
 
97
    if (machine_speed_mhz == -1) {
 
98
        ts->u64 = 0;
 
99
        return -1;
 
100
    } 
 
101
    ts->u64 = rdtsc();
 
102
    return 0;
 
103
}
 
104
 
 
105
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
 
106
{
 
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;
 
111
        }
 
112
    }
 
113
    
 
114
    if (machine_speed_mhz == -1) {
 
115
        freq->u64 = 1;  /* return 1 to prevent division by zero in apps. */
 
116
        return -1;
 
117
    } 
 
118
 
 
119
    freq->u64 = machine_speed.u64;
 
120
    return 0;
 
121
}
 
122
 
 
123
#elif defined(PJ_DARWINOS) && PJ_DARWINOS != 0
 
124
#include <mach/mach.h>
 
125
#include <mach/clock.h>
 
126
#include <errno.h>
 
127
 
 
128
#define NSEC_PER_SEC    1000000000
 
129
 
 
130
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
 
131
{
 
132
    mach_timespec_t tp;
 
133
    int ret;
 
134
    clock_serv_t serv;
 
135
 
 
136
    ret = host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &serv);
 
137
    if (ret != KERN_SUCCESS) {
 
138
        return PJ_RETURN_OS_ERROR(EINVAL);
 
139
    }
 
140
 
 
141
    ret = clock_get_time(serv, &tp);
 
142
    if (ret != KERN_SUCCESS) {
 
143
        return PJ_RETURN_OS_ERROR(EINVAL);
 
144
    }
 
145
 
 
146
    ts->u64 = tp.tv_sec;
 
147
    ts->u64 *= NSEC_PER_SEC;
 
148
    ts->u64 += tp.tv_nsec;
 
149
 
 
150
    return PJ_SUCCESS;
 
151
}
 
152
 
 
153
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
 
154
{
 
155
    freq->u32.hi = 0;
 
156
    freq->u32.lo = NSEC_PER_SEC;
 
157
 
 
158
    return PJ_SUCCESS;
 
159
}
 
160
 
 
161
#elif defined(USE_POSIX_TIMERS) && USE_POSIX_TIMERS != 0
 
162
#include <sys/time.h>
 
163
#include <time.h>
 
164
#include <errno.h>
 
165
 
 
166
#define NSEC_PER_SEC    1000000000
 
167
 
 
168
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
 
169
{
 
170
    struct timespec tp;
 
171
 
 
172
    if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
 
173
        return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
 
174
    }
 
175
 
 
176
    ts->u64 = tp.tv_sec;
 
177
    ts->u64 *= NSEC_PER_SEC;
 
178
    ts->u64 += tp.tv_nsec;
 
179
 
 
180
    return PJ_SUCCESS;
 
181
}
 
182
 
 
183
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
 
184
{
 
185
    freq->u32.hi = 0;
 
186
    freq->u32.lo = NSEC_PER_SEC;
 
187
 
 
188
    return PJ_SUCCESS;
 
189
}
 
190
 
 
191
#else
 
192
#include <sys/time.h>
 
193
#include <errno.h>
 
194
 
 
195
#define USEC_PER_SEC    1000000
 
196
 
 
197
PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts)
 
198
{
 
199
    struct timeval tv;
 
200
 
 
201
    if (gettimeofday(&tv, NULL) != 0) {
 
202
        return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
 
203
    }
 
204
 
 
205
    ts->u64 = tv.tv_sec;
 
206
    ts->u64 *= USEC_PER_SEC;
 
207
    ts->u64 += tv.tv_usec;
 
208
 
 
209
    return PJ_SUCCESS;
 
210
}
 
211
 
 
212
PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq)
 
213
{
 
214
    freq->u32.hi = 0;
 
215
    freq->u32.lo = USEC_PER_SEC;
 
216
 
 
217
    return PJ_SUCCESS;
 
218
}
 
219
 
 
220
#endif