+/*
+ * 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 _XOPEN_REALTIME != -1
+#if defined(_XOPEN_REALTIME) && _XOPEN_REALTIME != -1
+
+#define HAVE_IMPL
-timing_sched_env_t *timing_sched_get(timing_sched_env_t *env)
+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 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 NULL;
+ return;
+ new_scheduler = SCHED_FIFO;
+ new_sched_params = sched_params;
+ new_sched_params.sched_priority = sched_get_priority_max(new_scheduler);
+ sched_setscheduler(0, new_scheduler, &new_sched_params);
+ if (res < 0)
+ 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)
-{
- return NULL;
-}
+#ifndef HAVE_IMPL
+
+/* dummy implementation */
-int timing_sched_set(const timing_sched_env_t *env)
+void timing_enter_max_prio(void)
{
- 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