Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1175 → Rev 1176

/demos/trunk/first/cbsstar.c
20,11 → 20,11
 
/*
------------
CVS : $Id: cbsstar.c,v 1.4 2003-01-07 17:10:16 pj Exp $
CVS : $Id: cbsstar.c,v 1.5 2003-06-18 08:13:01 trimarchi Exp $
 
File: $File$
Revision: $Revision: 1.4 $
Last update: $Date: 2003-01-07 17:10:16 $
Revision: $Revision: 1.5 $
Last update: $Date: 2003-06-18 08:13:01 $
------------
 
Read CBSSTAR.h for general details.
75,10 → 75,8
* DEBUG stuffs begin
*/
 
//#define CBSSTAR_DEBUG
#ifdef CBSSTAR_DEBUG_OLD
 
#ifdef CBSSTAR_DEBUG
 
static __inline__ void fake_printf(char *fmt, ...) {}
 
//#define cbsstar_printf kern_printf
89,8 → 87,8
#define cbsstar_printf2 fake_printf
#define cbsstar_printf3 fake_printf
 
#if 0
void cbsstar_printq(QQUEUE *q)
#if 0
void cbsstar_printq(IQUEUE *q)
{
PID p;
kern_printf("[");
106,7 → 104,7
static __inline__ void cbsstar_printq(QQUEUE *q) {}
#endif
 
#if 0
#if 0
static __inline__ void cbsstar_printblob(int x) { if (x) cputc('±'); else cputc('Û'); }
#else
static __inline__ void cbsstar_printblob(int x) {}
123,7 → 121,7
struct budget_struct {
TIME Q; /* budget */
TIME T; /* period */
 
struct timespec dline; /* deadline */
int dline_timer; /* oslib event for budget reactivation*/
int avail; /* current budget */
144,6 → 142,8
int tb[MAX_PROC]; /* link task->budget (used in guest_end) */
 
bandwidth_t U; /*+ the used bandwidth by the server +*/
int cap_lev;
 
LEVEL scheduling_level;
 
185,10 → 185,11
*/ /* we modify the deadline ... */
TIMESPEC_ASSIGN(&b->dline, acttime);
ADDUSEC2TIMESPEC(b->T, &b->dline);
 
/* and the capacity */
b->avail = b->Q;
 
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf3("±%d±",lev->tb[p]);
cbsstar_printblob(lev->tb[p]);
201,7 → 202,7
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(C:iact p%d %ld.%ld av=%d)",p,b->dline.tv_sec,b->dline.tv_nsec/1000, b->avail);
#endif
 
//kern_printf("Pid %d, Act %d, Dd %d", p,acttime->tv_nsec/1000,(b->dline).tv_nsec/1000);
/* and, finally, we reinsert the task in the master level */
job_task_default_model(job, b->dline);
job_task_def_noexc(job);
259,7 → 260,7
article because if there is only the standard scheduling policy
this never apply) we reassign the deadline */
 
if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time) ) {
if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time) ) {
/* we kill the current activation */
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, p);
276,7 → 277,6
cbsstar_printf3("±%d±",lev->tb[p]);
cbsstar_printblob(lev->tb[p]);
#endif
 
