Subversion Repositories shark

Rev

Rev 1063 | Go to most recent revision | 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
 
221 giacomo 19
//=====================================================================
20
//       FFFFFFIII   RRRRR      SSTTTTTTT
21
//      FF         IIR   RR    SS
22
//     FF           IR        SS
23
//    FFFFFF         RRRR    SSSSST      
24
//   FF       FI       RRR  SS
25
//  FF         II     RRR  SS
26
// FF           IIIIIR    RS 
27
//       
28
// Basic FSF(FIRST Scheduling Framework) contract management
29
// S.Ha.R.K. Implementation
30
//=====================================================================
31
 
908 trimarchi 32
#include "fsf.h"
808 trimarchi 33
#include "fsf_server.h"
34
#include <kernel/descr.h>
35
#include <kernel/func.h>
36
#include <pistar.h>
989 trimarchi 37
#include <ll/i386/string.h>
221 giacomo 38
 
989 trimarchi 39
#define MAX_SHARED_NAME 15
40
 
808 trimarchi 41
struct hash_entry {
42
  mutex_t mx;
989 trimarchi 43
  char  shared_obj_name[MAX_SHARED_NAME];
868 trimarchi 44
  FSF_SHARED_OBJ_HANDLE_T_OPAQUE id;
808 trimarchi 45
};
46
 
47
 
868 trimarchi 48
#define MAX_HASH_ENTRY FSF_MAX_N_SHARED_OBJECTS 
808 trimarchi 49
struct  hash_entry htable[MAX_HASH_ENTRY];
50
 
51
 
52
/*----------------------------------------------------------------------*/
53
/* hash_fun() : address hash table                                      */
54
/*----------------------------------------------------------------------*/
868 trimarchi 55
static int hash_fun(fsf_shared_obj_id_t id)
808 trimarchi 56
{
57
    return (*id % MAX_HASH_ENTRY);
58
}
59
 
811 trimarchi 60
void fsf_register_shared_object(void) {
61
int i=0;
62
// Init Hash table
63
//kern_printf("(IT SO)\n");
64
for (i=0; i<MAX_HASH_ENTRY; i++) {
65
  htable[i].id=-1;
808 trimarchi 66
 
811 trimarchi 67
}
68
 
69
}
881 trimarchi 70
int fsf_init() {
811 trimarchi 71
 
881 trimarchi 72
  FSF_start_service_task();
941 trimarchi 73
  FSF_init_synch_obj_layer();
964 trimarchi 74
  return 0;
881 trimarchi 75
}
76
 
77
 
221 giacomo 78
int fsf_initialize_contract
79
  (fsf_contract_parameters_t *contract)
80
{
81
  struct timespec default_deadline = FSF_DEFAULT_DEADLINE;
82
 
83
  /* Check */
868 trimarchi 84
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 85
 
86
  /* Set to default value */
87
  NULL_TIMESPEC(&contract->budget_min);
88
  NULL_TIMESPEC(&contract->budget_max);
89
  NULL_TIMESPEC(&contract->period_min);
90
  NULL_TIMESPEC(&contract->period_max);
91
 
92
  contract->workload = FSF_DEFAULT_WORKLOAD;
93
 
868 trimarchi 94
  contract->policy = FSF_DEFAULT_SCHED_POLICY;
221 giacomo 95
 
96
  contract->d_equals_t = FSF_DEFAULT_D_EQUALS_T;
97
 
98
  TIMESPEC_ASSIGN(&contract->deadline,&default_deadline);
99
 
100
  contract->budget_overrun_sig_notify = 0;
101
  memset(&contract->budget_overrun_sig_value,0,sizeof(union sigval));
102
 
103
  contract->deadline_miss_sig_notify = 0;
104
  memset(&contract->deadline_miss_sig_value,0,sizeof(union sigval));
105
 
106
  contract->granularity = FSF_DEFAULT_GRANULARITY;
107
  contract->utilization_set.size = 0;
108
  contract->quality = FSF_DEFAULT_QUALITY;
109
  contract->importance = FSF_DEFAULT_IMPORTANCE;
110
 
111
  contract->preemption_level = 0;
112
  contract->critical_sections.size = 0;
113
 
114
  return 0;
115
 
116
}
117
 
