2
* Copyright © 2006 Mozilla Corporation
3
* Copyright © 2006 Red Hat, Inc.
5
* Permission to use, copy, modify, distribute, and sell this software
6
* and its documentation for any purpose is hereby granted without
7
* fee, provided that the above copyright notice appear in all copies
8
* and that both that copyright notice and this permission notice
9
* appear in supporting documentation, and that the name of
10
* the authors not be used in advertising or publicity pertaining to
11
* distribution of the software without specific, written prior
12
* permission. The authors make no representations about the
13
* suitability of this software for any purpose. It is provided "as
14
* is" without express or implied warranty.
16
* THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
17
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
18
* FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL,
19
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
21
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
22
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
* Authors: Vladimir Vukicevic <vladimir@pobox.com>
25
* Carl Worth <cworth@cworth.org>
28
/* Portions of this file come from liboil:
30
* LIBOIL - Library of Optimized Inner Loops
31
* Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org>
32
* All rights reserved.
34
* Redistribution and use in source and binary forms, with or without
35
* modification, are permitted provided that the following conditions
37
* 1. Redistributions of source code must retain the above copyright
38
* notice, this list of conditions and the following disclaimer.
39
* 2. Redistributions in binary form must reproduce the above copyright
40
* notice, this list of conditions and the following disclaimer in the
41
* documentation and/or other materials provided with the distribution.
43
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
44
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
47
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
51
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
52
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
53
* POSSIBILITY OF SUCH DAMAGE.
59
#ifdef _POSIX_PRIORITY_SCHEDULING
63
#include "cairo-perf.h"
67
#if defined(__i386__) || defined(__amd64__)
68
static inline unsigned long
69
oil_profile_stamp_rdtsc (void)
72
__asm__ __volatile__("rdtsc\n" : "=a" (ts) : : "edx");
75
#define OIL_STAMP oil_profile_stamp_rdtsc
78
#if defined(__powerpc__) || defined(__PPC__) || defined(__ppc__)
79
static inline cairo_perf_ticks_t
80
oil_profile_stamp_tb(void)
83
__asm__ __volatile__("mftb %0\n" : "=r" (ts));
86
#define OIL_STAMP oil_profile_stamp_tb
89
#if defined(__alpha__)
90
static inline cairo_perf_ticks_t
91
oil_profile_stamp_alpha(void)
94
__asm__ __volatile__ ("rpcc %0\n" : "=r"(ts));
97
#define OIL_STAMP oil_profile_stamp_alpha
100
#if defined(__s390__)
101
static cairo_perf_ticks_t
102
oil_profile_stamp_s390(void)
105
__asm__ __volatile__ ("STCK %0\n" : : "m" (ts));
108
#define OIL_STAMP oil_profile_stamp_s390
111
typedef struct _cairo_perf_timer
114
cairo_perf_ticks_t start;
115
cairo_perf_ticks_t stop;
117
struct timeval tv_start;
118
struct timeval tv_stop;
120
} cairo_perf_timer_t;
122
static cairo_perf_timer_t timer;
124
static cairo_perf_timer_synchronize_t cairo_perf_timer_synchronize = NULL;
125
static void *cairo_perf_timer_synchronize_closure = NULL;
127
cairo_perf_timer_set_synchronize (cairo_perf_timer_synchronize_t synchronize,
130
cairo_perf_timer_synchronize = synchronize;
131
cairo_perf_timer_synchronize_closure = closure;
135
cairo_perf_timer_start (void) {
136
if (cairo_perf_timer_synchronize)
137
cairo_perf_timer_synchronize (cairo_perf_timer_synchronize_closure);
139
timer.start = OIL_STAMP ();
141
gettimeofday (&timer.tv_start, NULL);
146
cairo_perf_timer_stop (void) {
147
if (cairo_perf_timer_synchronize)
148
cairo_perf_timer_synchronize (cairo_perf_timer_synchronize_closure);
150
timer.stop = OIL_STAMP ();
152
gettimeofday (&timer.tv_stop, NULL);
157
cairo_perf_timer_elapsed (void) {
158
cairo_perf_ticks_t ticks;
161
/* Handle 32-bit wraparound of timer value */
162
if (timer.stop < timer.start)
163
timer.stop += 0x100000000ll;
164
ticks = (timer.stop - timer.start);
166
ticks = (timer.tv_stop.tv_sec - timer.tv_start.tv_sec) * 1000000;
167
ticks += (timer.tv_stop.tv_usec - timer.tv_start.tv_usec);
174
cairo_perf_ticks_per_second (void) {
176
static cairo_perf_ticks_t tps = 0;
177
/* XXX: This is obviously not stable in light of changing CPU speed. */
179
struct timeval tv_start, tv_stop;
181
cairo_perf_timer_start ();
182
gettimeofday (&tv_start, NULL);
184
cairo_perf_timer_stop ();
185
gettimeofday (&tv_stop, NULL);
186
tv_elapsed = ((tv_stop.tv_sec - tv_start.tv_sec) +
187
+ (tv_stop.tv_usec - tv_start.tv_usec) / 1000000.0);
188
tps = round (cairo_perf_timer_elapsed () / tv_elapsed);
192
/* For gettimeofday the units are micro-seconds */
200
cairo_perf_yield (void) {
201
#ifdef _POSIX_PRIORITY_SCHEDULING