Subversion Repositories shark

Rev

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