Subversion Repositories shark

Rev

Rev 950 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1063 tullio 1
 
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation; either version 2 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program; if not, write to the Free Software
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 *
17
 */
18
 
949 trimarchi 19
#include <stdio.h>
20
#include <unistd.h>
21
#include <time.h>
22
#include <errno.h>
23
 
24
#include <pthread.h>
25
#include <sched.h>
26
#include <fsf.h>
27
#include "timespec_operations.h"
28
#include "fsf_os_compatibility.h"
29
 
30
 
31
/*
32
 
33
 * This is part of the common tests:
34
 
35
 ** Test of the synchronization object primitives
36
 
37
  -  Create two servers, server A and server B. Each with 5 seconds budget
38
     and 20 seconds period (minimum values equal to the maximum ones),
39
     preemption levels for A = 4 and for B = 3, A is INDETERMINATE workload
40
     and B is BOUNDED workload. Deadline is 19.9 seconds for A and it is
41
     equal to the period for B. Server A is bound to the main thread with
42
     fsf_negotiate_contract_for_myself, server B is created with
43
     fsf_negotiate_contract_for_new_thread.
44
 
45
  -  Once the main program becomes server A, it creates a Synch_object
46
     and stores its reference in the global variable SO1_handle, then it
47
     creates server B for a new thread and releases
48
     the CPU for 0.5 second. The new thread in server B after starting,
49
     just waits for SO1 to be signaled, after that it executes during 1 second,
50
     then it waits for the the synchronization object SO1_handle to be signaled
51
     again, and finally ends.
52
 
53
  -  After the first release of the CPU, the main thread in server A
54
     signals SO1_handle and then releases the CPU for 0.5 second again,
55
     after that it signals SO1_handle a second time and releases the CPU for 2 seconds.
56
     Finally it destroy the synchronization object OS1 and ends.
57
 
58
*/
59
 
60
#define LOCAL_ERROR(nn,ss) {if(errno==0) errno=(nn); perror(ss); return (nn);}
61
//#define ERROR(nn,ss) {if(errno==0) errno=(nn); perror(ss); exit (nn);}
62
#define FSF_MAX_N_TIME_VALUES     1000
63
 
64
struct timespec            instant_zero = {0,0};
65
int                        main_priority = 4;
66
struct timespec            last_time = {0,0};
67
fsf_server_id_t            server_A = 0;
68
fsf_server_id_t            server_B = 0;
69
fsf_synch_obj_handle_t     SO1_handle;
70
 
71
extern int cal_cycles;
72
extern int calibrate_cycle(void);
73
extern void eat(TIME wait);
74
 
75
struct pseudo_printed_results {
76
  char            *s;
77
  struct timespec  t;
78
}                                  res[FSF_MAX_N_TIME_VALUES];
79
volatile int                       res_index = 0;
80
 
81
//reports the real-time it is
82
//with a comment and the difference to the last reported time
83
int
84
put_time(const struct timespec *time, char *s)
85
{
86
  struct timespec now = {0,0};
87
  int terror;
88
 
89
//  if(time == (struct timespec *)NULL) {
90
    if ((terror=clock_gettime(CLOCK_REALTIME,&now)))
91
      ERROR(terror,"clock_gettime failed");
92
//  }
93
//  else {
94
//    now = *time;
95
//  }
96
 
97
  res[res_index].s = s;
98
  res[res_index].t = now;
99
 
100
  //  printf("(%2d)", res_index+1);
101
  //  printf("%-60s", s);
102
  //  printf(" %2d %9d\n", now.tv_sec,now.tv_nsec);
103
 
104
  if (res_index < FSF_MAX_N_TIME_VALUES) res_index++;
105
 
106
  return 0;
107
} /* End of put_time */
108
 
109
 
110
int
111
print_time_results()
112
{
113
  struct timespec now = {0,0};
114
  struct timespec diff = {0,0};
115
  char            *s = NULL;
116
  int i;
117
 
950 trimarchi 118
  fsf_printf("\n");
949 trimarchi 119
  for (i=0;i<res_index;i++)
120
  {
121
    now  = res[i].t;
122
    s    = res[i].s;
123
    if (s==NULL) s = "  - timestamp - ";
124
    diff = now;
125
    decr_timespec(&diff, &last_time);
126
    last_time = now;
950 trimarchi 127
    fsf_printf("(%2d)", i+1);
128
    fsf_printf("%-60s", s);
129
    fsf_printf(" %2d %9d", now.tv_sec,now.tv_nsec);
130
    fsf_printf(" [diff=%13.9f]\n", (double)diff.tv_sec+((double)diff.tv_nsec/(double)1000000000));
949 trimarchi 131
  }
132
 
133
  return 0;
134
} /* End of print_time_results */
135
 