/* and, finally, we reinsert the task in the master level */
job_task_default_model(job, b->dline);
job_task_def_noexc(job);
292,6 → 292,7
return 0;
}
 
 
static void CBSSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
{
/* A task has been activated for some reason. Basically, the task is
381,6 → 382,14
iq_extract(p, &lev->b[lev->tb[p]].tasks);
}
 
static void capacity_handler()
{
//kern_printf("!");
event_need_reschedule();
}
 
 
static void CBSSTAR_private_dispatch(LEVEL l, PID p, int nostop)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
404,8 → 413,8
if (!nostop) {
TIMESPEC_ASSIGN(&ty, &schedule_time);
ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty);
cap_timer = kern_event_post(&ty, capacity_timer, NULL);
}
lev->cap_lev = kern_event_post(&ty, capacity_handler, NULL);
}
}
 
static void CBSSTAR_private_epilogue(LEVEL l, PID p)
413,12 → 422,16
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
struct budget_struct *b = &lev->b[lev->tb[p]];
 
#ifdef CBSSTAR_DEBUG
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(C:gepi %d",p);
#endif
#endif
 
CBSSTAR_account_capacity(lev,p);
 
if (lev->cap_lev!=NIL)
kern_event_delete(lev->cap_lev);
lev->cap_lev=NIL;
 
/* we have to check if the capacity is still available */
if (b->avail > 0) {
/* there is capacity available, maybe it is simply a preemption;
425,10 → 438,11
the task have to return to the ready queue */
level_table[ lev->scheduling_level ]->
private_epilogue(lev->scheduling_level,p);
#ifdef CBSSTAR_DEBUG
cbsstar_printf2(" *av=%d", b->avail);
#endif
#ifdef CBSSTAR_DEBUG
cbsstar_printf(" *av=%d", b->avail);
#endif
} else {
 
/* The capacity is exausted; the deadline have to be postponed and
the task have to be reinserted in the master module */
JOB_TASK_MODEL job;
443,15 → 457,14
while (b->avail <= 0) {
ADDUSEC2TIMESPEC(b->T, &b->dline);
b->avail += b->Q;
#ifdef CBSSTAR_DEBUG
cbsstar_printf3("±%d±",lev->tb[p]);
cbsstar_printblob(lev->tb[p]);
#endif
#ifdef CBSSTAR_DEBUG
cbsstar_printf("±%d±",b->avail);
#endif
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf2(" %ld.%ld av=%d",b->dline.tv_sec,b->dline.tv_nsec/1000, b->avail);
#endif
#ifdef CBSSTAR_DEBUG
kern_printf(" %ld.%ld av=%d",b->dline.tv_sec,b->dline.tv_nsec/1000, b->avail);
#endif
/* and, finally, we reinsert the task in the master level */
job_task_default_model(job, b->dline);
462,6 → 475,7
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
}
 
 
510,12 → 524,11
 
lev->n = n;
lev->freebudgets = 0;
 
for (i=0; i<MAX_PROC; i++)
lev->tb[i] = NIL;
 
lev->U = 0;
 
lev->cap_lev=NIL;
lev->scheduling_level = master;
 
return l;
/demos/trunk/first/edfstar.c
18,11 → 18,11
 
/**
------------
CVS : $Id: edfstar.c,v 1.4 2003-01-07 17:10:16 pj Exp $
CVS : $Id: edfstar.c,v 1.5 2003-06-18 08:13:02 trimarchi Exp $
 
File: $File$
Revision: $Revision: 1.4 $
Last update: $Date: 2003-01-07 17:10:16 $
Revision: $Revision: 1.5 $
Last update: $Date: 2003-06-18 08:13:02 $
------------
**/
 
264,7 → 264,7
return 0; /* OK, also if the task cannot be guaranteed... */
}
 
static int EDFSTAR_task_eligible(LEVEL l, PID p)
static int EDFSTAR_public_eligible(LEVEL l, PID p)
{
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
 
586,6 → 586,7
lev->l.private_epilogue = EDFSTAR_private_epilogue;
 
lev->l.public_guarantee = NULL;
lev->l.public_eligible = EDFSTAR_public_eligible;
lev->l.public_create = EDFSTAR_public_create;
lev->l.public_end = EDFSTAR_public_end;
lev->l.public_dispatch = EDFSTAR_public_dispatch;
/demos/trunk/first/makefile
7,7 → 7,7
endif
include $(BASE)/config/config.mk
 
PROGS= test1 test2 test3 test4 test5 test6 testiq
PROGS= test1 test2 test3 test4 test5 test6 test7 testiq
 
include $(BASE)/config/example.mk
 
29,5 → 29,8
test6:
make -f $(SUBMAKE) APP=test6 INIT= OTHEROBJS="rmstar.o cbsstar.o" OTHERINCL= SHARKOPT=__OLDCHAR__
 
test7:
make -f $(SUBMAKE) APP=test7 INIT= OTHEROBJS="posixstar.o cbsstar.o" OTHERINCL= SHARKOPT=__OLDCHAR__
 
#testiq:
# make -f $(SUBMAKE) APP=testiq INIT= OTHEROBJS="iqueue.o " OTHERINCL=
/demos/trunk/first/posixstar.c
0,0 → 1,529
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Trimarchi Michael <trimarchi@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
 
/**
------------
CVS : $Id: posixstar.c,v 1.1 2003-06-18 08:13:02 trimarchi Exp $
 
File: $File$
Revision: $Revision: 1.1 $
Last update: $Date: 2003-06-18 08:13:02 $
------------
 
This file contains the scheduling module compatible with POSIX
specifications
 
Read posixstar.h for further details.
 
RR tasks have the CONTROL_CAP bit set
 
**/
 
/*
* Copyright (C) 2000 Paolo Gai
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARR2ANTY; without even the implied waRR2anty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
 
 
#include <ll/stdio.h>
#include <ll/string.h>
#include <kernel/model.h>
#include <kernel/descr.h>
#include <kernel/var.h>
#include <kernel/func.h>
#include <kernel/trace.h>
#include "posixstar.h"
#include "cbsstar.h"
//#define POSIXSTAR_DEBUG
/*+ Status used in the level +*/
#define POSIXSTAR_READY MODULE_STATUS_BASE
 
/*+ the level redefinition for the Round Robin level +*/
typedef struct {
level_des l; /*+ the standard level descriptor +*/
 
int nact[MAX_PROC]; /*+ number of pending activations +*/
int priority[MAX_PROC]; /*+ priority of each task +*/
 
IQUEUE *ready; /*+ the ready queue array +*/
 
int slice; /*+ the level's time slice +*/
 
// the multiboot is not usefull for this module
// struct multiboot_info *multiboot; /*+ used if the level have to insert
// the main task +*/
int maxpriority; /*+ the priority are from 0 to maxpriority
(i.e 0 to 31) +*/
 
int yielding; /*+ equal to 1 when a sched_yield is called +*/
 
int budget;
 
PID activated;
int scheduling_level;
} POSIXSTAR_level_des;
 
/* the private scheduler choice a task and insert in cbsstar module */
/* This is not efficient but very fair :-)
The need of all this stuff is because if a task execute a long time
due to (shadow!) priority inheritance, then the task shall go to the
tail of the queue many times... */
 
static void POSIXSTAR_private_scheduler(POSIXSTAR_level_des * lev)
{
/* the old posix scheduler select the private job for CBS */
PID p=NIL;
 
int prio;
 
prio = lev->maxpriority;
 
for (;;) {
p = iq_query_first(&lev->ready[prio]);
if (p == NIL) {
if (prio) {
prio--;
continue;
}
else {
p=NIL;
break;
}
}
//if (p != NIL && (proc_table[p].control & CONTROL_CAP))
// kern_printf("CC SET %d",p);
//kern_printf("task %d", p);
 
if ((proc_table[p].control & CONTROL_CAP) &&
(proc_table[p].avail_time <= 0)) {
proc_table[p].avail_time += proc_table[p].wcet;
//kern_printf("RR policy");
iq_extract(p,&lev->ready[prio]);
iq_insertlast(p,&lev->ready[prio]);
}
else {
break;
}
}
 
if (p!=lev->activated) {
if (lev->activated != NIL ) {
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, lev->activated);
//kern_printf("CBS ext %d", lev->activated);
}
lev->activated = p;
if (p != NIL) {
BUDGET_TASK_MODEL b;
budget_task_default_model(b, lev->budget);
// viene inserito nel CBS
//#ifdef POSIXSTAR_DEBUG
//kern_printf("CBS Ins %d",p);
//#endif
level_table[ lev->scheduling_level ]->
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&b);
}
}
}
 
