Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

#include "hlpdemo.h"
#include <drivers/shark_keyb26.h>
#include "snapshot.h"

//#define ESC 27

/*
#define DEBUG
*/


/* tipologia di task e mutex */
HARD_TASK_MODEL m;

/* scala temporale del sistema in us */
#define TIMESCALE (100 * 1000)

/* buffer che contiene la configurazione letto in nrt mode */
extern char myfilebuf[1000];

extern int read_conf(char *, unsigned int);
extern void print_taskconf(taskconf_list_t *);

void trace_info_hlp(void);

/* tempo dell'avvio */
TIME start;

/* struttura dati contenente la configurazione */
taskconf_list_t *taskconf = NULL;

/* lista dei mutex del sistema */
mutex_list_t *mutexes = NULL;

#define YMENU    10             /* menu level                   */
#define XMIN     50
#define XMAX     600
#define YMIN     100
#define YMAX     450
#define YFLOOR(index) YMIN + (50 * (index + 1))

#define COLWHITE rgb16(255,255,255)
#define COLLOAD  rgb16(180,180,180)

/*--------------------------------------------------------------*/

/* posizione lungo l'asse x dopo t sec. */
int xpost(unsigned int t)
{
  int ret;

  ret = XMIN + 10 + (((sys_gettime(NULL) - start) / TIMESCALE) + t);
  if (ret > XMAX)
    ret = XMAX;
  if (ret < XMIN)
    ret = XMIN;

  return ret;
}

/* posizione lungo l'asse x al tempo t corrente */
int xpos(void)
{
  return xpost(0);
}

typedef struct color_stack {
  int color;
  struct color_stack *next;
} color_stack_t;

void color_stack_push(int color, color_stack_t **head)
{
  color_stack_t *new;

  new = (color_stack_t *)kern_alloc(sizeof(color_stack_t));
  new->color = color;
  new->next = *head;

  *head = new;
}

int color_stack_pop(color_stack_t **head)
{
  int ret = COLLOAD;
  color_stack_t *tmp = *head;

  if (*head != NULL)
    {
      ret = (*head)->color;
      *head = (*head)->next;
      kern_free(tmp, (sizeof(color_stack_t)));
    }
 
  return ret;
}


void load(int time, int i, int color, char *name)
{
  int j;
  TIME last;
  char buf[50];

  for (j = 0; j < time; j++)
    {
      last = sys_gettime(NULL);

      grx_line(xpos(), YFLOOR(i), xpos(), YFLOOR(i) - 10, color);
      sprintf(buf,
              "Time: %.4d, task active: %.5s(PID=%.2d, Shadow=%.2d)",
              (int)((sys_gettime(NULL) - start) / TIMESCALE) + 2,
              name,
              exec,
              exec_shadow);
      grx_text(buf, 100,100,COLWHITE,0);

      while (sys_gettime(NULL) - last + (TIMESCALE/100) < TIMESCALE);
    }
}

TASK    Ji(void *arg)
{
  taskconf_list_t *cur = (taskconf_list_t *)arg;
  action_list_t *act;
  color_stack_t *colorstack;

  color_stack_push(COLLOAD, &colorstack);

  while (1)
    {
 
      act = cur->actionlist;

      while (act)
        {
          switch (act->type)
            {
            case LOAD:
              load(act->time, cur->i, colorstack->color, cur->name);
              if (xpos() == XMAX)
                {
                  task_kill(cur->pid);
                  return 0;
                }
              break;
             
            case LOCK: /* task lock */
              color_stack_push(act->mutex->color, &colorstack);
              grx_text(act->mutex->name, xpos() - 2, YFLOOR(cur->i) + 10, COLWHITE, 0);
              mutex_lock(&act->mutex->m);
              trace_info_hlp();
              break;
             
            case UNLOCK: /* task unlock */
              color_stack_pop(&colorstack);
              mutex_unlock(&act->mutex->m);
              trace_info_hlp();
              break;
            }
          act = act->next;
        }
      task_endcycle();
    }

  return 0;
}

void draw_scenario(void)
{
  /* The scenario */
  grx_rect(XMIN-1, YMIN-1, XMAX+1, YMAX+1, COLWHITE);
  grx_text("Simulation of HLP tasks", XMIN, YMENU+10, COLWHITE, 0);
  grx_text("SPACE Start demo"        , XMIN, YMENU+20, COLWHITE, 0);
  grx_text("ESC   exit to DOS"         , XMIN, YMENU+30, COLWHITE, 0);
}

void trace_info_hlp()
{
  HLP_mutex_resource_des *m;
  RLEVEL l;
  HLP_mutex_t *mutscan;
  HLP_tasklist_t *taskscan;
  int i = 0;
  char buf[60];

  if (mutexes)
    {
      l = mutexes->m.mutexlevel;
      m = (HLP_mutex_resource_des *)(resource_table[l]);
     
      for (mutscan = m->mutexlist; mutscan; mutscan = mutscan->next)
        {
          if (mutscan->owner != NIL)
            sprintf(buf, "mutex: %p owner=%2d, used by", mutscan, mutscan->owner);
          else
            sprintf(buf, "mutex: %p no owner, used by", mutscan);
         
          grx_text(buf, 50, 320, COLWHITE, 0);
         
          for (i = 1, taskscan = mutscan->tasklist; taskscan; taskscan = taskscan->next, i++)
            {
              sprintf(buf, "task: %p, pid=%d, preempt=%ld",
                      taskscan,
                      taskscan->pid,
                      taskscan->preempt);
              grx_text(buf, 100, 320+i*8, COLWHITE, 0);
            }
        }

      grx_text("All tasks:", 100, 320 + i++ * 8, COLWHITE, 0);

      if (taskconf)
        for (taskscan = m->tasklist; taskscan; taskscan = taskscan->next, i++)
          {
            sprintf(buf,
                    "task: %p, pid=%d, preempt=%ld",
                    taskscan,
                    taskscan->pid,
                    taskscan->preempt);

            grx_text(buf, 100, 320+i*8, COLWHITE, 0);
          }
    }
  else
    {
      grx_text("No mutexes", 200, 200, COLWHITE, 0);
    }

}