136
 
137
 
138
int
139
fsf_priority_map (unsigned long plevel)
140
{
141
  return plevel;
142
}
143
 
144
 
145
void * fsf_bounded_server_B (void * arg)
146
{
147
  //fsf_server_id_t       in = *((fsf_server_id_t *)arg);
148
  int                   terror=0;
149
 
150
  //fsf_server_id_t     server;
151
 
152
  //struct timespec  next_activation_time = in.offset;
153
  struct timespec  next_budget;
154
  struct timespec  next_period;
155
  bool             was_deadline_missed = 0;
156
  bool             was_budget_overran = 0;
157
 
158
  //executes for 0.1 second
159
 
160
  put_time(NULL, "B start one tenth of second execution   ");
161
  eat(100000);
162
  put_time(NULL, "B complete one tenth of second execution");
163
 
164
  //wait for the the synchronization object SO1_handle to be signaled
165
 
166
  put_time(NULL, "B called first fsf_schedule_triggered_job     ");
167
 
168
  if ((terror=fsf_schedule_triggered_job (
169
                                       SO1_handle,
170
                                       &next_budget,
171
                                       &next_period,
172
                                       &was_deadline_missed,
173
                                       &was_budget_overran)))
174
  {
175
     ERROR(terror,"fsf_bounded_server: first call to fsf_schedule_triggered_job failed");
176
  }
177
  put_time(NULL, "B returned from first fsf_schedule_triggered_job");
178
 
179
 
180
 
181
  //executes for 1 second
182
 
183
  put_time(NULL, "B start 1 second execution   ");
184
  eat(1000000);
185
  put_time(NULL, "B complete the 1 second execution");
186
 
187
  //wait for the the synchronization object SO1_handle to be signaled again
188
  put_time(NULL, "B called fsf_schedule_triggered_job");
189
  terror=fsf_schedule_triggered_job (
190
                                       SO1_handle,
191
                                       &next_budget,
192
                                       &next_period,
193
                                       &was_deadline_missed,
194
                                       &was_budget_overran);
195
  put_time(NULL, "B returned from fsf_schedule_triggered_job");
196
  if (terror)
197
  {
198
     ERROR(terror,"fsf_bounded_server: second call to fsf_schedule_triggered_job failed");
199
  }
200
 
201
 
202
  //end
203
  put_time(NULL, "B ends");
204
 
205
  return 0;
206
 
207
} /* End of fsf_bounded_server_B */
208
 
209
 
210
 
