Subversion Repositories shark

Rev

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

Rev Author Line No. Line
221 giacomo 1
//=====================================================================
2
//       FFFFFFIII   RRRRR      SSTTTTTTT
3
//      FF         IIR   RR    SS
4
//     FF           IR        SS
5
//    FFFFFF         RRRR    SSSSST      
6
//   FF       FI       RRR  SS
7
//  FF         II     RRR  SS
8
// FF           IIIIIR    RS 
9
//       
10
// Basic FSF(FIRST Scheduling Framework) contract management
11
// S.Ha.R.K. Implementation
12
//=====================================================================
13
 
14
#include "fsf_contract.h"
15
#include "cbsstar.h"
16
#include "posixstar.h"
17
#include "edfstar.h"
18
#include "posix.h"
19
#include "comm_message.h"
20
 
21
#include <pthread.h>
22
#include <stdlib.h>
23
 
224 giacomo 24
//#define FSF_DEBUG
221 giacomo 25
 
224 giacomo 26
int fsf_cbsstar_level;
27
int fsf_posix_level;
221 giacomo 28
 
224 giacomo 29
int FSF_register_module(int posix_level, int cbsstar_level)
30
{
31
 
32
  printk("FSF Module\n");
33
 
34
  fsf_posix_level = posix_level;
35
  fsf_cbsstar_level = cbsstar_level;
36
 
37
  return 0;
38
 
39
}
40
 
221 giacomo 41
/* Convert the contract specification to
42
 * budget parameters
43
 */
44
int set_CBSSTAR_budget_from_contract
45
  (const fsf_contract_parameters_t *contract,
46
   int *budget)
47
{
48
 
49
  int local_scheduler_level = 0;
50
 
51
   switch (contract->local_scheduler_id) {
52
     case FSF_SCHEDULER_POSIX:
224 giacomo 53
       local_scheduler_level = POSIXSTAR_register_level(fsf_cbsstar_level,5000,32);
221 giacomo 54
       break;
55
     case FSF_SCHEDULER_EDF:
224 giacomo 56
       local_scheduler_level = EDFSTAR_register_level(fsf_cbsstar_level);
221 giacomo 57
       break;
58
     case FSF_SCHEDULER_RM:
59
       break;
60
   }    
61
 
224 giacomo 62
  *budget = CBSSTAR_setbudget(fsf_cbsstar_level,
221 giacomo 63
                              TIMESPEC2USEC(&(contract->budget_min)),
64
                              TIMESPEC2USEC(&(contract->period_max)),
65
                              local_scheduler_level,contract->local_scheduler_id);
66
 
67
  return 0;
68
 
69
}
70
 
71
int adjust_CBSSTAR_budget_from_contract
72
  (const fsf_contract_parameters_t *contract,
73
   int budget)
74
{
75
 
224 giacomo 76
  CBSSTAR_adjust_budget(fsf_cbsstar_level,
221 giacomo 77
                        TIMESPEC2USEC(&(contract->budget_min)),
78
                        TIMESPEC2USEC(&(contract->period_max)),
79
                        budget);
80
 
81
  return 0;
82
 
83
}
84
 
85
/* Admission Test function */
86
int add_contract(const fsf_contract_parameters_t *contract)
87
{
88
 
89
  return 0;
90
 
91
}
92
 
93
int link_contract_to_server(const fsf_contract_parameters_t *contract,
94
                            fsf_server_id_t server)
95
{
96
 
97
  return 0;
98
 
99
}
100
 
101
int remove_contract(fsf_server_id_t server)
102
{
103
 
104
  return 0;
105
 
106
}
107
 
108
 
109
int fsf_negotiate_contract
110
  (const fsf_contract_parameters_t *contract,
111
   fsf_server_id_t                 *server)
112
{
113
 
114
  /* Check if contract is initialized */
115
  if (!contract) return FSF_ERR_NOT_INITIALIZED;
116
 
117
  /* Admission Test */
118
  if (FSF_ADMISSION_TEST_IS_ENABLED)
119
    if (add_contract(contract))
120
      return FSF_ERR_CONTRACT_REJECTED;
121
 
122
  /* SERVER = BUDGET */    
123
  set_CBSSTAR_budget_from_contract(contract,server);
124
 
125
  #ifdef FSF_DEBUG
126
    kern_printf("(New Server %d)",*server);
127
  #endif
128
 
129
  if (*server >= 0)
130
    link_contract_to_server(contract,*server);
131
  else
132
    return FSF_ERR_CREATE_SERVER;
133
 
134
  return 0;
135
 
136
}
137
 
