Subversion Repositories shark

Rev

Rev 949 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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