static int POSIXSTAR_public_eligible(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
if (p==lev->activated) {
//kern_printf("eli %d", p);
 
return level_table[ lev->scheduling_level ]->
private_eligible(lev->scheduling_level,p);
}
return 0;
}
 
static int POSIXSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
NRT_TASK_MODEL *nrt;
 
if (m->pclass != NRT_PCLASS) return -1;
if (m->level != 0 && m->level != l) return -1;
 
nrt = (NRT_TASK_MODEL *)m;
 
/* the task state is set at SLEEP by the general task_create */
 
/* I used the wcet field because using wcet can account if a task
consume more than the timeslice... */
 
if (nrt->inherit == NRT_INHERIT_SCHED &&
proc_table[exec_shadow].task_level == l) {
/* We inherit the scheduling properties if the scheduling level
*is* the same */
lev->priority[p] = lev->priority[exec_shadow];
proc_table[p].avail_time = proc_table[exec_shadow].avail_time;
proc_table[p].wcet = proc_table[exec_shadow].wcet;
 
proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP) |
(proc_table[exec_shadow].control & CONTROL_CAP);
lev->nact[p] = (lev->nact[exec_shadow] == -1) ? -1 : 0;
}
else {
if (nrt->weight<=lev->maxpriority)
lev->priority[p] = nrt->weight;
else lev->priority[p]=lev->maxpriority;
if (nrt->slice) {
proc_table[p].avail_time = nrt->slice;
proc_table[p].wcet = nrt->slice;
}
else {
proc_table[p].avail_time = lev->slice;
proc_table[p].wcet = lev->slice;
}
if (nrt->policy == NRT_RR_POLICY) {
proc_table[p].control |= CONTROL_CAP;
//kern_printf("CCAP set:%d",p);
 
}
if (nrt->arrivals == SAVE_ARRIVALS)
lev->nact[p] = 0;
else
lev->nact[p] = -1;
}
 
