1/*
2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2004-2006, Axel D��rfler, axeld@pinc-software.de.
4 * All rights reserved.
5 * Distributed under the terms of the MIT License.
6 */
7
8
9#include <sys/time.h>
10
11#include <errno.h>
12#include <string.h>
13
14#include <OS.h>
15
16#include <errno_private.h>
17#include <syscall_utils.h>
18
19#include <user_timer_defs.h>
20
21#include <time_private.h>
22
23
24static bool
25itimerval_to_itimerspec(const itimerval& val, itimerspec& spec)
26{
27	return timeval_to_timespec(val.it_value, spec.it_value)
28		&& timeval_to_timespec(val.it_interval, spec.it_interval);
29}
30
31
32static void
33itimerspec_to_itimerval(const itimerspec& spec, itimerval& val)
34{
35	timespec_to_timeval(spec.it_value, val.it_value);
36	timespec_to_timeval(spec.it_interval, val.it_interval);
37}
38
39
40static bool
41prepare_timer(__timer_t& timer, int which)
42{
43	switch (which) {
44		case ITIMER_REAL:
45			timer.SetTo(USER_TIMER_REAL_TIME_ID, -1);
46			return true;
47		case ITIMER_VIRTUAL:
48			timer.SetTo(USER_TIMER_TEAM_USER_TIME_ID, -1);
49			return true;
50		case ITIMER_PROF:
51			timer.SetTo(USER_TIMER_TEAM_TOTAL_TIME_ID, -1);
52			return true;
53	}
54
55	return false;
56}
57
58
59// #pragma mark -
60
61
62int
63getitimer(int which, struct itimerval* value)
64{
65	// prepare the respective timer
66	__timer_t timer;
67	if (!prepare_timer(timer, which))
68		RETURN_AND_SET_ERRNO(EINVAL);
69
70	// let timer_gettime() do the job
71	itimerspec valueSpec;
72	if (timer_gettime(&timer, &valueSpec) != 0)
73		return -1;
74
75	// convert back to itimerval value
76	itimerspec_to_itimerval(valueSpec, *value);
77
78	return 0;
79}
80
81
82int
83setitimer(int which, const struct itimerval* value, struct itimerval* oldValue)
84{
85	// prepare the respective timer
86	__timer_t timer;
87	if (!prepare_timer(timer, which))
88		RETURN_AND_SET_ERRNO(EINVAL);
89
90	// convert value to itimerspec
91	itimerspec valueSpec;
92	if (!itimerval_to_itimerspec(*value, valueSpec))
93		RETURN_AND_SET_ERRNO(EINVAL);
94
95	// let timer_settime() do the job
96	itimerspec oldValueSpec;
97	if (timer_settime(&timer, 0, &valueSpec,
98			oldValue != NULL ? &oldValueSpec : NULL) != 0) {
99		return -1;
100	}
101
102	// convert back to itimerval oldValue
103	if (oldValue != NULL)
104		itimerspec_to_itimerval(oldValueSpec, *oldValue);
105
106	return 0;
107}
108