Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

#include <kernel/kern.h>
#include "parser.h"
#include "dosread.h"

#include "fsf_contract.h"
#include "fsf_server.h"

/* Memory pointers on loaded file */
extern void *start_file;
extern void *end_file;

/* Calibration Loops */
#define CALIBRATION_DELTA 10000

/* Mutex number */
#define MAX_MUTEX 10

/* Activate task output */
#define TASK_OUTPUT

struct timespec zero_time;
int cal_cycles = 0;

mutex_t mux_table[MAX_MUTEX];

/* Not Real-Time Task */
TASK nrt_test_task(void *arg)
{
  long long i,exec_cycles = 0;
  int exec_1,exec_2,exec_3;
  int act_1,act_2,act_3,next_act;
  int crit_1 = 0,crit_2 = 0,crit_3 = 0,crit_4 = 0;
  int crit_start,crit_len;
  long long crit_start_cycles = 0, crit_len_cycles = 0;
  struct timespec next_time;
  struct loader_task *l = (struct loader_task *)(arg);
  char tmp[20];
                                                                                                                           
  act_1 = TIMESPEC2USEC(&l->act_par_2);
  act_2 = TIMESPEC2USEC(&l->act_par_3);
  act_3 = TIMESPEC2USEC(&l->act_par_4);

  if (l->act_type == PAR_ACT_PERIODIC) {
    kern_gettime(&next_time);
    ADDUSEC2TIMESPEC(act_1,&next_time);
    kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
  }

  if (l->act_type == PAR_ACT_MEAN) {
    next_act = act_1 + rand() % act_2 - act_2/2;
    kern_gettime(&next_time);
    ADDUSEC2TIMESPEC(next_act,&next_time);
    kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
  }

  if (l->act_type == PAR_ACT_GAUSS) {
  }

  if (l->act_type == PAR_ACT_GAUSS_MAX) {
  }
                                                                                                                             
  exec_1 = TIMESPEC2USEC(&l->exec_par_1);
  exec_2 = TIMESPEC2USEC(&l->exec_par_2);
  exec_3 = TIMESPEC2USEC(&l->exec_par_3);
 
  if (l->crit_type == PAR_CRIT) {
    crit_1 = TIMESPEC2USEC(&l->crit_par_1);
    crit_2 = TIMESPEC2USEC(&l->crit_par_2);
    crit_3 = TIMESPEC2USEC(&l->crit_par_3);
    crit_4 = TIMESPEC2USEC(&l->crit_par_4);
  }
   
  #ifdef TASK_OUTPUT
    printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN, "R[000000]");
  #endif
                                                                                                                           
  if (l->exec_type == PAR_EXEC_CONST)
    exec_cycles = (long long)(exec_1) * CALIBRATION_DELTA / cal_cycles;
                                                                                                                             
  if (l->exec_type == PAR_EXEC_MEAN)
    exec_cycles = (long long)(exec_1 + rand() % exec_2 - exec_2/2)
                    * CALIBRATION_DELTA / cal_cycles;
                                                                                                                             
  if (l->exec_type == PAR_EXEC_GAUSS)
    exec_cycles = 0;

  if (l->exec_type == PAR_EXEC_GAUSS_MAX)
    exec_cycles = 0;

  if (l->crit_type == PAR_CRIT) {
    crit_start = crit_1 + rand() % crit_2 - crit_2/2;
    crit_len = crit_3 + rand() % crit_4 - crit_4/2;
    crit_start_cycles = (long long)(crit_start) * CALIBRATION_DELTA / cal_cycles;
    crit_len_cycles = (long long)(crit_len) * CALIBRATION_DELTA / cal_cycles;
    exec_cycles -= crit_start_cycles + crit_len_cycles;
    if (exec_cycles < 0) {
      cprintf("Error: exec_cycles < 0\n");
      sys_end();
    }
  }

  if (l->crit_type == PAR_NO_CRIT)
    for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
  else {
    for (i=0;i<crit_start_cycles;i++) kern_gettime(NULL);
    #ifdef TASK_OUTPUT
      sprintf(tmp,"B[%02d][%02d]",exec_shadow,l->resource);
      printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, RED,tmp);
    #endif
    mutex_lock(&mux_table[l->resource]);
    for (i=0;i<crit_len_cycles;i++) kern_gettime(NULL);
    mutex_unlock(&mux_table[l->resource]);
    #ifdef TASK_OUTPUT
      printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN,"R[000000]");
    #endif
    for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
  }

  #ifdef TASK_OUTPUT
    printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, BLUE, "E[000000]");
  #endif
                                                                                                                             
  return NULL;
                                                                                                                             
}