return 0; /* OK */
}
 
static void POSIXSTAR_public_dispatch(LEVEL l, PID p, int nostop)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
//#ifdef POSIXSTAR_DEBUG
//kern_printf("PDisp:%d(%d)",p, lev->activated);
//#endif
/* the task state is set EXE by the scheduler()
we extract the task from the ready queue
NB: we can't assume that p is the first task in the queue!!! */
//iq_extract(p, &lev->ready[lev->priority[p]]);
if (p==lev->activated) {
level_table[lev->scheduling_level]->private_dispatch(lev->scheduling_level, p, nostop);
}
}
 
static void POSIXSTAR_public_epilogue(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
//#ifdef POSIXSTAR_DEBUG
//kern_printf("PEpic:%d(%d)",p, lev->activated);
//#endif
if (p==lev->activated) {
if (lev->yielding) {
lev->yielding = 0;
iq_extract(p,&lev->ready[lev->priority[p]]);
iq_insertlast(p,&lev->ready[lev->priority[p]]);
}
/* check if the slice is finished and insert the task in the coPOSIXect
qqueue position */
else if (proc_table[p].control & CONTROL_CAP &&
proc_table[p].avail_time <= 0) {
//proc_table[p].avail_time += proc_table[p].wcet;
//kern_printf("avail_time %d", proc_table[p].avail_time);
iq_extract(p,&lev->ready[lev->priority[p]]);
iq_insertlast(p,&lev->ready[lev->priority[p]]);
//level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p);
//lev->activated=NIL;
POSIXSTAR_private_scheduler(lev);
}
else {
//iq_insertfirst(p,&lev->ready[lev->priority[p]]);
level_table[lev->scheduling_level]->private_epilogue(lev->scheduling_level,p);
}
proc_table[p].status = POSIXSTAR_READY;
}
}
 
static void POSIXSTAR_internal_activate(POSIXSTAR_level_des *lev, PID p)
{
 
/* Insert task in the correct position */
proc_table[p].status = POSIXSTAR_READY;
iq_insertlast(p,&lev->ready[lev->priority[p]]);
 
}
 
static void POSIXSTAR_public_activate(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
/* Test if we are trying to activate a non sleeping task */
/* save activation (only if needed...) */
if (proc_table[p].status != SLEEP) {
if (lev->nact[p] != -1)
lev->nact[p]++;
return;
}
#ifdef POSIXSTAR_DEBUG
kern_printf("PA:%d",p);
#endif
POSIXSTAR_internal_activate(lev, p);
POSIXSTAR_private_scheduler(lev);
 
}
 
 
static void POSIXSTAR_public_unblock(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
/* Similar to POSIX_task_activate, but we don't check in what state
the task is */
 
/* Insert task in the coPOSIXect position */
proc_table[p].status = POSIXSTAR_READY;
iq_insertlast(p,&lev->ready[lev->priority[p]]);
POSIXSTAR_private_scheduler(lev);
}
 
static void POSIXSTAR_public_block(LEVEL l, PID p)
{
/* Extract the running task from the level
. we have already extract it from the ready queue at the dispatch time.
. the capacity event have to be removed by the generic kernel
. the wcet don't need modification...
. the state of the task is set by the calling function
 
So, we do nothing!!!
*/
 
//#ifdef POSIXSTAR_DEBUG
//kern_printf("PB:%d", p);
//#endif
}
 
static int POSIXSTAR_public_message(LEVEL l, PID p, void *m)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
if (lev->nact[p] > 0) {
/* continue!!!! */
lev->nact[p]--;
iq_insertfirst(p,&lev->ready[lev->priority[p]]);
proc_table[p].status = POSIXSTAR_READY;
}
else {
proc_table[p].status = SLEEP;
 
}
//#ifdef POSIXSTAR_DEBUG
//kern_printf("PM:%d",p);
//#endif
//jet_update_endcycle(); /* Update the Jet data... */
//trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */
POSIXSTAR_private_scheduler(lev);
return 0;
}
 
static void POSIXSTAR_public_end(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
#ifdef POSIXSTAR_DEBUG
kern_printf("PEnd:%d", p);
#endif
lev->nact[p] = -1;
 
/* then, we insert the task in the free queue */
proc_table[p].status = FREE;
iq_priority_insert(p,NULL);
POSIXSTAR_private_scheduler(lev);
}
 
/* Registration functions */
 