118
int fsf_set_contract_basic_parameters
119
  (fsf_contract_parameters_t *contract,
120
   const struct timespec  *budget_min,
868 trimarchi 121
   const struct timespec  *period_max,  
221 giacomo 122
   fsf_workload_t          workload)
123
{
124
 
868 trimarchi 125
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 126
 
940 trimarchi 127
  if (budget_min->tv_sec < 0 || budget_min->tv_nsec > 1000000000)
128
     return FSF_ERR_BAD_ARGUMENT;
129
 
130
  if (period_max->tv_sec < 0 || period_max->tv_nsec > 1000000000)
131
     return FSF_ERR_BAD_ARGUMENT;
132
 
874 trimarchi 133
  if (budget_min && (budget_min->tv_sec!=0 || budget_min->tv_nsec!=0)) {
868 trimarchi 134
     TIMESPEC_ASSIGN(&contract->budget_min,budget_min);
135
     TIMESPEC_ASSIGN(&contract->budget_max,budget_min);
874 trimarchi 136
  } else return FSF_ERR_BAD_ARGUMENT;
137
 
138
  if (period_max && (period_max->tv_sec!=0 || period_max->tv_nsec!=0)) {
868 trimarchi 139
     TIMESPEC_ASSIGN(&contract->period_max,period_max);
140
     TIMESPEC_ASSIGN(&contract->period_min,period_max);
874 trimarchi 141
  } else return FSF_ERR_BAD_ARGUMENT;
142
 
143
  switch(workload) {
144
     case FSF_INDETERMINATE:
145
     case FSF_BOUNDED:
146
     case FSF_OVERHEAD:
147
        contract->workload = workload;
148
        break;
149
     default: return FSF_ERR_BAD_ARGUMENT;
868 trimarchi 150
  }
221 giacomo 151
 
874 trimarchi 152
 
221 giacomo 153
  return 0;
154
 
155
}
156
 
157
int fsf_get_contract_basic_parameters
158
  (const fsf_contract_parameters_t *contract,
159
   struct timespec  *budget_min,
160
   struct timespec  *period_max,
161
   fsf_workload_t   *workload)
162
{
163
 
874 trimarchi 164
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 165
 
166
  TIMESPEC_ASSIGN(budget_min,&contract->budget_min);
868 trimarchi 167
  TIMESPEC_ASSIGN(period_max,&contract->period_max);
221 giacomo 168
 
169
  *workload = contract->workload;
170
 
171
  return 0;
172
 
173
}
174
 
175
int fsf_set_contract_timing_requirements
176
  (fsf_contract_parameters_t *contract,
177
   bool                   d_equals_t,
178
   const struct timespec *deadline,
179
   int                    budget_overrun_sig_notify,
180
   union sigval           budget_overrun_sig_value,
181
   int                    deadline_miss_sig_notify,
182
   union sigval           deadline_miss_sig_value)
183
{
184
 
868 trimarchi 185
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
908 trimarchi 186
  if ((d_equals_t==true && deadline != FSF_NULL_DEADLINE) ||
187
      (d_equals_t==false && deadline == FSF_NULL_DEADLINE))
874 trimarchi 188
     return FSF_ERR_BAD_ARGUMENT;
908 trimarchi 189
  if (deadline != FSF_NULL_DEADLINE && TIMESPEC_A_GT_B(deadline, &contract->period_max))
874 trimarchi 190
     return FSF_ERR_BAD_ARGUMENT;
221 giacomo 191
 
192
  contract->d_equals_t = d_equals_t;
193
 
194
  if (deadline) TIMESPEC_ASSIGN(&contract->deadline,deadline);
195
 
196
  contract->budget_overrun_sig_notify = budget_overrun_sig_notify;
197
  contract->budget_overrun_sig_value = budget_overrun_sig_value;
198
  contract->deadline_miss_sig_notify = deadline_miss_sig_notify;
199
  contract->deadline_miss_sig_value = deadline_miss_sig_value;
200
 
201
  return 0;
202
 
203
}
204
 
