Subversion Repositories shark

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1085 pj 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/**
20
 ------------
21
 CVS :        $Id: static.c,v 1.1.1.1 2002-09-02 09:37:48 pj Exp $
22
 
23
 File:        $File$
24
 Revision:    $Revision: 1.1.1.1 $
25
 Last update: $Date: 2002-09-02 09:37:48 $
26
 ------------
27
**/
28
 
29
/*
30
 * Copyright (C) 2001 Paolo Gai
31
 *
32
 * This program is free software; you can redistribute it and/or modify
33
 * it under the terms of the GNU General Public License as published by
34
 * the Free Software Foundation; either version 2 of the License, or
35
 * (at your option) any later version.
36
 *
37
 * This program is distributed in the hope that it will be useful,
38
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40
 * GNU General Public License for more details.
41
 *
42
 * You should have received a copy of the GNU General Public License
43
 * along with this program; if not, write to the Free Software
44
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
45
 *
46
 */
47
 
48
#include "static.h"
49
#include <ll/stdio.h>
50
#include <ll/string.h>
51
#include <kernel/model.h>
52
#include <kernel/descr.h>
53
#include <kernel/var.h>
54
#include <kernel/func.h>
55
#include <kernel/trace.h>
56
 
57
#define STATIC_printf kern_printf
58
//#define STATIC_printf printk
59
 
60
/*+ Status used in the level +*/
61
#define STATIC_READY         MODULE_STATUS_BASE    /*+ - Ready status        +*/
62
#define STATIC_IDLE          MODULE_STATUS_BASE+4  /*+ to wait the deadline  +*/
63
 
64
/*+ flags +*/
65
#define STATIC_FLAG_NORAISEEXC  2
66
 
67
/*+ the level redefinition for the Earliest Deadline First level +*/
68
typedef struct {
69
  level_des l;     /*+ the standard level descriptor          +*/
70
 
71
  QUEUE mytable;
72
 
73
  PID currenttask;
74
 
75
  struct timespec hp;
76
  struct timespec ref;
77
 
78
} STATIC_level_des;
79
 
80
static void STATIC_offset_activate(void *par)
81
{
82
  PID p = (PID) par;
83
  STATIC_level_des *lev;
84
 
85
  lev = (STATIC_level_des *)level_table[proc_table[p].task_level];
86
 
87
  lev->currenttask = p;
88
  event_need_reschedule();
89
 
90
  STATIC_printf("(o p%d t%d)", p, (int)proc_table[p].timespec_priority.tv_sec);
91
}
92
 
93
static void STATIC_activateall(STATIC_level_des *lev)
94
{
95
  PID my_table_index;
96
  struct timespec x;
97
 
98
  STATIC_printf("(A ");
99
 
100
  for (my_table_index = (PID)lev->mytable;
101
       my_table_index != NIL;
102
       my_table_index = proc_table[my_table_index].next) {
103
    ADDTIMESPEC(&lev->ref,&proc_table[my_table_index].timespec_priority,&x);
104
    kern_event_post(&x, STATIC_offset_activate,(void *)my_table_index);
105
 
106
    STATIC_printf("|p%d t%d ",
107
                  my_table_index,
108
                  (int)proc_table[my_table_index].timespec_priority.tv_sec);
109
  }
110
 
111
  STATIC_printf(")");
112
 
113
}
114
 
115
static void STATIC_hyperperiod(void *par)
116
{
117
  STATIC_level_des *lev;
118
  struct timespec x;
119
 
120
  lev = (STATIC_level_des *)level_table[(LEVEL)par];
121
 
122
  STATIC_printf("(hp %d)", (int)lev->ref.tv_sec);
123
 
124
  STATIC_activateall(lev);
125
 
126
  ADDTIMESPEC(&lev->ref, &lev->hp, &x);
127
  lev->ref = x;
128
 
129
  kern_event_post(&x, STATIC_hyperperiod, par);
130
}
131
 
132
 
133
static int STATIC_level_accept_task_model(LEVEL l, TASK_MODEL *m)
134
{
135
  if (m->pclass == STATIC_PCLASS || m->pclass == (STATIC_PCLASS | l))
136
    return 0;
137
 
138
  return -1;
139
}
140
 