/*+ Registration function:
TIME slice the slice for the Round Robin queue
struct multiboot_info *mb used if createmain specified +*/
LEVEL POSIXSTAR_register_level(int budget, int master, TIME slice,
int prioritylevels)
{
LEVEL l; /* the level that we register */
POSIXSTAR_level_des *lev; /* for readableness only */
PID i; /* a counter */
int x; /* a counter */
 
printk("POSIXSTAR_register_level\n");
 
l = level_alloc_descriptor(sizeof(POSIXSTAR_level_des));
 
lev = (POSIXSTAR_level_des *)level_table[l];
 
printk(" lev=%d\n",(int)lev);
 
/* fill the standard descriptor */
/*
lev->l.private_insert = NULL;
lev->l.private_extract = NULL;
lev->l.private_dispatch = NULL;
lev->l.private_epilogue = NULL;
*/
 
//lev->l.public_scheduler = NULL;
lev->l.public_create = POSIXSTAR_public_create;
lev->l.public_end = POSIXSTAR_public_end;
lev->l.public_dispatch = POSIXSTAR_public_dispatch;
lev->l.public_epilogue = POSIXSTAR_public_epilogue;
lev->l.public_activate = POSIXSTAR_public_activate;
lev->l.public_unblock = POSIXSTAR_public_unblock;
lev->l.public_block = POSIXSTAR_public_block;
lev->l.public_message = POSIXSTAR_public_message;
lev->l.public_eligible = POSIXSTAR_public_eligible;
 
/* fill the POSIX descriptor part */
for (i = 0; i < MAX_PROC; i++)
lev->nact[i] = -1;
 
lev->maxpriority = prioritylevels -1;
 
lev->ready = (IQUEUE *)kern_alloc(sizeof(IQUEUE) * prioritylevels);
 
for (x = 0; x < prioritylevels; x++)
iq_init(&lev->ready[x], NULL, 0);
 
if (slice < POSIXSTAR_MINIMUM_SLICE) slice = POSIXSTAR_MINIMUM_SLICE;
if (slice > POSIXSTAR_MAXIMUM_SLICE) slice = POSIXSTAR_MAXIMUM_SLICE;
lev->slice = slice;
lev->activated=NIL;
lev->budget = budget;
lev->scheduling_level = master;
//lev->multiboot = mb;
 
//if (createmain)
// sys_atrunlevel(POSIXSTAR_call_main,(void *) l, RUNLEVEL_INIT);
 
return l;
}
 
/*+ this function forces the running task to go to his queue tail;
(it works only on the POSIX level) +*/
int POSIXSTAR_sched_yield(LEVEL l)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
if (proc_table[exec_shadow].task_level != l)
return -1;
 
proc_table[exec_shadow].context = kern_context_save();
lev->yielding = 1;
scheduler();
kern_context_load(proc_table[exec_shadow].context);
return 0;
}
 
/*+ this function returns the maximum level allowed for the POSIX level +*/
int POSIXSTAR_get_priority_max(LEVEL l)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
return lev->maxpriority;
}
 
/*+ this function returns the default timeslice for the POSIX level +*/
int POSIXSTAR_rr_get_interval(LEVEL l)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
return lev->slice;
}
 
/*+ this functions returns some paramaters of a task;
policy must be NRT_RR_POLICY or NRT_FIFO_POLICY;
priority must be in the range [0..prioritylevels]
returns ENOSYS or ESRCH if there are problems +*/
int POSIXSTAR_getschedparam(LEVEL l, PID p, int *policy, int *priority)
{
if (p<0 || p>= MAX_PROC || proc_table[p].status == FREE)
return ESRCH;
 
if (proc_table[p].task_level != l)
return ENOSYS;
 
if (proc_table[p].control & CONTROL_CAP)
*policy = NRT_RR_POLICY;
else
*policy = NRT_FIFO_POLICY;
 
*priority = ((POSIXSTAR_level_des *)(level_table[l]))->priority[p];
 
return 0;
}
 
/*+ this functions sets paramaters of a task +*/
int POSIXSTAR_setschedparam(LEVEL l, PID p, int policy, int priority)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
if (p<0 || p>= MAX_PROC || proc_table[p].status == FREE)
return ESRCH;
 
if (proc_table[p].task_level != l)
return ENOSYS;
 
if (policy == SCHED_RR)
proc_table[p].control |= CONTROL_CAP;
else if (policy == SCHED_FIFO)
proc_table[p].control &= ~CONTROL_CAP;
else
return EINVAL;
 
if (lev->priority[p] != priority) {
if (proc_table[p].status == POSIXSTAR_READY) {
iq_extract(p,&lev->ready[lev->priority[p]]);
lev->priority[p] = priority;
iq_insertlast(p,&lev->ready[priority]);
}
else
lev->priority[p] = priority;
}
 
return 0;
}