Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

/*
 * Project: S.Ha.R.K.
 *
 * Coordinators:
 *   Giorgio Buttazzo    <giorgio@sssup.it>
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *
 * Authors     :
 *   Paolo Gai           <pj@gandalf.sssup.it>
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
 *   Luca Abeni          <luca@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: dummy.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $

 File:        $File$
 Revision:    $Revision: 1.1.1.1 $
 Last update: $Date: 2002-03-29 14:12:52 $
 ------------

 This file contains the Dummy scheduling module

 Read dummy.h for further details.

**/


/*
 * 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 WARRANTY; without even the implied warranty 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 <modules/dummy.h>
#include <ll/ll.h>
#include <ll/stdio.h>
#include <ll/string.h>
#include <kernel/config.h>
#include <sys/types.h>
#include <modules/codes.h>
#include <kernel/model.h>
#include <kernel/descr.h>
#include <kernel/var.h>
#include <kernel/func.h>



/*+ the level redefinition for the Dummy level +*/
typedef struct {
  level_des l;     /*+ the standard level descriptor          +*/

  PID dummy;       /*+ the dummy task...                      +*/
} dummy_level_des;


static int dummy_level_accept_task_model(LEVEL l, TASK_MODEL *m)
{
  dummy_level_des *lev = (dummy_level_des *)(level_table[l]);

  if ((m->pclass == DUMMY_PCLASS || m->pclass == (DUMMY_PCLASS | l))
      && lev->dummy == -1)
    return 0;
  else
    return -1;
}

static int dummy_level_accept_guest_model(LEVEL l, TASK_MODEL *m)
{
  return -1;
}

static void dummy_level_status(LEVEL l)
{
  dummy_level_des *lev = (dummy_level_des *)(level_table[l]);

  kern_printf("dummy PID: %d\n", lev->dummy);
};


static PID dummy_level_scheduler(LEVEL l)
{
  dummy_level_des *lev = (dummy_level_des *)(level_table[l]);
  //kern_printf("DUMMYsched!!! %d", lev->dummy);
  return lev->dummy;
}

/* There is not guarantee on this level!!! -> the entry must be null
int (*level_guarantee)(LEVEL l, DWORD *freebandwidth); */


static int dummy_task_create(LEVEL l, PID p, TASK_MODEL *m)
{
  /* the dummy level doesn't introduce any new field in the TASK_MODEL
     so, all initialization stuffs are done by the task_create.
     the task state is set at SLEEP by the general task_create */

  return 0; /* OK */
}

static void dummy_task_detach(LEVEL l, PID p)
{
  /* the dummy level doesn't introduce any new field in the TASK_MODEL
     so, all detach stuffs are done by the task_create
     The task state is set at FREE by the general task_create */

}

static int dummy_task_eligible(LEVEL l, PID p)
{
  return 0; /* if the task p is chosen, it is always eligible */
}

extern int testactive;
extern struct timespec s_stime[];
extern TIME s_curr[];
extern TIME s_PID[];
extern int useds;
static void dummy_task_dispatch(LEVEL l, PID p, int nostop)
{
  /* nothing... the dummy hangs the cpu waiting for interrupts... */
  if (0)//testactive)
  {
    s_stime[useds]= schedule_time;
    s_curr[useds] = -1;
    s_PID[useds]  = p;
    useds++;
  }

  //kern_printf("ÛDUMMYÛ");

}

static void dummy_task_epilogue(LEVEL l, PID p)
{
  proc_table[p].status = SLEEP; /* Paranoia */
}