141
static int STATIC_level_accept_guest_model(LEVEL l, TASK_MODEL *m)
142
{
143
  return -1;
144
}
145
 
146
 
147
 
148
static void STATIC_level_status(LEVEL l)
149
{ kern_raise(XUNVALID_TASK,exec_shadow); }
150
 
151
/* The scheduler only gets the first task in the queue */
152
static PID STATIC_level_scheduler(LEVEL l)
153
{
154
  STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
155
 
156
  return lev->currenttask;
157
}
158
 
159
/* The on-line guarantee is enabled only if the appropriate flag is set... */
160
static int STATIC_level_guarantee(LEVEL l, bandwidth_t *freebandwidth)
161
{
162
  return 1;
163
}
164
 
165
static int STATIC_task_create(LEVEL l, PID p, TASK_MODEL *m)
166
{
167
  STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
168
 
169
  /* if the STATIC_task_create is called, then the pclass must be a
170
     valid pclass. */
171
 
172
  STATIC_TASK_MODEL *h = (STATIC_TASK_MODEL *)m;
173
 
174
  proc_table[p].timespec_priority.tv_sec = h->offset.tv_sec;
175
  proc_table[p].timespec_priority.tv_nsec = h->offset.tv_nsec;
176
  q_timespec_insert(p,&lev->mytable);
177
 
178
  return 0; /* OK, also if the task cannot be guaranteed... */
179
}
180
 
181
static void STATIC_task_detach(LEVEL l, PID p)
182
{
183
}
184
 
185
static int STATIC_task_eligible(LEVEL l, PID p)
186
{
187
  return 0; /* if the task p is chosen, it is always eligible */
188
}
189
 
190
static void STATIC_task_dispatch(LEVEL l, PID p, int nostop)
191
{
192
}
193
 
194
static void STATIC_task_epilogue(LEVEL l, PID p)
195
{
196
}
197
 
198
static void STATIC_task_activate(LEVEL l, PID p)
199
{
200
}
201
 
202
static void STATIC_task_insert(LEVEL l, PID p)
203
{
204
}
205
 
206
static void STATIC_task_extract(LEVEL l, PID p)
207
{
208
}
209
 
210
static void STATIC_task_endcycle(LEVEL l, PID p)
211
{
212
  STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
213
 
214
  lev->currenttask = NIL;
215
}
216
 
217
static void STATIC_task_end(LEVEL l, PID p)
218
{
219
  STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
220
 
221
  lev->currenttask = NIL;
222
 
223
  q_extract(p,&lev->mytable);
224
 
225
  /* we finally put the task in the ready queue */
226
  proc_table[p].status = FREE;
227
  q_insertfirst(p,&freedesc);
228
}
229
 
230
static void STATIC_task_sleep(LEVEL l, PID p)
231
{ kern_raise(XUNVALID_TASK,exec_shadow); }
232
 
233
static void STATIC_task_delay(LEVEL l, PID p, TIME usdelay)
234
{ kern_raise(XUNVALID_TASK,exec_shadow); }
235
 
236
/* Guest Functions
237
   These functions manages a JOB_TASK_MODEL, that is used to put
238
   a guest task in the STATIC ready queue. */
239
 
240
static int STATIC_guest_create(LEVEL l, PID p, TASK_MODEL *m)
241
{ kern_raise(XUNVALID_GUEST,exec_shadow); return 0; }
242
 
243
static void STATIC_guest_detach(LEVEL l, PID p)
244
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
245
 
246
static void STATIC_guest_dispatch(LEVEL l, PID p, int nostop)
247
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
248
 
249
static void STATIC_guest_epilogue(LEVEL l, PID p)
250
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
251
 
252
static void STATIC_guest_activate(LEVEL l, PID p)
253
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
254
 
255
static void STATIC_guest_insert(LEVEL l, PID p)
256
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
257
 
258
static void STATIC_guest_extract(LEVEL l, PID p)
259
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
260
 
261
static void STATIC_guest_endcycle(LEVEL l, PID p)
262
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
263
 
264
static void STATIC_guest_end(LEVEL l, PID p)
265
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
266
 
267
static void STATIC_guest_sleep(LEVEL l, PID p)
268
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
269
 