138
int fsf_bind_thread_to_server
139
  (fsf_server_id_t server,
140
   pthread_t       thread,
141
   void            *rt_arg)
142
{
143
 
144
  STD_command_message *msg;
145
  int local_scheduler_level,scheduler_id;
146
 
147
  /* Move thread from the posix module to local scheduler */
148
 
149
  #ifdef FSF_DEBUG 
150
    kern_printf("(Bind thread = %d to Server = %d)",thread,server);
151
  #endif
152
 
153
  /* Check if server and thread exsist */
154
  if (server == -1 || thread == -1)
155
    return FSF_ERR_BIND_THREAD;
156
 
224 giacomo 157
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,server);
158
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,server);
221 giacomo 159
 
160
  /* Check if thread is already bind */
161
  switch (scheduler_id) {
162
    case FSF_SCHEDULER_POSIX:
163
      if (POSIXSTAR_getbudget(local_scheduler_level,thread) != -1)
164
        return FSF_ERR_BIND_THREAD;
165
 
166
      /* Set server on local scheduler */
167
      POSIXSTAR_setbudget(local_scheduler_level,thread,(int)(server));
168
 
169
      /* Send change level command to posix level */
170
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
171
 
234 giacomo 172
      #ifdef FSF_DEBUG
173
         kern_printf("(MSG POSIXSTAR LEV %d SER %d THR %d)",local_scheduler_level,server,thread);
174
      #endif
175
 
221 giacomo 176
      msg->command = STD_SET_NEW_MODEL;
177
      msg->param = (void *)(rt_arg);
178
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
179
 
180
      msg->command = STD_SET_NEW_LEVEL;
181
      msg->param = (void *)(local_scheduler_level);
182
      task_message(msg,thread,0);
183
 
184
      free(msg);
185
 
186
    break;
187
    case FSF_SCHEDULER_EDF:
188
 
189
      if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
190
        return FSF_ERR_BIND_THREAD;
191
 
192
      /* Set server on local scheduler */
193
      EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
194
 
195
      /* Send change level command to posix level */
196
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
197
 
226 giacomo 198
      #ifdef FSF_DEBUG
199
         kern_printf("(MSG EDFSTAR LEV %d SEV %d THR %d)",local_scheduler_level,server,thread);
200
      #endif
201
 
221 giacomo 202
      msg->command = STD_SET_NEW_MODEL;
203
      msg->param = (void *)(rt_arg);
204
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
205
 
206
      msg->command = STD_SET_NEW_LEVEL;
207
      msg->param = (void *)(local_scheduler_level);
208
      task_message(msg,thread,0);
209
 
210
      free(msg);
211
 
212
      break;
213
    case FSF_SCHEDULER_RM:
214
    default:
215
      return FSF_ERR_BIND_THREAD;
216
      break;
217
  }
218
 
219
  return 0;
220
 
221
}
222
 
223
int fsf_unbind_thread_from_server
224
  (pthread_t       thread)
225
{
226
 
227
  int local_scheduler_level, scheduler_id;
228
 
229
  /* Move thread from the local scheduler module to posix level */
230
 
231
  #ifdef FSF_DEBUG
232
    kern_printf("(UnBind thread = %d)",thread);
233
  #endif
234
 
235
  /* Check if thread exsists */
236
  if (thread == -1)
237
    return FSF_ERR_UNBIND_THREAD;
238
 
224 giacomo 239
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
240
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level,thread);
221 giacomo 241
 
242
  switch (scheduler_id) {
243
    case FSF_SCHEDULER_POSIX:
244
      /* Check if it is bind to a server */
245
      if (POSIXSTAR_getbudget(local_scheduler_level,thread) == -1)
246
        return FSF_ERR_UNBIND_THREAD;
247
      else {
248
 
249
        STD_command_message *msg;
250
        NRT_TASK_MODEL nrt;
251
 
252
        nrt_task_default_model(nrt);
253
        nrt_task_def_save_arrivals(nrt);
254
 
255
        /* Send change level command to local scheduler */
256
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
257
 
258
        msg->command = STD_SET_NEW_MODEL;
259
        msg->param = (void *)(&nrt);
224 giacomo 260
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 261
 
262
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 263
        msg->param = (void *)(fsf_posix_level);
221 giacomo 264
        task_message(msg,thread,0);
265
 
266
        free(msg);
267
 
268
      }
269
    break;
270
    case FSF_SCHEDULER_EDF:
271
 
272
      if (EDFSTAR_getbudget(local_scheduler_level,thread) == -1)
273
        return FSF_ERR_UNBIND_THREAD;
274
      else {
275
 
276
        STD_command_message *msg;
277
        NRT_TASK_MODEL nrt;
278
 
279
        nrt_task_default_model(nrt);
280
        nrt_task_def_save_arrivals(nrt);
281
 
282
        /* Send change level command to local scheduler */
283
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
284
 
285
        msg->command = STD_SET_NEW_MODEL;
286
        msg->param = (void *)(&nrt);
224 giacomo 287
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 288
 
289
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 290
        msg->param = (void *)(fsf_posix_level);
221 giacomo 291
        task_message(msg,thread,0);
292
 
293
        free(msg);
294
 
295
      }
296
      break;
297
 
298
    case FSF_SCHEDULER_RM:
299
      break;
300
  }
301
 
302
  return 0;
303
 
304
}
305
 
306
int fsf_negotiate_contract_for_new_thread
307
  (const fsf_contract_parameters_t *contract,
308
   fsf_server_id_t      *server,
309
   pthread_t            *thread,
310
   pthread_attr_t       *attr,
311
   fsf_thread_code_t     thread_code,
312
   void                 *arg,
313
   void                 *rt_arg)
314
 
315
{
316
 
317
  int error;
318
 
319
  /* Create server */
320
  error = fsf_negotiate_contract(contract, server);
321
  if (error) return error;
322
 
323
  /* Create pthread */
324
  if (pthread_create(thread, attr, thread_code, arg))
325
    return FSF_ERR_CREATE_THREAD;
326
 
327
  /* Bind thread to server */
328
  error = fsf_bind_thread_to_server(*server, *thread, rt_arg);
329
  if (error) return error;
330
 
331
  return 0;
332
 
333
}
334
 
335
int fsf_negotiate_contract_for_myself
336
  (const fsf_contract_parameters_t *contract,
337
   fsf_server_id_t *server,
338
   void            *rt_arg)
339
{
340
 
341
  int error;
342
 
343
  /* Create server */
344
  error = fsf_negotiate_contract(contract, server);
345
  if (error) return error;
346
 
347
  /* Bind current thread to server */
348
  error = fsf_bind_thread_to_server(*server, exec_shadow, rt_arg);
349
  if (error) return error;
350
 
351
  return 0;
352
 
353
}
354
 
355
int fsf_get_server
356
  (fsf_server_id_t *server,
357
   pthread_t       thread)
358
{
359
  int local_scheduler_level, scheduler_id;
360
 
224 giacomo 361
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
362
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, thread);
221 giacomo 363
 
364
  switch (scheduler_id) {
365
    case FSF_SCHEDULER_POSIX:  
366
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
367
    case FSF_SCHEDULER_EDF:
368
    case FSF_SCHEDULER_RM:
369
      return -1;
370
  }
371
 
372
  return -1;
373
 
374
}
375
 
376
int fsf_cancel_contract
377
  (fsf_server_id_t *server)
378
{
379
 
380
  int local_scheduler_level, scheduler_id;
381
 
382
  #ifdef FSF_DEBUG
383
    kern_printf("(Remove server %d)",*server);
384
  #endif
385
 
386
  /* Check server id */
387
  if (*server < 0)
388
    return FSF_ERR_INVALID_SERVER;
389
 
224 giacomo 390
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,*server);
391
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,*server);
221 giacomo 392
 
393
  switch (scheduler_id) {
394
    case FSF_SCHEDULER_POSIX:
395
 
396
      /* Check if some thread use the server */
397
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
398
        return FSF_ERR_SERVER_USED;
399
 
400
      break;
401
    case FSF_SCHEDULER_EDF:
402
    case FSF_SCHEDULER_RM:
403
      break;
404
  }
405
 
224 giacomo 406
  CBSSTAR_removebudget(fsf_cbsstar_level,*server);
221 giacomo 407
 
408
  level_free_descriptor(local_scheduler_level);
409
 
410
  remove_contract(*server);
411
 
412
  *server = -1;
413
 
414
  return 0;
415
 
416
}
417
 
418
int fsf_renegotiate_contract
419
  (const fsf_contract_parameters_t *new_contract,
420
   fsf_server_id_t server)
421
{
422
 
423
  #ifdef FSF_DEBUG
424
    kern_printf("(Renegotiate for server %d)",server);
425
  #endif
426
 
427
  if (!new_contract)
428
    return FSF_ERR_NOT_INITIALIZED;
429
 
430
  if (server < 0)
431
    return FSF_ERR_INVALID_SERVER;
432
 
433
  return adjust_CBSSTAR_budget_from_contract(new_contract,server);
434
 
435
}