/* Soft and hard Task */
TASK test_task(void *arg)
{
  long long i,exec_cycles = 0;
  int exec_1,exec_2,exec_3;
  int act_1,act_2,act_3,next_act;
  int crit_1 = 0,crit_2 = 0,crit_3 = 0,crit_4 = 0;
  int crit_start,crit_len;
  long long crit_start_cycles = 0, crit_len_cycles = 0;
  struct timespec next_time;
  int act = 0;
  struct loader_task *l = (struct loader_task *)(arg);
  char tmp[20];
                                                                                                                         
  act_1 = TIMESPEC2USEC(&l->act_par_2);
  act_2 = TIMESPEC2USEC(&l->act_par_3);
  act_3 = TIMESPEC2USEC(&l->act_par_4);
                                                                                                                             
  exec_1 = TIMESPEC2USEC(&l->exec_par_1);
  exec_2 = TIMESPEC2USEC(&l->exec_par_2);
  exec_3 = TIMESPEC2USEC(&l->exec_par_3);

  if (l->crit_type == PAR_CRIT) {
    crit_1 = TIMESPEC2USEC(&l->crit_par_1);
    crit_2 = TIMESPEC2USEC(&l->crit_par_2);
    crit_3 = TIMESPEC2USEC(&l->crit_par_3);
    crit_4 = TIMESPEC2USEC(&l->crit_par_4);
  }

  while(1) {

    task_testcancel();

    act++;

    #ifdef TASK_OUTPUT
      sprintf(tmp,"X[%06d]",act);
      printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN, tmp);
    #endif

    if (l->act_type == PAR_ACT_MEAN) {
      next_act = act_1 + rand() % act_2 - act_2/2;
      kern_gettime(&next_time);
      ADDUSEC2TIMESPEC(next_act,&next_time);
      kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
    }

    if (l->act_type == PAR_ACT_GAUSS) {
    }

    if (l->act_type == PAR_ACT_GAUSS_MAX) {
    }

    if (l->exec_type == PAR_EXEC_CONST)
      exec_cycles = (long long)(exec_1) * CALIBRATION_DELTA / cal_cycles;
 
    if (l->exec_type == PAR_EXEC_MEAN)
      exec_cycles = (long long)(exec_1 + rand() % exec_2 - exec_2/2)
                     * CALIBRATION_DELTA / cal_cycles;
                                                                                                                             
    if (l->exec_type == PAR_EXEC_GAUSS)
      exec_cycles = 0;

    if (l->exec_type == PAR_EXEC_GAUSS_MAX)
      exec_cycles = 0;
   
    if (l->crit_type == PAR_CRIT) {
      crit_start = crit_1 + rand() % crit_2 - crit_2/2;
      crit_len = crit_3 + rand() % crit_4 - crit_4/2;
      crit_start_cycles = (long long)(crit_start) * CALIBRATION_DELTA / cal_cycles;
      crit_len_cycles = (long long)(crit_len) * CALIBRATION_DELTA / cal_cycles;
      exec_cycles -= crit_start_cycles + crit_len_cycles;
      if (exec_cycles < 0) {
        cprintf("Error: exec_cycles < 0\n");
        sys_end();
      }
    }  
 
    if (l->crit_type == PAR_NO_CRIT)
      for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
    else {
      for (i=0;i<crit_start_cycles;i++) kern_gettime(NULL);
      #ifdef TASK_OUTPUT
        sprintf(tmp,"B[%02d][%02d]",exec_shadow,l->resource);
        printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, RED, tmp);
      #endif
      mutex_lock(&mux_table[l->resource]);
      for (i=0;i<crit_len_cycles;i++) kern_gettime(NULL);
      mutex_unlock(&mux_table[l->resource]);
      #ifdef TASK_OUTPUT
        sprintf(tmp,"X[%06d]",act);
        printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN, tmp);
      #endif
      for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
    }
 
    task_endcycle();
                                                                                                                           
  }
                                                                                                                             
  return NULL;
                                                                                                                             
}

