Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
bd0527dc
Commit
bd0527dc
authored
Jun 01, 2009
by
Matthias Braun
Browse files
rework architecture specific timer code
[r26081]
parent
80d22a2b
Changes
4
Show whitespace changes
Inline
Side-by-side
ir/stat/stat_timing.c
View file @
bd0527dc
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief OS abstraction from time measurement
* @author Sebastian Hack, Michael Beck, Matthias Braun
* @version $Id$
*/
#include "config.h"
#include <stdio.h>
#include "stat_timing.h"
#include <stdio.h>
#ifdef __linux__
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
/* define GNU macro for processor affinity stuff if on linux */
#if defined __linux__ && !defined __USE_GNU
#define __USE_GNU
#endif
#include <sched.h>
/* we can only use the scheduling stuff, if that macro is defined in unistd.h */
#if defined(_XOPEN_REALTIME) && _XOPEN_REALTIME != -1
timing_sched_env_t
*
timing_sched_get
(
timing_sched_env_t
*
env
)
#define HAVE_IMPL
static
int
in_max_prio
=
0
;
static
cpu_set_t
affinity
;
static
int
scheduler
;
static
struct
sched_param
sched_params
;
void
timing_enter_max_prio
(
void
)
{
int
res
;
int
new_scheduler
=
SCHED_FIFO
;
struct
sched_param
new_sched_params
;
cpu_set_t
new_affinity
;
#ifdef __linux__
res
=
sched_getaffinity
(
0
,
sizeof
(
env
->
affinity
),
&
env
->
affinity
);
if
(
res
<
0
)
return
NULL
;
#endif
if
(
in_max_prio
)
return
;
env
->
scheduler
=
sched_getscheduler
(
0
);
if
(
env
->
scheduler
<
0
)
return
NULL
;
/* remember old scheduler settings */
res
=
sched_getaffinity
(
0
,
sizeof
(
affinity
),
&
affinity
);
if
(
res
<
0
)
return
;
scheduler
=
sched_getscheduler
(
0
);
if
(
scheduler
<
0
)
return
;
res
=
sched_getparam
(
0
,
&
sched_params
);
if
(
res
<
0
)
return
;
res
=
sched_getparam
(
0
,
&
env
->
params
);
/* set high prio */
CPU_ZERO
(
&
new_affinity
);
CPU_SET
(
0
,
&
new_affinity
);
res
=
sched_setaffinity
(
0
,
sizeof
(
new_affinity
),
&
new_affinity
);
if
(
res
<
0
)
return
;
new_scheduler
=
SCHED_FIFO
;
sched_params
.
sched_priority
=
sched_get_priority_max
(
new_scheduler
);
sched_setscheduler
(
0
,
new_scheduler
,
&
new_sched_params
);
if
(
res
<
0
)
return
NULL
;
return
;
return
env
;
in_max_prio
=
1
;
}
int
timing_
sched_set
(
const
timing_sched_env_t
*
env
)
void
timing_
leave_max_prio
(
void
)
{
int
res
;
#ifdef __linux__
res
=
sched_setaffinity
(
0
,
sizeof
(
env
->
affinity
),
&
env
->
affinity
);
if
(
!
in_max_prio
)
return
;
/* restore old settings */
res
=
sched_setaffinity
(
0
,
sizeof
(
affinity
),
&
affinity
);
if
(
res
<
0
)
return
0
;
#endif
return
;
res
=
sched_setscheduler
(
0
,
env
->
scheduler
,
&
env
->
params
);
sched_setscheduler
(
0
,
scheduler
,
&
sched_
params
);
if
(
res
<
0
)
return
0
;
return
;
return
1
;
in_max_prio
=
0
;
}
timing_sched_env_t
*
timing_sched_prepare_max_prio
(
timing_sched_env_t
*
env
)
{
int
policy
=
SCHED_FIFO
;
#ifdef __linux__
CPU_ZERO
(
&
env
->
affinity
);
CPU_SET
(
0
,
&
env
->
affinity
);
#endif
env
->
scheduler
=
policy
;
env
->
params
.
sched_priority
=
sched_get_priority_max
(
policy
);
return
env
;
}
#endif
#else
timing_sched_env_t
*
timing_sched_get
(
timing_sched_env_t
*
env
)
{
(
void
)
env
;
return
NULL
;
}
#ifndef HAVE_IMPL
/* dummy implementation */
int
timing_
sched_set
(
const
timing_sched_env_t
*
env
)
void
timing_
enter_max_prio
(
void
)
{
(
void
)
env
;
return
0
;
}
timing_sched_env_t
*
timing_sched_prepare_max_prio
(
timing_sched_env_t
*
env
)
void
timing_leave_max_prio
(
void
)
{
return
env
;
}
#endif
/* _POSIX_PRIORITY_SCHEDULING */
#endif
ir/stat/stat_timing.h
View file @
bd0527dc
#ifndef _TICKS_H
#define _TICKS_H
/*
* To use the Pentium RDTSC timer
* define TIMING_USE_RDTSC when including
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#define TIMING_USE_RDTSC
#if defined(_WIN32)
#ifdef TIMING_USE_RDTSC
/**
* @file
* @brief OS abstraction from time measurement
* @author Sebastian Hack, Michael Beck, Matthias Braun
* @version $Id$
*/
#ifndef FIRM_STAT_TIMING_H
#define FIRM_STAT_TIMING_H
typedef
unsigned
__int64
timing_ticks_t
;
#ifdef __i386__
__inline
timing_ticks_t
__timing_ticks
(
void
)
{
__asm
{
rdtsc
}
}
#define timing_ticks(t) ((t) = __timing_ticks())
#define timing_ticks_init(t) ((t) = 0)
#define timing_ticks_cmp(a, b, cmp) ((a) cmp (b))
#define timing_ticks_sub(r, a) ((r) = (r) - (a))
#define timing_ticks_add(r, a) ((r) = (r) + (a))
#define timing_ticks_ulong(t) ((unsigned long) (t))
#define timing_ticks_dbl(t) ((double) (t))
#ifdef __GNUC__
typedef
unsigned
long
long
timing_ticks_t
;
static
inline
timing_ticks_t
__timing_ticks
(
void
)
{
timing_ticks_t
result
;
__asm__
__volatile__
(
"rdtsc"
:
"=A"
(
result
));
return
result
;
}
#else
#error NOT IMPLEMENTED YET
#endif
/* TIMING_USE_RDTSC */
typedef
struct
{
int
dummy
;
}
timing_sched_env_t
;
#else
/* POSIX/Linux stuff */
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
/* define GNU macro for processor affinity stuff if on linux */
#if defined __linux__ && !defined __USE_GNU
#define __USE_GNU
#endif
#include <sched.h>
typedef
struct
{
#ifdef _POSIX_PRIORITY_SCHEDULING
struct
sched_param
params
;
#if define _MSC_VER
/* win32 implementation using rdtsc */
typedef
unsigned
__int64
timing_ticks_t
;
static
__inline
timing_ticks_t
__timing_ticks
(
void
)
{
__asm
{
rdtsc
}
}
#else
#error need a 64bit int type
#endif
int
scheduler
;
#ifdef __linux__
cpu_set_t
affinity
;
#endif
}
timing_sched_env_t
;
/* only use rdtsc on GNU C with x86 */
#if defined TIMING_USE_RDTSC && defined __GNUC__ && defined __i386__
typedef
unsigned
long
long
timing_ticks_t
;
#define timing_ticks(t) __asm__ __volatile__ ("rdtsc" : "=A" (t))
#define timing_ticks(t) ((t) = __timing_ticks())
#define timing_ticks_init(t) ((t) = 0)
#define timing_ticks_cmp(a, b, cmp) ((a) cmp (b))
#define timing_ticks_sub(r, a) ((r) = (r) - (a))
...
...
@@ -66,7 +50,9 @@ typedef unsigned long long timing_ticks_t;
#define timing_ticks_ulong(t) ((unsigned long) (t))
#define timing_ticks_dbl(t) ((double) (t))
#else
#else
/* !__i386__ */
#include <sys/time.h>
typedef
struct
timeval
timing_ticks_t
;
#define timing_ticks(t) (gettimeofday(&(t), NULL))
...
...
@@ -104,27 +90,9 @@ typedef struct timeval timing_ticks_t;
#define timing_ticks_ulong(t) ((unsigned long) ((t).tv_usec + 1000000 * (t).tv_sec))
#define timing_ticks_dbl(t) (((t).tv_usec + 1000000.0 * (t).tv_sec))
#endif
/* TIMING_USE_RDTSC ... */
#endif
/* _WIN32 */
/**
* Set the current schedule parameters.
* @return 1, if succeeded, 0 if not (see errno, for details).
*/
int
timing_sched_set
(
const
timing_sched_env_t
*
env
);
/**
* Get the schedule parameters.
* @return 1, if succeeded, 0 if not (see errno, for details).
*/
timing_sched_env_t
*
timing_sched_get
(
timing_sched_env_t
*
env
);
#endif
/**
* Prepare schedule parameters which limit the process on one CPU
* and set the maximum task priority.
* @return The paramter @p env.
*/
timing_sched_env_t
*
timing_sched_prepare_max_prio
(
timing_sched_env_t
*
env
);
void
timing_enter_max_prio
(
void
);
void
timing_leave_max_prio
(
void
);
#endif
/* _TICKS_H */
#endif
ir/stat/statev.c
View file @
bd0527dc
...
...
@@ -67,8 +67,6 @@ int stat_ev_enabled = 0;
int
stat_ev_timer_sp
=
0
;
timing_ticks_t
stat_ev_timer_elapsed
[
MAX_TIMER
];
timing_ticks_t
stat_ev_timer_start
[
MAX_TIMER
];
timing_sched_env_t
stat_ev_sched_rt
;
timing_sched_env_t
stat_ev_sched_normal
;
#ifdef FIRM_HAVE_REGEX
#include <regex.h>
...
...
@@ -139,8 +137,6 @@ void stat_ev_begin(const char *prefix, const char *filt)
}
stat_ev_enabled
=
stat_ev_file
!=
NULL
;
timing_sched_get
(
&
stat_ev_sched_normal
);
timing_sched_prepare_max_prio
(
&
stat_ev_sched_rt
);
}
void
stat_ev_end
(
void
)
...
...
ir/stat/statev.h
View file @
bd0527dc
...
...
@@ -61,16 +61,14 @@ extern int stat_ev_enabled;
extern
int
stat_ev_timer_sp
;
extern
timing_ticks_t
stat_ev_timer_elapsed
[];
extern
timing_ticks_t
stat_ev_timer_start
[];
extern
timing_sched_env_t
stat_ev_sched_rt
;
extern
timing_sched_env_t
stat_ev_sched_normal
;
static
inline
__attribute__
((
unused
))
void
stat_ev_tim_push
(
void
)
{
timing_ticks_t
temp
;
int
sp
=
stat_ev_timer_sp
++
;
timing_ticks
(
temp
);
if
(
sp
==
0
)
timing_
sched_set
(
&
stat_ev_sched_rt
);
else
{
if
(
sp
==
0
)
{
timing_
enter_max_prio
(
);
}
else
{
timing_ticks_sub
(
temp
,
stat_ev_timer_start
[
sp
-
1
]);
timing_ticks_add
(
stat_ev_timer_elapsed
[
sp
-
1
],
temp
);
}
...
...
@@ -87,10 +85,11 @@ static inline __attribute__((unused)) void stat_ev_tim_pop(const char *name) {
timing_ticks_add
(
stat_ev_timer_elapsed
[
sp
],
temp
);
if
(
name
!=
NULL
&&
stat_ev_enabled
)
stat_ev_printf
(
'E'
,
name
,
"%g"
,
timing_ticks_dbl
(
stat_ev_timer_elapsed
[
sp
]));
if
(
sp
==
0
)
timing_
sched_set
(
&
stat_ev_sched_normal
);
else
if
(
sp
==
0
)
{
timing_
leave_max_prio
(
);
}
else
{
timing_ticks
(
stat_ev_timer_start
[
sp
-
1
]);
}
}
#define stat_ev_ctx_push_fmt(key, fmt, value) \
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment