Subversion Repositories shark

Rev

Rev 221 | Rev 226 | 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
 
172
      msg->command = STD_SET_NEW_MODEL;
173
      msg->param = (void *)(rt_arg);
174
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
175
 
176
      msg->command = STD_SET_NEW_LEVEL;
177
      msg->param = (void *)(local_scheduler_level);
178
      task_message(msg,thread,0);
179
 
180
      free(msg);
181
 
182
    break;
183
    case FSF_SCHEDULER_EDF:
184
 
185
      if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
186
        return FSF_ERR_BIND_THREAD;
187
 
188
      /* Set server on local scheduler */
189
      EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
190
 
191
      /* Send change level command to posix level */
192
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
193
 
194
      msg->command = STD_SET_NEW_MODEL;
195
      msg->param = (void *)(rt_arg);
196
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
197
 
198
      msg->command = STD_SET_NEW_LEVEL;
199
      msg->param = (void *)(local_scheduler_level);
200
      task_message(msg,thread,0);
201
 
202
      free(msg);
203
 
204
      break;
205
    case FSF_SCHEDULER_RM:
206
    default:
207
      return FSF_ERR_BIND_THREAD;
208
      break;
209
  }
210
 
211
  return 0;
212
 
213
}
214
 
215
int fsf_unbind_thread_from_server
216
  (pthread_t       thread)
217
{
218
 
219
  int local_scheduler_level, scheduler_id;
220
 
221
  /* Move thread from the local scheduler module to posix level */
222
 
223
  #ifdef FSF_DEBUG
224
    kern_printf("(UnBind thread = %d)",thread);
225
  #endif
226
 
227
  /* Check if thread exsists */
228
  if (thread == -1)
229
    return FSF_ERR_UNBIND_THREAD;
230
 
224 giacomo 231
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
232
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level,thread);
221 giacomo 233
 
234
  switch (scheduler_id) {
235
    case FSF_SCHEDULER_POSIX:
236
      /* Check if it is bind to a server */
237
      if (POSIXSTAR_getbudget(local_scheduler_level,thread) == -1)
238
        return FSF_ERR_UNBIND_THREAD;
239
      else {
240
 
241
        STD_command_message *msg;
242
        NRT_TASK_MODEL nrt;
243
 
244
        nrt_task_default_model(nrt);
245
        nrt_task_def_save_arrivals(nrt);
246
 
247
        /* Send change level command to local scheduler */
248
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
249
 
250
        msg->command = STD_SET_NEW_MODEL;
251
        msg->param = (void *)(&nrt);
224 giacomo 252
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 253
 
254
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 255
        msg->param = (void *)(fsf_posix_level);
221 giacomo 256
        task_message(msg,thread,0);
257
 
258
        free(msg);
259
 
260
      }
261
    break;
262
    case FSF_SCHEDULER_EDF:
263
 
264
      if (EDFSTAR_getbudget(local_scheduler_level,thread) == -1)
265
        return FSF_ERR_UNBIND_THREAD;
266
      else {
267
 
268
        STD_command_message *msg;
269
        NRT_TASK_MODEL nrt;
270
 
271
        nrt_task_default_model(nrt);
272
        nrt_task_def_save_arrivals(nrt);
273
 
274
        /* Send change level command to local scheduler */
275
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
276
 
277
        msg->command = STD_SET_NEW_MODEL;
278
        msg->param = (void *)(&nrt);
224 giacomo 279
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 280
 
281
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 282
        msg->param = (void *)(fsf_posix_level);
221 giacomo 283
        task_message(msg,thread,0);
284
 
285
        free(msg);
286
 
287
      }
288
      break;
289
 
290
    case FSF_SCHEDULER_RM:
291
      break;
292
  }
293
 
294
  return 0;
295
 
296
}
297
 
298
int fsf_negotiate_contract_for_new_thread
299
  (const fsf_contract_parameters_t *contract,
300
   fsf_server_id_t      *server,
301
   pthread_t            *thread,
302
   pthread_attr_t       *attr,
303
   fsf_thread_code_t     thread_code,
304
   void                 *arg,
305
   void                 *rt_arg)
306
 
307
{
308
 
309
  int error;
310
 
311
  /* Create server */
312
  error = fsf_negotiate_contract(contract, server);
313
  if (error) return error;
314
 
315
  /* Create pthread */
316
  if (pthread_create(thread, attr, thread_code, arg))
317
    return FSF_ERR_CREATE_THREAD;
318
 
319
  /* Bind thread to server */
320
  error = fsf_bind_thread_to_server(*server, *thread, rt_arg);
321
  if (error) return error;
322
 
323
  return 0;
324
 
325
}
326
 
327
int fsf_negotiate_contract_for_myself
328
  (const fsf_contract_parameters_t *contract,
329
   fsf_server_id_t *server,
330
   void            *rt_arg)
331
{
332
 
333
  int error;
334
 
335
  /* Create server */
336
  error = fsf_negotiate_contract(contract, server);
337
  if (error) return error;
338
 
339
  /* Bind current thread to server */
340
  error = fsf_bind_thread_to_server(*server, exec_shadow, rt_arg);
341
  if (error) return error;
342
 
343
  return 0;
344
 
345
}
346
 
347
int fsf_get_server
348
  (fsf_server_id_t *server,
349
   pthread_t       thread)
350
{
351
  int local_scheduler_level, scheduler_id;
352
 
224 giacomo 353
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
354
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, thread);
221 giacomo 355
 
356
  switch (scheduler_id) {
357
    case FSF_SCHEDULER_POSIX:  
358
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
359
    case FSF_SCHEDULER_EDF:
360
    case FSF_SCHEDULER_RM:
361
      return -1;
362
  }
363
 
364
  return -1;
365
 
366
}
367
 
368
int fsf_cancel_contract
369
  (fsf_server_id_t *server)
370
{
371
 
372
  int local_scheduler_level, scheduler_id;
373
 
374
  #ifdef FSF_DEBUG
375
    kern_printf("(Remove server %d)",*server);
376
  #endif
377
 
378
  /* Check server id */
379
  if (*server < 0)
380
    return FSF_ERR_INVALID_SERVER;
381
 
224 giacomo 382
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,*server);
383
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,*server);
221 giacomo 384
 
385
  switch (scheduler_id) {
386
    case FSF_SCHEDULER_POSIX:
387
 
388
      /* Check if some thread use the server */
389
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
390
        return FSF_ERR_SERVER_USED;
391
 
392
      break;
393
    case FSF_SCHEDULER_EDF:
394
    case FSF_SCHEDULER_RM:
395
      break;
396
  }
397
 
224 giacomo 398
  CBSSTAR_removebudget(fsf_cbsstar_level,*server);
221 giacomo 399
 
400
  level_free_descriptor(local_scheduler_level);
401
 
402
  remove_contract(*server);
403
 
404
  *server = -1;
405
 
406
  return 0;
407
 
408
}
409
 
410
int fsf_renegotiate_contract
411
  (const fsf_contract_parameters_t *new_contract,
412
   fsf_server_id_t server)
413
{
414
 
415
  #ifdef FSF_DEBUG
416
    kern_printf("(Renegotiate for server %d)",server);
417
  #endif
418
 
419
  if (!new_contract)
420
    return FSF_ERR_NOT_INITIALIZED;
421
 
422
  if (server < 0)
423
    return FSF_ERR_INVALID_SERVER;
424
 
425
  return adjust_CBSSTAR_budget_from_contract(new_contract,server);
426
 
427
}