]> rtime.felk.cvut.cz Git - frescor/frsh-forb.git/blob - src/frsh/frsh_api/frsh_synchobj.c
frsh: RTEMS synchronization minor fixes
[frescor/frsh-forb.git] / src / frsh / frsh_api / frsh_synchobj.c
1 /**
2  * @file   frsh_synchobj.c
3  * @author Dario Faggioli <faggioli@gandalf.sssup.it>
4  *
5  * @brief  FRSH core synchronization objects related functions
6  *         not implamented in managers.
7  *
8  *
9  */
10 #include <fres_vres.h>
11 #include <fra_generic.h>
12 #include <fres_synchobj.h>
13
14 #include <frsh_core.h>
15 #include <time.h>
16
17 int frsh_synchobj_create(frsh_synchobj_handle_t *synch_handle)
18 {
19         if (!synch_handle)
20                 return FRSH_ERR_BAD_ARGUMENT;
21
22         *synch_handle = fres_synchobj_new();
23         if (!(*synch_handle)) goto err;
24
25         return 0;
26 err:
27         return errno;
28 }
29
30 int frsh_synchobj_destroy(const frsh_synchobj_handle_t synch_handle)
31 {
32         return fres_synchobj_destroy(synch_handle);
33 }
34
35 static void
36 __frsh_synchobj_check_wcet_and_deadline(frsh_thread_id_t thread,
37                                         fres_thread_vres_t *th_vres,
38                                         bool *was_deadline_missed,
39                                         bool *was_budget_overrun)
40 {
41         fosa_clock_id_t th_clockid;
42         fosa_abs_time_t curr_time, curr_exec_time;
43         frsh_vres_id_t vres;
44         fres_block_basic *b;
45         fres_block_timing_reqs *t;
46
47         if (!was_deadline_missed && !was_budget_overrun)
48                 return;
49
50         *was_deadline_missed = false;
51         *was_budget_overrun = false;
52
53         fosa_thread_get_cputime_clock(thread, &th_clockid);
54         fosa_clock_get_time(FOSA_CLOCK_REALTIME, &curr_time);
55         fosa_clock_get_time(th_clockid, &curr_exec_time);
56
57         curr_time = fosa_abs_time_decr(curr_time, th_vres->job_start_time);
58         curr_exec_time = fosa_abs_time_decr(curr_exec_time,
59                                             th_vres->job_cpu_time);
60
61         vres = th_vres->vres;
62         b = fres_contract_get_basic(vres->perceived);
63         t = fres_contract_get_timing_reqs(vres->perceived);
64
65         if (was_deadline_missed &&
66             fosa_abs_time_smaller_or_equal(t->deadline, curr_time))
67                 *was_deadline_missed = true;
68
69         if (was_budget_overrun &&
70             fosa_abs_time_smaller_or_equal(b->budget, curr_exec_time))
71                 *was_budget_overrun = false;
72 }
73
74 static void
75 __frsh_synchobj_set_wcet_and_deadline(frsh_thread_id_t thread,
76                                       fres_thread_vres_t *th_vres)
77 {
78         fosa_clock_id_t th_clockid;
79
80         fosa_thread_get_cputime_clock(thread, &th_clockid);
81         fosa_clock_get_time(FOSA_CLOCK_REALTIME,
82                                   &th_vres->job_start_time);
83         fosa_clock_get_time(th_clockid, &th_vres->job_cpu_time);
84
85 }
86
87 int frsh_synchobj_wait
88   (const frsh_synchobj_handle_t synch_handle,
89    frsh_rel_time_t *next_budget,
90    frsh_rel_time_t *next_period,
91    bool *was_deadline_missed,
92    bool *was_budget_overrun)
93 {
94         frsh_thread_id_t thread = fosa_thread_self();
95         fres_thread_vres_t *th_vres;
96         int ret = 0;
97
98         th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
99         if (!th_vres) goto out;
100
101         __frsh_synchobj_check_wcet_and_deadline(thread,
102                                                 th_vres,
103                                                 was_deadline_missed,
104                                                 was_budget_overrun);
105
106         ret = fres_synchobj_wait_with_timeout(synch_handle, NULL);
107         if (ret) goto out;
108
109         __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
110         frsh_vres_get_budget_and_period(th_vres->vres,
111                                         next_budget,
112                                         next_period);
113
114 out:
115         return ret;
116 }
117
118 int frsh_synchobj_wait_with_timeout
119   (const frsh_synchobj_handle_t synch_handle,
120    const frsh_abs_time_t *abs_timeout,
121    bool *timed_out,
122    frsh_rel_time_t *next_budget,
123    frsh_rel_time_t *next_period,
124    bool *was_deadline_missed,
125    bool *was_budget_overrun)
126 {
127         frsh_thread_id_t thread = fosa_thread_self();
128         fres_thread_vres_t *th_vres;
129         int ret = 0;
130
131         th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
132         if (!th_vres) goto out;
133
134         __frsh_synchobj_check_wcet_and_deadline(thread,
135                                                 th_vres,
136                                                 was_deadline_missed,
137                                                 was_budget_overrun);
138
139         ret = fres_synchobj_wait_with_timeout(synch_handle, abs_timeout);
140         if (ret == ETIMEDOUT) *timed_out = true;
141         else if (ret != 0) goto out;
142
143         __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
144         frsh_vres_get_budget_and_period(th_vres->vres,
145                                         next_budget,
146                                         next_period);
147
148 out:
149         return ret;
150 }
151
152 int frsh_synchobj_signal(const frsh_synchobj_handle_t synch_handle)
153 {
154         return fres_synchobj_signal(synch_handle);
155 }
156
157 int frsh_timed_wait
158   (const frsh_abs_time_t *abs_time,
159    frsh_rel_time_t *next_budget,
160    frsh_rel_time_t *next_period,
161    bool *was_deadline_missed,
162    bool *was_budget_overrun)
163 {
164         frsh_thread_id_t thread = fosa_thread_self();
165         fres_thread_vres_t *th_vres;
166         int ret = 0;
167
168         th_vres = fra_get_thread_vres(&thread, FRSH_RT_PROCESSOR);
169         if (!th_vres) goto out;
170
171         __frsh_synchobj_check_wcet_and_deadline(thread,
172                                                 th_vres,
173                                                 was_deadline_missed,
174                                                 was_budget_overrun);
175
176 #ifdef RTEMS
177         ret = nanosleep(abs_time, NULL);        
178 #else
179         ret = clock_nanosleep(FOSA_CLOCK_REALTIME,
180                               TIMER_ABSTIME,
181                               abs_time, NULL);
182 #endif
183
184         __frsh_synchobj_set_wcet_and_deadline(thread, th_vres);
185         frsh_vres_get_budget_and_period(th_vres->vres,
186                                         next_budget,
187                                         next_period);
188
189 out:
190         return ret;
191 }
192
193 int frsh_vresperiod_wait
194   (unsigned long period_num,
195    frsh_rel_time_t       *next_budget,
196    frsh_rel_time_t       *next_period,
197    bool                  *was_deadline_missed,
198    bool                  *was_budget_overran)
199 {
200         return FRSH_ERR_NOT_IMPLEMENTED;
201 }
202
203 int frsh_get_period_number(const frsh_vres_id_t vres, long *period_num)
204
205 {
206         return FRSH_ERR_NOT_IMPLEMENTED;
207 }
208