205
int fsf_get_contract_timing_requirements
206
  (const fsf_contract_parameters_t *contract,
207
   bool                            *d_equals_t,
208
   struct timespec                 *deadline,
209
   int                             *budget_overrun_sig_notify,
210
   union sigval                    *budget_overrun_sig_value,
211
   int                             *deadline_miss_sig_notify,
212
   union sigval                    *deadline_miss_sig_value)
213
{
214
 
868 trimarchi 215
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 216
 
217
  *d_equals_t = contract->d_equals_t;
218
 
219
  TIMESPEC_ASSIGN(deadline,&contract->deadline);
220
 
221
  *budget_overrun_sig_notify = contract->budget_overrun_sig_notify;
222
  *budget_overrun_sig_value = contract->budget_overrun_sig_value;
223
  *deadline_miss_sig_notify = contract->deadline_miss_sig_notify;
224
  *deadline_miss_sig_value = contract->deadline_miss_sig_value;
225
 
226
  return 0;
227
 
228
}
229
 
868 trimarchi 230
int
231
fsf_set_contract_reclamation_parameters
232
  (fsf_contract_parameters_t   *contract,
233
   const struct timespec       *budget_max,
234
   const struct timespec       *period_min,
221 giacomo 235
   fsf_granularity_t            granularity,
868 trimarchi 236
   const fsf_utilization_set_t *utilization_set,
221 giacomo 237
   int                          quality,
238
   int                          importance)
239
{
240
 
868 trimarchi 241
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 242
 
940 trimarchi 243
  if (budget_max->tv_sec < 0 || budget_max->tv_nsec > 1000000000)
244
     return FSF_ERR_BAD_ARGUMENT;
245
 
246
  if (period_min->tv_sec < 0 || period_min->tv_nsec > 1000000000)
247
     return FSF_ERR_BAD_ARGUMENT;
248
 
221 giacomo 249
  contract->granularity = granularity;
250
 
251
  if (utilization_set) memcpy(&contract->utilization_set,utilization_set,sizeof(fsf_utilization_set_t));
868 trimarchi 252
 
253
  if (budget_max) TIMESPEC_ASSIGN(&contract->budget_max,budget_max);
254
  if (period_min) TIMESPEC_ASSIGN(&contract->period_min,period_min);
255
 
221 giacomo 256
  contract->quality = quality;
257
  contract->importance = importance;
258
 
259
  return 0;
260
 
261
}
262
 
263
int fsf_get_contract_reclamation_parameters
264
  (const fsf_contract_parameters_t *contract,
868 trimarchi 265
   struct timespec                 *budget_max,
266
   struct timespec                 *period_min,
221 giacomo 267
   fsf_granularity_t               *granularity,
268
   fsf_utilization_set_t           *utilization_set,
269
   int                             *quality,
270
   int                             *importance)
271
{
272
 
868 trimarchi 273
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 274
 
275
  *granularity = contract->granularity;
964 trimarchi 276
  if (utilization_set)
277
    memcpy(utilization_set,&contract->utilization_set,sizeof(fsf_utilization_set_t));
868 trimarchi 278
 
279
  TIMESPEC_ASSIGN(budget_max,&contract->budget_max);
280
  TIMESPEC_ASSIGN(period_min,&contract->period_min);
221 giacomo 281
 
282
  *quality = contract->quality;
283
  *importance = contract->importance;
284
 
285
  return 0;
286
 
287
}
288
 
289
int fsf_set_contract_synchronization_parameters
290
  (fsf_contract_parameters_t     *contract,
291
   const fsf_critical_sections_t *critical_sections)
292
{
293
 
868 trimarchi 294
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 295
 
296
  if (critical_sections) memcpy(&contract->critical_sections,critical_sections,sizeof(fsf_critical_sections_t));
297
 
298
  return 0;
299
 
300
}
301
 
302
int
303
fsf_get_contract_synchronization_parameters
304
  (const fsf_contract_parameters_t *contract,
305
   fsf_critical_sections_t         *critical_sections)
306
{
307
 
868 trimarchi 308
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
964 trimarchi 309
  if (critical_sections)
310
    memcpy(critical_sections,&contract->critical_sections,sizeof(fsf_critical_sections_t));
868 trimarchi 311
 
221 giacomo 312
  return 0;
313
 
314
}
315
 
