xref: /haiku/src/system/libroot/posix/sys/itimer.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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 
24 static bool
25 itimerval_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 
32 static void
33 itimerspec_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 
40 static bool
41 prepare_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 
62 int
63 getitimer(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 
82 int
83 setitimer(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