270
static void STATIC_guest_delay(LEVEL l, PID p, TIME usdelay)
271
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
272
 
273
/* Registration functions */
274
 
275
/*+ Registration function:
276
    int flags                 the init flags ... see STATIC.h +*/
277
void STATIC_register_level()
278
{
279
  LEVEL l;            /* the level that we register */
280
  STATIC_level_des *lev;  /* for readableness only */
281
 
282
  printk("STATIC_register_level\n");
283
 
284
  /* request an entry in the level_table */
285
  l = level_alloc_descriptor();
286
 
287
  printk("    alloco descrittore %d %d\n",l,(int)sizeof(STATIC_level_des));
288
 
289
  /* alloc the space needed for the STATIC_level_des */
290
  lev = (STATIC_level_des *)kern_alloc(sizeof(STATIC_level_des));
291
 
292
  printk("    lev=%d\n",(int)lev);
293
 
294
  /* update the level_table with the new entry */
295
  level_table[l] = (level_des *)lev;
296
 
297
  /* fill the standard descriptor */
298
  strncpy(lev->l.level_name,  STATIC_LEVELNAME, MAX_LEVELNAME);
299
  lev->l.level_code               = STATIC_LEVEL_CODE;
300
  lev->l.level_version            = STATIC_LEVEL_VERSION;
301
 
302
  lev->l.level_accept_task_model  = STATIC_level_accept_task_model;
303
  lev->l.level_accept_guest_model = STATIC_level_accept_guest_model;
304
  lev->l.level_status             = STATIC_level_status;
305
  lev->l.level_scheduler          = STATIC_level_scheduler;
306
 
307
  lev->l.level_guarantee        = NULL;
308
 
309
  lev->l.task_create              = STATIC_task_create;
310
  lev->l.task_detach              = STATIC_task_detach;
311
  lev->l.task_eligible            = STATIC_task_eligible;
312
  lev->l.task_dispatch            = STATIC_task_dispatch;
313
  lev->l.task_epilogue            = STATIC_task_epilogue;
314
  lev->l.task_activate            = STATIC_task_activate;
315
  lev->l.task_insert              = STATIC_task_insert;
316
  lev->l.task_extract             = STATIC_task_extract;
317
  lev->l.task_endcycle            = STATIC_task_endcycle;
318
  lev->l.task_end                 = STATIC_task_end;
319
  lev->l.task_sleep               = STATIC_task_sleep;
320
  lev->l.task_delay               = STATIC_task_delay;
321
 
322
  lev->l.guest_create             = STATIC_guest_create;
323
  lev->l.guest_detach             = STATIC_guest_detach;
324
  lev->l.guest_dispatch           = STATIC_guest_dispatch;
325
  lev->l.guest_epilogue           = STATIC_guest_epilogue;
326
  lev->l.guest_activate           = STATIC_guest_activate;
327
  lev->l.guest_insert             = STATIC_guest_insert;
328
  lev->l.guest_extract            = STATIC_guest_extract;
329
  lev->l.guest_endcycle           = STATIC_guest_endcycle;
330
  lev->l.guest_end                = STATIC_guest_end;
331
  lev->l.guest_sleep              = STATIC_guest_sleep;
332
  lev->l.guest_delay              = STATIC_guest_delay;
333
 
334
  /* fill the STATIC descriptor part */
335
 
336
  lev->mytable = NIL;
337
  lev->currenttask = NIL;
338
 
339
  NULL_TIMESPEC(&lev->hp);
340
  NULL_TIMESPEC(&lev->ref);
341
}
342
 
343
void STATIC_start(LEVEL l, struct timespec *h, struct timespec *o)
344
{
345
  STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
346
  struct timespec x;
347
 
348
  kern_cli();
349
  ll_gettime(TIME_EXACT, &x);
350
  lev->hp = *h;
351
 
352
  ADDTIMESPEC(&x,o,&lev->ref);
353
  STATIC_printf("(ST: ref:%d.%d x:%d.%d)\n",
354
                (int)lev->ref.tv_sec, (int)lev->ref.tv_nsec,
355
                (int)x.tv_sec, (int)x.tv_nsec);
356
 
357
  kern_event_post(&x, STATIC_hyperperiod,(void *)l);
358
 
359
  kern_sti();
360
}
361
 
362