/* Background Task */
TASK back_task(void *arg)
{
  long long i,exec_cycles = 0;
  int exec_1,exec_2,exec_3;
  int act_1,act_2,act_3,next_act;
  int crit_1 = 0,crit_2 = 0,crit_3 = 0,crit_4 = 0;
  int crit_start,crit_len;
  long long crit_start_cycles = 0, crit_len_cycles = 0;
  struct timespec next_time;
  int act = 0;
  struct loader_task *l = (struct loader_task *)(arg);
  char tmp[20];
                                                                                                                             
  act_1 = TIMESPEC2USEC(&l->act_par_2);
  act_2 = TIMESPEC2USEC(&l->act_par_3);
  act_3 = TIMESPEC2USEC(&l->act_par_4);
                                                                                                                             
  exec_1 = TIMESPEC2USEC(&l->exec_par_1);
  exec_2 = TIMESPEC2USEC(&l->exec_par_2);
  exec_3 = TIMESPEC2USEC(&l->exec_par_3);

  if (l->crit_type == PAR_CRIT) {
    crit_1 = TIMESPEC2USEC(&l->crit_par_1);
    crit_2 = TIMESPEC2USEC(&l->crit_par_2);
    crit_3 = TIMESPEC2USEC(&l->crit_par_3);
    crit_4 = TIMESPEC2USEC(&l->crit_par_4);
  }

  while(1) {

    task_testcancel();

    act++;

    #ifdef TASK_OUTPUT
      sprintf(tmp,"X[%06d]",act);
      printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN, tmp);
    #endif

    if (l->act_type == PAR_ACT_MEAN) {
      next_act = act_1 + rand() % act_2 - act_2/2;
      kern_gettime(&next_time);
      ADDUSEC2TIMESPEC(next_act,&next_time);
      kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow);
    }

    if (l->act_type == PAR_ACT_GAUSS) {
    }

    if (l->act_type == PAR_ACT_GAUSS_MAX) {
    }

    if (l->exec_type == PAR_EXEC_CONST)
      exec_cycles = (long long)(exec_1) * CALIBRATION_DELTA / cal_cycles;
 
    if (l->exec_type == PAR_EXEC_MEAN)
      exec_cycles = (long long)(exec_1 + rand() % exec_2 - exec_2/2)
                     * CALIBRATION_DELTA / cal_cycles;
                                                                                                                             
    if (l->exec_type == PAR_EXEC_GAUSS)
      exec_cycles = 0;

    if (l->exec_type == PAR_EXEC_GAUSS_MAX)
      exec_cycles = 0;
   
    if (l->crit_type == PAR_CRIT) {
      crit_start = crit_1 + rand() % crit_2 - crit_2/2;
      crit_len = crit_3 + rand() % crit_4 - crit_4/2;
      crit_start_cycles = (long long)(crit_start) * CALIBRATION_DELTA / cal_cycles;
      crit_len_cycles = (long long)(crit_len) * CALIBRATION_DELTA / cal_cycles;
      exec_cycles -= crit_start_cycles + crit_len_cycles;
      if (exec_cycles < 0) {
        cprintf("Error: exec_cycles < 0\n");
        sys_end();
      }
    }  
 
    if (l->crit_type == PAR_NO_CRIT)
      for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
    else {
      for (i=0;i<crit_start_cycles;i++) kern_gettime(NULL);
      #ifdef TASK_OUTPUT
        sprintf(tmp,"B[%02d][%02d]",exec_shadow,l->resource);
        printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, RED, tmp);
      #endif
      mutex_lock(&mux_table[l->resource]);
      for (i=0;i<crit_len_cycles;i++) kern_gettime(NULL);
      mutex_unlock(&mux_table[l->resource]);
      #ifdef TASK_OUTPUT
        sprintf(tmp,"X[%06d]",act);
        printf_xy((exec_shadow % 5) * 9 + 34, exec_shadow / 5 + 5, GREEN, tmp);
      #endif
      for (i=0;i<exec_cycles;i++) kern_gettime(NULL);
    }
                                                                                                                   
  }
                                                                                                                             
  return NULL;
                                                                                                                             
}

/* Delay Calibration */
int calibrate_cycle()
{
  long long i;
  struct timespec start,end,diff;

  kern_cli();
  kern_gettime(&start);
  for (i=0;i<CALIBRATION_DELTA;i++) kern_gettime(NULL);
  kern_gettime(&end);
  kern_sti();

  SUBTIMESPEC(&end,&start,&diff);
  cal_cycles = TIMESPEC2USEC(&diff);

  cprintf("Calibration usec/[%d cycles] = %d\n",CALIBRATION_DELTA,cal_cycles);

  return 0;

}