211
int main()
212
{
213
   struct sched_param   param;
214
   struct timespec      half_second= {0,500000000};
215
   struct timespec      tmp = {0,0};
216
   int                  terror = 0;
217
 
218
  fsf_contract_parameters_t  contract;
219
  struct timespec    budget_min = {7,0};
220
  struct timespec    period_max = {20,0};
221
  struct timespec    budget_max = {7,0};
222
  struct timespec    period_min = {20,0};
223
  fsf_workload_t     workload = FSF_INDETERMINATE;
224
 
225
  bool               d_equals_t = false;
226
  struct timespec    deadline = {19,900000000};
227
  int                budget_overrun_sig_notify = FSF_NULL_SIGNAL;   // 0
228
  union sigval       budget_overrun_sig_value = {0};
229
  int                deadline_miss_sig_notify = FSF_NULL_SIGNAL;    // 0
230
  union sigval       deadline_miss_sig_value = {0};
231
 
232
  fsf_granularity_t      granularity = FSF_DEFAULT_GRANULARITY;       // CONTINUOUS
233
  fsf_utilization_set_t *utilization_set = FSF_NULL_UTILIZATION_SET;  // NULL
234
  int                    quality = 1;
235
  int                    importance = FSF_DEFAULT_IMPORTANCE;         // 1
236
 
237
  fsf_preemption_level_t   preemption_level;
238
  fsf_critical_sections_t *critical_sections = NULL;
239
 
240
  pthread_t                task_in_b;
241
 
950 trimarchi 242
  INITIALIZATION_CODE
949 trimarchi 243
  SERIAL_CONSOLE_INIT;
244
 
245
  param.sched_priority = main_priority;
246
  if ((terror=pthread_setschedparam(pthread_self(), SCHED_FIFO, &param)))
247
    ERROR(terror,"pthread_setschedparam");
248
 
249
  instant_zero.tv_sec = 10000000;
250
  instant_zero.tv_nsec = 10000000;
251
  clock_settime(CLOCK_REALTIME,&instant_zero);
252
  clock_gettime(CLOCK_REALTIME,&instant_zero);
253
  last_time = instant_zero;
254
  put_time(&instant_zero, "instant_zero");
255
  put_time(NULL, "printing point 1");
256
  put_time(NULL, "printing point 2");
257
 
258
 
259
 
260
  if ((terror=fsf_initialize_contract(&contract)))
261
  {
950 trimarchi 262
     fsf_printf(" Initialize fail for server A\n");
949 trimarchi 263
     ERROR(terror,"fsf_initialize_contract failed");
264
  }
265
 
266
  if ((terror=fsf_set_contract_basic_parameters (&contract,
267
                                    &budget_min,
268
                                    &period_max,                                  
269
                                    workload)))
270
  {
950 trimarchi 271
     fsf_printf("Set_Basic_Parameters failed for server A\n");
949 trimarchi 272
     ERROR(terror,"set_contract_basic_parameters failed");
273
  }
274
 
275
  if ((terror=fsf_set_contract_timing_requirements (&contract,
276
                                      d_equals_t,
277
                                      (d_equals_t?NULL:&deadline),
278
                                      budget_overrun_sig_notify,
279
                                      budget_overrun_sig_value,
280
                                      deadline_miss_sig_notify,
281
                                      deadline_miss_sig_value)))
282
  {
950 trimarchi 283
     fsf_printf("Set_Timing_Requirements failed for server A\n");
949 trimarchi 284
     ERROR(terror,"fsf_set_contract_timing_requirements failed");
285
  }
286
 
287
  if ((terror=fsf_set_contract_reclamation_parameters (&contract,
288
                                                       &budget_max,
289
                                                       &period_min,
290
                                                       granularity,
291
                                                       utilization_set,
292
                                                       quality,
293
                                                       importance)))
294
  {
950 trimarchi 295
     fsf_printf("Set_Reclamation_Parameters failed for server A\n");
949 trimarchi 296
     ERROR(terror,"fsf_set_contract_reclamation_parameters failed");
297
  }
298
 
299
  preemption_level = (fsf_preemption_level_t) param.sched_priority;
300
  if ((terror=fsf_set_contract_synchronization_parameters (&contract,                                            
301
                                              critical_sections)))
302
  {
950 trimarchi 303
     fsf_printf("Set_Synchronization_Parameters failed for server A\n");
949 trimarchi 304
     ERROR(terror,"fsf_set_contract_synchronization_parameters failed");
305
  }
306
 
307
 
308
  put_time(NULL, "A start first server contract negotiation");
309
  terror = fsf_negotiate_contract_for_myself (&contract, &server_A);
310
  put_time(NULL, "A end first server contract negotiation");
311
  if (terror)
312
  {
950 trimarchi 313
    fsf_printf("Negotiate_Contract failed for server A\n");
949 trimarchi 314
    ERROR(terror,"fsf_negotiate_contract_for_myself failed");
315
  }
316
 
317
  //creation of the synchronization object
318
  put_time(NULL, "A start creating synchronization object");
319
  terror=fsf_create_synch_obj(&SO1_handle);
320
  put_time(NULL, "A end creating synchronization object");
321
  if (terror)
322
  {
323
     ERROR(terror,"fsf_signal_synchobject failed");    
324
  }
325
 
326
 
327
  //preparation of server B
328
  workload = FSF_BOUNDED;
329
  d_equals_t = true;
330
  //deadline.tv_sec = deadline.tv_nsec = 0;
331
 
332
  if ((terror=fsf_set_contract_basic_parameters (&contract,
333
                                    &budget_min,
334
                                    &period_max,                                
335
                                    workload)))
336
  {
950 trimarchi 337
     fsf_printf("Set_Basic_Parameters failed for server B\n");
949 trimarchi 338
     ERROR(terror,"set_contract_basic_parameters failed");
339
  }
340
 
341
  if ((terror=fsf_set_contract_timing_requirements (&contract,
342
                                      d_equals_t,
343
                                      (d_equals_t?NULL:&deadline),
344
                                      budget_overrun_sig_notify,
345
                                      budget_overrun_sig_value,
346
                                      deadline_miss_sig_notify,
347
                                      deadline_miss_sig_value)))
348
  {
950 trimarchi 349
     fsf_printf("Set_Timing_Requirements failed for server B\n");
949 trimarchi 350
     ERROR(terror,"fsf_set_contract_timing_requirements failed");
351
  }
352
 
353
  preemption_level--;
354
  if ((terror=fsf_set_contract_synchronization_parameters (&contract,                                            
355
                                              critical_sections)))
356
  {
950 trimarchi 357
     fsf_printf("Set_Synchronization_Parameters failed for server B\n");
949 trimarchi 358
     ERROR(terror,"fsf_set_contract_synchronization_parameters failed");
359
  }
360
 
361
  put_time(NULL, "A starts server B contract negotiation");
362
  terror=fsf_negotiate_contract_for_new_thread (&contract, &server_B, &task_in_b, NULL, fsf_bounded_server_B, NULL);
363
  put_time(NULL, "A ends server B contract negotiation");
364
  if (terror)
365
  {
950 trimarchi 366
     fsf_printf("Negotiate_Contract failed for server B\n");
949 trimarchi 367
     ERROR(terror,"fsf_negotiate_contract_for_new_thread failed");
368
  }
369
 
370
  if(!server_B) ERROR((-1), "Contract B not accepted");
371
 
372
  put_time(NULL, "A starts a half second nanosleep");
373
  if ((terror=nanosleep(&half_second,NULL)))
374
  ERROR(terror, "nanosleep 1 failed");
375
  put_time(NULL, "A completes the half second nanosleep");
376
 
377
  put_time(NULL, "A starts post-signaling synchronization object");
378
  terror=fsf_signal_synch_obj(SO1_handle);
379
  put_time(NULL, "A ends post-signaling synchronization object");
380
  if (terror)
381
  {
382
     ERROR(terror,"fsf_signal_synchobject failed");
383
  }
384
 
385
  half_second.tv_sec = 3;
386
  half_second.tv_nsec = 0;
387
  put_time(NULL, "A starts another 3s nanosleep");
388
  if ((terror=nanosleep(&half_second,NULL)))
389
    ERROR(terror, "nanosleep 2 failed");
390
  put_time(NULL, "A completes the other half second nanosleep");
391
 
392
  put_time(NULL, "A starts pre-signaling synchronization object");
393
  terror=fsf_signal_synch_obj(SO1_handle);
394
  put_time(NULL, "A ends pre-signaling synchronization object");
395
  if (terror)
396
  {
397
     ERROR(terror,"fsf_signal_synchobject failed");
398
  }
399
 
400
  tmp.tv_sec = 2;
401
  tmp.tv_nsec = 0;
402
  put_time(NULL, "A starts a final 2 seconds nanosleep");
403
  if ((terror=nanosleep(&tmp,NULL)))
404
    ERROR(terror, "third nanosleep failed");
405
  put_time(NULL, "A ends the final 2 seconds nanosleep");
406
 
407
  put_time(NULL, "A starts destroying synchronization object");
408
  terror=fsf_destroy_synch_obj(SO1_handle);
409
  put_time(NULL, "A ends destroying synchronization object");
410
  if (terror)
411
  {
412
     ERROR(terror,"fsf_destroy_synchobject failed");
413
  }
414
 
415
  print_time_results();
416
 
417
  STANDARD_CONSOLE_INIT; //marte1.26i+
418
 
419
  //print_time_results();
420
 
950 trimarchi 421
  fsf_printf("\nThe End.\n");
949 trimarchi 422
 
423
  //stop_scheduler = 1;
424
 
425
  exit(0);
426
  return 0;
427
} /* End of main */