868 trimarchi 316
int
317
fsf_set_contract_scheduling_policy
221 giacomo 318
  (fsf_contract_parameters_t *contract,
868 trimarchi 319
   fsf_sched_policy_t         sched_policy)
221 giacomo 320
{
321
 
868 trimarchi 322
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 323
 
868 trimarchi 324
  contract->policy = sched_policy;
221 giacomo 325
 
326
  return 0;
327
 
328
}
329
 
330
int
868 trimarchi 331
fsf_get_contract_scheduling_policy
221 giacomo 332
  (const fsf_contract_parameters_t *contract,
868 trimarchi 333
   fsf_sched_policy_t              *sched_policy)
221 giacomo 334
{
335
 
868 trimarchi 336
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 337
 
868 trimarchi 338
  *sched_policy = contract->policy;
221 giacomo 339
 
340
  return 0;
341
 
342
}
343
 
868 trimarchi 344
/* OLD VERSION
808 trimarchi 345
// mutex lock function
221 giacomo 346
 
808 trimarchi 347
int fsf_lock_object(fsf_shared_operation_t *op) {
348
  int index, oldindex;
811 trimarchi 349
 
350
  index=hash_fun(&(op->obj_id));  
351
  //kern_printf("index %d, htableid %d, obj_op_id %d", index, htable[index].id,op->obj_id);
221 giacomo 352
 
808 trimarchi 353
  if (htable[index].id!=op->obj_id) {
354
    oldindex=index;
355
    index = (index + 1) % MAX_HASH_ENTRY;
356
    // find
811 trimarchi 357
    while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 358
    if (index==oldindex) return -1;
359
  }
811 trimarchi 360
  //kern_printf("(SO LK)");
808 trimarchi 361
  // we need a special implementation for mutex_lock ... additional parameter
829 giacomo 362
  return PISTAR_lock(FSF_get_shared_object_level(), &htable[index].mx,TIMESPEC2USEC(&op->wcet));
808 trimarchi 363
 
364
}
365
 
366
int fsf_unlock_object(fsf_shared_operation_t *op) {
367
 
368
  int index, oldindex;
369
 
370
  index=hash_fun(&op->obj_id);  
371
 
372
  if (htable[index].id!=op->obj_id) {
373
    oldindex=index;
374
    index = (index + 1) % MAX_HASH_ENTRY;
375
    // find
811 trimarchi 376
    while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 377
    if (index==oldindex) return -1;
378
  }
811 trimarchi 379
  //kern_printf("UNLOCK index %d", index);
380
 
808 trimarchi 381
  return mutex_unlock(&htable[index].mx);
382
 
383
 
384
 
385
}
386
 
868 trimarchi 387
*/
388
 
989 trimarchi 389
 
390
int fsf_get_shared_object_handle
391
   (fsf_shared_obj_id_t      obj_id,
392
    fsf_shared_obj_handle_t *obj_handle) {
393
  int index;
394
  int oldindex;
395
  SYS_FLAGS f;
396
 
397
  f=kern_fsave();
398
 
399
  index=hash_fun(obj_id);
400
 
401
  if (strcmp(htable[index].shared_obj_name,obj_id) == 0) {
402
        kern_frestore(f);
403
        return index;
404
  }
405
 
406
  if (htable[index].id!=0) {
407
    oldindex=index;
408
    index = (index + 1) % MAX_HASH_ENTRY;
409
    // collision detection
410
    while (htable[index].id !=0 && index!=oldindex) {
411
      if (strcmp(htable[index].shared_obj_name,obj_id) == 0) {
412
        kern_frestore(f);
413
        return index;
414
      }
415
      index=(index+1) % MAX_HASH_ENTRY;
416
    }
417
 
418
    // table is full
419
    if (index==oldindex) {
420
      kern_frestore(f);
421
      return -1;
422
    }
423
  }
424
 
425
  kern_frestore(f);
426
  return -1;
427
 
428
}
429
 
430
 
431
 