/* Mutex create */
void loader_mutex_create(struct loader_task *start_loader_task)
{

  struct loader_task *current = start_loader_task;
  int i,res = 0;
  PI_mutexattr_t a;
  int init_array[MAX_MUTEX];

  PI_mutexattr_default(a);

  for (i = 0;i < MAX_MUTEX;i++) init_array[i] = 0;

  while (current != NULL) {
 
    if (current->crit_type == PAR_CRIT) {
      if (init_array[current->resource] == 0) {
        mutex_init(&mux_table[current->resource],&a);
        init_array[current->resource] = 1;
        res++;
      }
    }

    current = current->next;

  }

  cprintf("Created %d mutex\n",res);

}

/* Task create */
void loader_task_create(struct loader_task *start_loader_task)
{

  struct loader_task *current = start_loader_task;
  char tmp[30];
  int i, total_task;
  int total_group = 0;
  PID p;

  total_task = 0;

  while (current != NULL) {

    total_group++;
    current->group = total_group;
    current->bandwidth = 0;

    for (i=0; i < current->number; i++) {

      if (current->task_type == PAR_TASK_NRT) {
        NRT_TASK_MODEL nrt;
     
        nrt_task_default_model(nrt);
        nrt_task_def_save_arrivals(nrt);
        nrt_task_def_arg(nrt,(void *)(current));
        nrt_task_def_ctrl_jet(nrt);
        nrt_task_def_level(nrt,current->task_level);
        nrt_task_def_group(nrt,total_group);
        nrt_task_def_usemath(nrt);

        sprintf(tmp,"NRT %d:%d",current->group,i);
        p = task_create(tmp,nrt_test_task,&nrt,NULL);
        if (p == NIL) {
          cprintf("Error nrt task creating\n");
          sys_end();
        }

        total_task++;

      }

      if (current->task_type == PAR_TASK_BACK) {
        NRT_TASK_MODEL nrt;
     
        nrt_task_default_model(nrt);
        nrt_task_def_save_arrivals(nrt);
        nrt_task_def_arg(nrt,(void *)(current));
        nrt_task_def_ctrl_jet(nrt);
        nrt_task_def_level(nrt,current->task_level);
        nrt_task_def_group(nrt,total_group);
        nrt_task_def_usemath(nrt);

        sprintf(tmp,"BACK %d:%d",current->group,i);
        p = task_create(tmp,back_task,&nrt,NULL);
        if (p == NIL) {
          cprintf("Error back task creating\n");
          sys_end();
        }

        total_task++;

      }

      if (current->task_type == PAR_TASK_HARD) {
        HARD_TASK_MODEL ht;
                                                                                                                             
        hard_task_default_model(ht);
        hard_task_def_arg(ht,(void *)(current));
        hard_task_def_wcet(ht,TIMESPEC2USEC(&current->wcet));
        hard_task_def_ctrl_jet(ht);
        hard_task_def_level(ht,current->task_level);
        hard_task_def_group(ht,total_group);
        hard_task_def_usemath(ht);

        if (current->act_type != PAR_ACT_PERIODIC) {
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->deadline));
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->deadline)
                                 * TIMESPEC2USEC(&current->wcet);
          hard_task_def_aperiodic(ht);
        } else {
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->act_par_2));
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
                                 * TIMESPEC2USEC(&current->wcet);
        }
       
        sprintf(tmp,"HARD %d:%d",current->group,i);
        p = task_create(tmp,test_task,&ht,NULL);
        if (p == NIL) {
          cprintf("Error hard task creating\n");
          sys_end();
        }

        total_task++;
                                                                                                                             
      }

      if (current->task_type == PAR_TASK_SOFT) {
        SOFT_TASK_MODEL st;
                                                                                                                             
        soft_task_default_model(st);
        soft_task_def_save_arrivals(st);
        soft_task_def_arg(st,(void *)(current));
        soft_task_def_met(st,TIMESPEC2USEC(&current->wcet));
        soft_task_def_ctrl_jet(st);
        soft_task_def_level(st,current->task_level);
        soft_task_def_group(st,total_group);
        soft_task_def_usemath(st);

        if (current->act_type == PAR_ACT_PERIODIC) {
          soft_task_def_period(st,TIMESPEC2USEC(&current->act_par_2));
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
                                 * TIMESPEC2USEC(&current->wcet);
        } else if (current->act_type != PAR_ACT_SINGLE) {
          soft_task_def_period(st,TIMESPEC2USEC(&current->act_par_2));
          current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(&current->act_par_2)
                                 * TIMESPEC2USEC(&current->wcet);
          soft_task_def_aperiodic(st);
        } else {
          soft_task_def_period(st,TIMESPEC2USEC(&current->wcet)*1000);
          current->bandwidth += MAX_BANDWIDTH / 1000;
          soft_task_def_aperiodic(st);
        }
       
        sprintf(tmp,"SOFT %d:%d",current->group,i);
        p = task_create(tmp,test_task,&st,NULL);
        if (p == NIL) {
          cprintf("Error soft task creating\n");
          sys_end();
        }

        total_task++;
                                                                                                                             
      }

      if (current->task_type == PAR_TASK_FSF) {

        if (current->local_scheduler == PAR_POSIX) {
          NRT_TASK_MODEL nrt;
          pthread_t j;
          int err;

          nrt_task_default_model(nrt);
          nrt_task_def_save_arrivals(nrt);
          nrt_task_def_ctrl_jet(nrt);
          nrt_task_def_usemath(nrt);
         
          err = fsf_create_thread(current->server,&j,NULL,back_task,(void *)current,&nrt);
          if (err) {
            cprintf("Error fsf task creating\n");
            sys_end();
          }
        }

        if (current->local_scheduler == PAR_EDF) {
          HARD_TASK_MODEL ht;
          pthread_t j;
          int err;

          hard_task_default_model(ht);
          hard_task_def_ctrl_jet(ht);          
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->deadline));
          hard_task_def_wcet(ht,TIMESPEC2USEC(&current->wcet));
          hard_task_def_usemath(ht);

          err = fsf_create_thread(current->server,&j,NULL,test_task,(void *)current,&ht);
          if (err) {
            cprintf("Error fsf task creating\n");
            sys_end();
          }

        }

        if (current->local_scheduler == PAR_RM) {
          HARD_TASK_MODEL ht;
          pthread_t j;
          int err;
                                                                                                                             
          hard_task_default_model(ht);
          hard_task_def_mit(ht,TIMESPEC2USEC(&current->deadline));
          hard_task_def_wcet(ht,TIMESPEC2USEC(&current->wcet));
          hard_task_def_ctrl_jet(ht);
          hard_task_def_usemath(ht);

          err = fsf_create_thread(current->server,&j,NULL,test_task,(void *)current,&ht);
          if (err) {
            cprintf("Error fsf task creating\n");
            sys_end();
          }
                                                                                                                             
        }

        total_task++;

      }

    }

    cprintf("Task group %d created. Worst case BW = %d.%d \n",
             current->group,(int)( (long long)current->bandwidth * 100 / MAX_BANDWIDTH),
             (int)( (long long)current->bandwidth*  100000 / MAX_BANDWIDTH % 1000));

    current = current->next;

  }

  cprintf("Created %d tasks\n",total_task);
 
}

/* Set the first extivation events */
void loader_first_execution(struct loader_task *start_loader_task)
{

  struct loader_task *current = start_loader_task;
  struct timespec start_time;  

  while (current != NULL) {

    if (current->task_type != PAR_TASK_FSF) {
 
      ADDTIMESPEC(&zero_time,&current->act_par_1,&start_time);

      kern_event_post(&start_time, (void *)((void *)group_activate), (void *)(current->group));

    }

    current = current->next;

  }  

}

void fsfinit(void);

int main()
{

  struct loader_task *start_loader_task = NULL;
  struct timespec total;
  struct timespec end_time;

  line_reader(start_file, end_file, &total, &start_loader_task);

  srand(kern_gettime(NULL));

  calibrate_cycle();

  fsfinit();

  loader_mutex_create(start_loader_task);
 
  loader_task_create(start_loader_task);
 
  kern_gettime(&zero_time);

  loader_first_execution(start_loader_task);

  ADDTIMESPEC(&zero_time,&total,&end_time);
  kern_event_post(&end_time,(void *)((void *)(sys_end)),NULL);

  return 0;

}