/* get preemption level inverse proportional to period and starting by 1 */
int get_preemption_level(taskconf_list_t *task)
{
  taskconf_list_t *scan;
  int ret = 1;
 
  for (scan = taskconf; scan; scan = scan->next)
    if (scan != task && scan->period < task->period)
      ret++;

  return ret;
}

/****************************** MAIN ******************************/

int main(int argc, char **argv)
{
    char c;             /* character from keyboard      */
    int i = 0, j = 0, started = 0, numtask = 0, nummutex = 0;
    taskconf_list_t *curtask = NULL;
    mutex_list_t *mutexlist = NULL, *curmut = NULL;
    PID pid = NIL;
    HLP_mutexattr_t a;
    HLP_RES_MODEL r;

    if (read_conf(myfilebuf, 1000) == -1)
      {
        sys_shutdown_message("Error reading configuration file");
        sys_end();
      }

    for (curtask = taskconf; curtask != NULL; curtask = curtask->next)
      numtask++;

    draw_scenario();
    curtask = taskconf;

    for (curmut = mutexes; curmut; curmut = curmut->next)
      {
        HLP_mutexattr_default(a);
        mutex_init(&(curmut->m), &a);
      }
   
    snapshot_freeslot(0);

    c = keyb_getch(BLOCK);
    i = started = 0;
    do {
     
      if ((c == ' ') && !started) {
        started = 1;
        start = sys_gettime(NULL);

        while (curtask) {

          /* traccio gli assi temporali per ogni task */
          grx_line(XMIN + 10, YFLOOR(i), XMAX - 10, YFLOOR(i), COLWHITE);
          grx_text(curtask->name, XMIN - 20, YFLOOR(i) - 10, COLWHITE, 0);                     
         
          /* disegna frecce di attivazione */
          for (j = 0; xpost(j) < XMAX; j += curtask->period)
            {
              grx_line(xpost(j), YFLOOR(i), xpost(j), YFLOOR(i) - 20, COLWHITE);
              grx_line(xpost(j), YFLOOR(i) - 20, xpost(j) - 5, YFLOOR(i) - 15, COLWHITE);
              grx_line(xpost(j), YFLOOR(i) - 20, xpost(j) + 5, YFLOOR(i) - 15, COLWHITE);
            }

          hard_task_default_model(m);
          hard_task_def_level(m,0);
          hard_task_def_ctrl_jet(m);
          hard_task_def_periodic(m);
          hard_task_def_wcet(m, (curtask->wcet + 2) * TIMESCALE);
          hard_task_def_mit(m, curtask->period * TIMESCALE);
          hard_task_def_arg(m,(void *)curtask);
          hard_task_def_group(m, 1);
         
          /* registro i mutex per il pid */
          nummutex = 0;
          mutexlist = curtask->mutexlist;
          while(mutexlist) {
            mutexlist = mutexlist->next;
            nummutex++;
          }
         
          //      HLP_res_default_model(r, get_preemption_level(curtask));
          HLP_res_default_model(r, 1000 - curtask->period);
         
          switch (nummutex) {
          case 0:
            pid = task_create(curtask->name, Ji, &m, &r);
            break;
           
          case 1:
            pid = task_createn(curtask->name, Ji, (TASK_MODEL *)&m, &r,
                               HLP_usemutex(&(curtask->mutexlist->m)), NULL);
            break;
           
          case 2:
            pid = task_createn(curtask->name, Ji, (TASK_MODEL *)&m, &r,
                               HLP_usemutex(&(curtask->mutexlist->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->m)), NULL);
            break;
          case 3:
            pid = task_createn(curtask->name, Ji, (TASK_MODEL *)&m, &r,
                               HLP_usemutex(&(curtask->mutexlist->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->next->m)), NULL);
            break;
          case 4:
            pid = task_createn(curtask->name, Ji, (TASK_MODEL *)&m, &r,
                               HLP_usemutex(&(curtask->mutexlist->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->next->m)),
                               HLP_usemutex(&(curtask->mutexlist->next->next->next->m)), NULL);
            break;
           
          default:
            sys_shutdown_message("Too many mutexes! I am stupid!");
            sys_end();
          }
         
          if (pid == NIL)
            {
              sys_shutdown_message("Could not create task %s", curtask->name);
              sys_end();
              print_taskconf(curtask);
              return 0;
            }
          curtask->pid = pid;
          curtask->i = i++;
         
          curtask = curtask->next;
        }
       
        trace_info_hlp();
       
        start = sys_gettime(NULL);
        group_activate(1);
      }


      c = keyb_getch(BLOCK);

      if (xpos() > XMAX)
        {
          group_kill(1);
        }
     
    } while (c != ESC);

    snapshot_getslot(0, 640, 480, 2);
    snapshot_grab(0);

    sys_end();
   
    snapshot_save_ppm(0, "snapshot.ppm");

    return 0;
   
}

/*--------------------------------------------------------------*/