Subversion Repositories shark

Rev

Rev 1266 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/* FSF Loader
 *
 * Load and run a specific set of tasks/contracts
 *
 * This is the system indipendent part
 *
 * Giacomo Guidi <giacomo@gandalf.sssup.it>
 * Michael Timarchi <trimarchi@gandalf.sssup.it>
 *
 */


#include "fsf_contract.h" //Framework main header
#include "calibrate.h"
#include "func.h" //Generic function definitions
#include "lconst.h"

/* Activate task output debug */
#define TASK_OUTPUT

int cal_cycles = CALIBRATION_RESULT; //Calibration const, it converts usec to cycles
struct timespec zero_time; //Zero time of the simulation                                        
extern struct loader_task loader_task_list[]; //Loader task array
extern int total_loader_task; //Loader task number

/* OS: Oneshot Task:
   begin
    - execution
   end
*/

void *oneshot_task(void *arg)
{
  long long i,exec_cycles = 0;
  struct loader_task *l = (struct loader_task *)(arg);
  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      char tmp[20];
    #endif
  #endif

  start_oneshot_task();

  /* to avoid problem if the task start inside the create function */
  if (l->act_current == 0) l->act_current = 1;                                                                                                                            
  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      sprintf(tmp,"[ONESHOT]");
      printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
    #endif
  #endif

  exec_cycles = (long long)(TIMESPEC2USEC(&l->exec[l->act_current-1])) * CALIBRATION_DELTA / cal_cycles;
 
  /* Execution delay */
  for (i=0;i<exec_cycles;i++)
    __asm__ __volatile__ ("xorl %%eax,%%eax\n\t"
                          "cpuid\n\t"
                          :::"eax","ebx","ecx","edx");
 
  end_oneshot_task();
 
  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      sprintf(tmp,"[--END--]");
      printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
    #endif
  #endif

  return NULL;
                                                                                                                             
}

/* CT: Cyclical Task:
   begin
     while (1) {
       - execution
       - end_cycle
     }
   end (never end)
*/

void *periodic_task(void *arg)
{
  long long i,exec_cycles = 0,block_cycles = 0;
  int act = 0;
  struct loader_task *l = (struct loader_task *)(arg);

  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      char tmp[20];
    #endif
  #endif

  start_periodic_task();

  if (l->act_current == 0) l->act_current = 1;

  while(1) {

    start_job_periodic_task();

    #ifdef TASK_OUTPUT
      #ifdef OS_SHARK
        sprintf(tmp,"C[%06d]",act);
        printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
      #endif
    #endif
   
    exec_cycles = (long long)(TIMESPEC2USEC(&l->exec[l->act_current-1])) * CALIBRATION_DELTA / cal_cycles;
    block_cycles = (long long)(TIMESPEC2USEC(&l->block[l->act_current-1])) * CALIBRATION_DELTA / cal_cycles;  

    /* Execution delay */  
    for (i=0;i<exec_cycles;i++)
    __asm__ __volatile__ ("xorl %%eax,%%eax\n\t"
                          "cpuid\n\t"
                          :::"eax","ebx","ecx","edx");
    if (l->muxstatus == 2) {
 
      #ifdef TASK_OUTPUT
        #ifdef OS_SHARK
          sprintf(tmp,"C[LOCK%02d]",l->resource);
          printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, RED, tmp);
        #endif
      #endif

      generic_lock_mutex(l->resource);
      for (i=0;i<block_cycles;i++)
      __asm__ __volatile__ ("xorl %%eax,%%eax\n\t"
                            "cpuid\n\t"
                            :::"eax","ebx","ecx","edx");
      generic_unlock_mutex(l->resource);
     
      #ifdef TASK_OUTPUT
        #ifdef OS_SHARK
          sprintf(tmp,"C[FREE%02d]",l->resource);
          printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
        #endif
      #endif

    }    

    end_job_periodic_task();

    generic_task_endcycle();
   
    act++;
   
  }  

  end_periodic_task();

  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      sprintf(tmp,"[--END--]");
      printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
    #endif
  #endif
                                                                                                               
  return NULL;
                                                                                                                             
}