868 trimarchi 432
int fsf_init_shared_object
433
   (fsf_shared_obj_id_t      id,
434
    fsf_shared_obj_handle_t *obj,
435
    pthread_mutex_t         *mutex) {
808 trimarchi 436
  int index;
437
  int oldindex;
438
  PISTAR_mutexattr_t a;
811 trimarchi 439
  SYS_FLAGS f;
808 trimarchi 440
 
441
  PISTAR_mutexattr_default(a);
811 trimarchi 442
  //kern_printf("(SI SO)\n");
443
  f=kern_fsave();
829 giacomo 444
 
868 trimarchi 445
  index=hash_fun(id);
811 trimarchi 446
  //kern_printf("Index %d Hash %d", index, htable[index].id);
829 giacomo 447
 
989 trimarchi 448
  if (strcmp(htable[index].shared_obj_name,id) == 0) {
829 giacomo 449
        kern_frestore(f);
450
        return -1;
451
  }
452
 
989 trimarchi 453
  if (htable[index].id!=0) {
808 trimarchi 454
    oldindex=index;
455
    index = (index + 1) % MAX_HASH_ENTRY;
456
    // collision detection
989 trimarchi 457
    while (htable[index].id !=0 && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 458
    // table is full
825 trimarchi 459
    if (index==oldindex) {
460
        kern_frestore(f);
829 giacomo 461
        return -1;
825 trimarchi 462
    }
808 trimarchi 463
  }
829 giacomo 464
 
868 trimarchi 465
  //obj->size=0;
829 giacomo 466
 
808 trimarchi 467
  mutex_init(&(htable[index]).mx, &a);
868 trimarchi 468
  mutex=&(htable[index]).mx;
989 trimarchi 469
  strncpy(htable[index].shared_obj_name, id,MAX_SHARED_NAME);
470
  *obj=index;
811 trimarchi 471
  kern_frestore(f);
829 giacomo 472
 
473
  return 0;
474
 
811 trimarchi 475
  //kern_printf("(EI SO)\n");
808 trimarchi 476
}
477
 
868 trimarchi 478
/* OLD VERSION
808 trimarchi 479
// Declare an operation
480
// This function is used to declare that a shared object has
481
//    a synchronized operation on it.
482
// It checks if another operation with the same id has already been
483
//    declared; if so, return false (-1).
484
// The obj_id field of the operation is set equal to the shared object id.
485
// the structure op is copied in the first free element in the array
486
//    shared_op pof the structure obj. If there are no more free element,
487
//    returns -1.
488
// Returns 0 if the operation has been completed, -1 otherwise.
489
 
490
int fsf_declare_shared_object_operation(fsf_shared_object_t *obj,
491
                                        fsf_shared_operation_t *op) {
492
  int i;
825 trimarchi 493
  SYS_FLAGS f;
494
 
495
  f=kern_fsave();
496
 
808 trimarchi 497
  for (i=0; i<obj->size; i++) {
498
    // fail if the operation already declared
825 trimarchi 499
    if (op->op_id==obj->shared_op[i].op_id) {
500
      kern_frestore(f);
808 trimarchi 501
      return -1;    
825 trimarchi 502
    }
808 trimarchi 503
  }
504
 
505
  // fail if the object is full
825 trimarchi 506
  if (obj->size>(FSF_MAX_SHARED_OPERATION-1)) {
507
    kern_frestore(f);
808 trimarchi 508
    return -1;  
825 trimarchi 509
  }
829 giacomo 510
 
823 trimarchi 511
  //kern_printf("(DO SO)");
808 trimarchi 512
  obj->size++;
829 giacomo 513
  obj->shared_op[i].op_id = op->op_id;
514
  TIMESPEC_ASSIGN(&obj->shared_op[i].wcet,&op->wcet);
515
  obj->shared_op[i].obj_id = obj->obj_id;
516
  op->obj_id = obj->obj_id;
517
 
825 trimarchi 518
  kern_frestore(f);  
829 giacomo 519
 
808 trimarchi 520
  return 0;
521
 
522
 
523
}
868 trimarchi 524
*/
808 trimarchi 525
 
868 trimarchi 526
/* OLD VERSION
808 trimarchi 527
int fsf_set_contract_synchronization_parameters(
528
    fsf_contract_parameters_t *contract,
529
    const fsf_shared_operation_t *shared_ops,
530
    size_t op_num)
531
{
532
  if (shared_ops && op_num < FSF_MAX_SHARED_OPERATION)
533
    memcpy(&contract->shared_operations,shared_ops,op_num);
534
  else return -1;
535
 
536
  return 0;
537
}
868 trimarchi 538
*/
954 trimarchi 539
 
540
// MARTE IMPLEMENTATION SPECIFIC MODULE
541
 
542
// The operations defined in this module are of optional use. They
543
// only work in the fixed priority implementation, and they may be
544
// used to enhance the behavior of the applications running under the
545
// fsf scheduler.
546
 
547
//// The definition of this type is in fsf_basic_types.h
548
//
549
//typedef unsigned long      fsf_preemption_level_t;
550
//                           // range 1..2**32-1
551
 
552
 
553
//fsf_set_contract_preemption_level: The operation updates the
554
//specified contract parameters object by setting its preemption level
555
//to the specified input parameter.
556
 
557
int
558
fsf_set_contract_preemption_level
559
  (fsf_contract_parameters_t     *contract,
560
   fsf_preemption_level_t         preemption_level) {
561
  return 0;
562
}
563
 
564
 
565
//fsf_get_contract_preemption_level: The operation obtains from the
566
//specified contract parameters object its preemption level and copies
567
//it to the place pointed to by the specified input parameter.
568
 
569
int
570
fsf_get_contract_preemption_level
571
  (const fsf_contract_parameters_t *contract,
572
   fsf_preemption_level_t          *preemption_level)  {
573
  return 0;
574
}
575
 
576
 
577
 
578
//fsf_set_service_thread_preemption_level: this function sets the
579
//preemption level of the service thread to the specified value. The
580
//initial preemption level is a configurable parameter
581
 
582
int
583
fsf_set_service_thread_preemption_level
584
  (fsf_preemption_level_t         preemption_level) {
585
  return 0;
586
}
587
 
588
 
589
//fsf_get_service_thread_preemption_level: this function stores the
590
//current preemption level of the service thread in the variable
591
//pointed to by preemption_level
592
 
593
int
594
fsf_get_service_thread_preemption_level
595
  (fsf_preemption_level_t        *preemption_level) {
596
  return 0;
597
}
598
 
599
 
600
 
601
//fsf_thread_exit: There is a limitation in the current version of the
602
//MaRTE implementation that causes the information of a terminated
603
//thread to continue to be stored in the fsf scheduler, and the thread
604
//to continue to be counted in the number of threads. The
605
//fsf_thread_exit operation allows the implementation to delete the
606
//thread's information, and then terminate the thread. Therefore, it
607
//is recommended to use this function to terminate a thread under fsf.
608
 
609
//This operation shall terminate the calling thread, make the value
610
//value_ptr available to any successful join with the terminating
611
//thread, and unbind the thread from its associated server. After
612
//cleaning up the thread management data, it is unbound and the
613
//scheduling policy is changed to fixed priority before the posix
614
//pthread_exit() function is called.
615
 
616
void
617
fsf_thread_exit (void *value_ptr) {
618
  return;
619
}
620
 
621
 
622
 
623
//fsf_set_shared_obj_preemption_level: The operation updates the
624
//specified shared object by setting its preemption level
625
//to the specified input parameter. 
626
//OBSERVATION: if this value is changed being any contract that
627
//uses the resource already accepted, the system's behavior and
628
//particularly the acceptance tests correctness are not garantee
629
//and probably wrong.
630
 
631
int
632
fsf_set_shared_obj_preemption_level
633
  (fsf_shared_obj_handle_t  obj_handle,
634
   fsf_preemption_level_t   preemption_level) {
635
  return 0;
636
}
637
 
638
 
639
 
640
//fsf_get_shared_obj_preemption_level: The operation obtains from the
641
//specified shared object its preemption level and copies
642
//it to the place pointed to by the specified input parameter.
643
 
644
int
645
fsf_get_shared_obj_preemption_level
646
  (fsf_shared_obj_handle_t  obj_handle,
647
   fsf_preemption_level_t  *preemption_level) {
648
  return 0;
649
}