static void dummy_task_activate(LEVEL l, PID p)
{ kern_printf("Dummy1"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_insert(LEVEL l, PID p)
{ kern_printf("Dummy2"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_extract(LEVEL l, PID p)
{ kern_printf("Dummy3"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_endcycle(LEVEL l, PID p)
{ kern_printf("Dummy4"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_end(LEVEL l, PID p)
{ kern_printf("Dummy5"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_sleep(LEVEL l, PID p)
{ kern_printf("Dummy6"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static void dummy_task_delay(LEVEL l, PID p, TIME tickdelay)
{ kern_printf("Dummy7"); kern_raise(XUNVALID_DUMMY_OP,exec_shadow); }

static int dummy_guest_create(LEVEL l, PID p, TASK_MODEL *m)
{ kern_printf("Dummy8"); kern_raise(XUNVALID_GUEST,exec_shadow); return 0; }

static void dummy_guest_detach(LEVEL l, PID p)
{ kern_printf("Dummy9"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_dispatch(LEVEL l, PID p, int nostop)
{ kern_printf("Dummy0"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_epilogue(LEVEL l, PID p)
{ kern_printf("Dummya"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_activate(LEVEL l, PID p)
{ kern_printf("Dummyb"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_insert(LEVEL l, PID p)
{ kern_printf("Dummyc"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_extract(LEVEL l, PID p)
{ kern_printf("Dummyd"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_endcycle(LEVEL l, PID p)
{ kern_printf("Dummye"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_end(LEVEL l, PID p)
{ kern_printf("Dummyf"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_sleep(LEVEL l, PID p)
{ kern_printf("Dummyg"); kern_raise(XUNVALID_GUEST,exec_shadow); }

static void dummy_guest_delay(LEVEL l, PID p,DWORD tickdelay)
{ kern_printf("Dummyh"); kern_raise(XUNVALID_GUEST,exec_shadow); }




/*+ Dummy task must be present & cannot be killed; +*/
static TASK dummy()
{
    /*
    It is possible to Halt the CPU & avoid consumption if idle
    cycle are intercepted with hlt instructions!
    It seems that some CPU have buggy hlt instruction or they
    have not it at all! So, if available, use the hlt facility!!
    */

    #ifdef __HLT_WORKS__
    for(;;) {
//       kern_printf("?");
        hlt();
    }
    #else
    for(;;);// kern_printf("?");
    #endif
}

/* Registration functions */

/*+ This init function install the dummy task +*/
static void dummy_create(void *l)
{
  LEVEL lev;
  PID p;
  DUMMY_TASK_MODEL m;

  lev = (LEVEL)l;

  dummy_task_default_model(m);
  dummy_task_def_level(m,lev);
  dummy_task_def_system(m);
  dummy_task_def_nokill(m);
  dummy_task_def_ctrl_jet(m);

  ((dummy_level_des *)level_table[lev])->dummy = p =
    task_create("Dummy", dummy, &m, NULL);

  if (p == NIL)
    printk("\nPanic!!! can't create dummy task...\n");

  /* dummy must block all tasks... */
  proc_table[p].sigmask = 0xFFFFFFFF;
}


/*+ Registration function:
    TIME slice                the slice for the Round Robin queue
    int createmain            1 if the level creates the main task 0 otherwise
    struct multiboot_info *mb used if createmain specified   +*/

void dummy_register_level()
{
  LEVEL l;            /* the level that we register */
  dummy_level_des *lev;  /* for readableness only */

  printk("Entro in dummy_register_level\n");
  /* request an entry in the level_table */
  l = level_alloc_descriptor();

  /* alloc the space needed for the dummy_level_des */
  lev = (dummy_level_des *)kern_alloc(sizeof(dummy_level_des));

  /* update the level_table with the new entry */
  level_table[l] = (level_des *)lev;

  /* fill the standard descriptor */
  strncpy(lev->l.level_name,  DUMMY_LEVELNAME, MAX_LEVELNAME);
  lev->l.level_code               = DUMMY_LEVEL_CODE;
  lev->l.level_version            = DUMMY_LEVEL_VERSION;

  lev->l.level_accept_task_model  = dummy_level_accept_task_model;
  lev->l.level_accept_guest_model = dummy_level_accept_guest_model;
  lev->l.level_status             = dummy_level_status;
  lev->l.level_scheduler          = dummy_level_scheduler;
  lev->l.level_guarantee          = NULL; /* No guarantee! */

  lev->l.task_create              = dummy_task_create;
  lev->l.task_detach              = dummy_task_detach;
  lev->l.task_eligible            = dummy_task_eligible;
  lev->l.task_dispatch            = dummy_task_dispatch;
  lev->l.task_epilogue            = dummy_task_epilogue;
  lev->l.task_activate            = dummy_task_activate;
  lev->l.task_insert              = dummy_task_insert;
  lev->l.task_extract             = dummy_task_extract;
  lev->l.task_endcycle            = dummy_task_endcycle;
  lev->l.task_end                 = dummy_task_end;
  lev->l.task_sleep               = dummy_task_sleep;
  lev->l.task_delay               = dummy_task_delay;

  lev->l.guest_create             = dummy_guest_create;
  lev->l.guest_detach             = dummy_guest_detach;
  lev->l.guest_dispatch           = dummy_guest_dispatch;
  lev->l.guest_epilogue           = dummy_guest_epilogue;
  lev->l.guest_activate           = dummy_guest_activate;
  lev->l.guest_insert             = dummy_guest_insert;
  lev->l.guest_extract            = dummy_guest_extract;
  lev->l.guest_endcycle           = dummy_guest_endcycle;
  lev->l.guest_end                = dummy_guest_end;
  lev->l.guest_sleep              = dummy_guest_sleep;
  lev->l.guest_delay              = dummy_guest_delay;

  /* the dummy process will be created at init_time.
     see also dummy_level_accept_model,dummy_create   */

  lev->dummy = -1;

  printk("\tPosto dummy_create\n");

  sys_atrunlevel(dummy_create,(void *) l, RUNLEVEL_INIT);
}