/* BT: Background Task:
   begin
     while (1) {
       - execution
     }
   end (never end)
*/

void *back_task(void *arg)
{
  long long i,exec_cycles = 0,block_cycles = 0;
  int act = 0;
  struct loader_task *l = (struct loader_task *)(arg);
  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      char tmp[20];
    #endif
  #endif

  start_back_task();

  if (l->act_current == 0) l->act_current = 1;

  while(1) {

    start_job_back_task();

    #ifdef TASK_OUTPUT
      #ifdef OS_SHARK
        sprintf(tmp,"B[%06d]",act);
        printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
      #endif
    #endif
   
    exec_cycles = (long long)(TIMESPEC2USEC(&l->exec[l->act_current-1])) * CALIBRATION_DELTA / cal_cycles;
    block_cycles = (long long)(TIMESPEC2USEC(&l->block[l->act_current-1])) * CALIBRATION_DELTA / cal_cycles;  
 
    /* Execution delay */
    for (i=0;i<exec_cycles;i++)
    __asm__ __volatile__ ("xorl %%eax,%%eax\n\t"
                          "cpuid\n\t"
                          :::"eax","ebx","ecx","edx");
    if (l->muxstatus == 2) {

      #ifdef TASK_OUTPUT
        #ifdef OS_SHARK
          sprintf(tmp,"B[LOCK%02d]",l->resource);
          printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, RED, tmp);
        #endif
      #endif

      generic_lock_mutex(l->resource);
      for (i=0;i<block_cycles;i++)
      __asm__ __volatile__ ("xorl %%eax,%%eax\n\t"
                            "cpuid\n\t"
                            :::"eax","ebx","ecx","edx");
      generic_unlock_mutex(l->resource);

      #ifdef TASK_OUTPUT
        #ifdef OS_SHARK
          sprintf(tmp,"C[FREE%02d]",l->resource);
          printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
        #endif
      #endif

    }    

    end_job_back_task();

    act++;
   
  }

  end_back_task();
   
  #ifdef TASK_OUTPUT
    #ifdef OS_SHARK
      sprintf(tmp,"[--END--]");
      printf_xy((get_current_exec_task() % 5) * 9 + 34,get_current_exec_task()  / 5 + 5, GREEN, tmp);
    #endif
  #endif
                                                                                                             
  return NULL;
                                                                                                                             
}

/* Task create */
/* this function create the task struct in memory */
void loader_task_create()
{

  struct loader_task *current = loader_task_list;
  int i=0, k=0;

  while (k <total_loader_task) {
    k++;
   
    for (i=0; i < current->number; i++) {
     
      pthread_t j;
      int err = 0;
     
      switch(current->task_type)  {
      case PAR_TASK_OS:
        err = generic_create_thread(generic_get_server_from_contract(current->contract),&j,NULL,
              oneshot_task,(void *)current,generic_get_task_model(current));
        break;
      case PAR_TASK_BT:
        err = generic_create_thread(generic_get_server_from_contract(current->contract),&j,NULL,
              back_task,(void *)current,generic_get_task_model(current));
        break;
      case PAR_TASK_CT:
        err = generic_create_thread(generic_get_server_from_contract(current->contract),&j,NULL,
              periodic_task,(void *)current,generic_get_task_model(current));
        break;
      }
      if (err) {
        printf("Error fsf task creating\n");
        generic_end_simulation();
      }
     
    }

    current = &loader_task_list[k];

  }
   
  printf("Created %d loader tasks\n",k);

 
}

/* Main Function */
int start_environment()
{

  extern struct timespec total_time;

  /* Calibrate the exec time */  
  generic_calibrate_cycle();
 
  /* Create the servers usign defined contracts */
  generic_fsfinit();

  /* Create the tasks */
  loader_task_create();

  /* Start the simulation */
  generic_start_simulation();

  /* Set the simulation end time */
  generic_set_simulation_time(&total_time);

  return 0;

}