/*
 * tasks.c
 *
 * Written by Vicente Esteve LLoret <viesllo@inf.upv.es>
 * Copyright (C) Dec, 2002 OCERA Consortium.
 *
 * 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 version 2.
 *
 * Function init_tasks is called from init.c and it's used to create and
 * initializate tasks.
 */

#include <rtl_conf.h>
#include <time.h>
#include <pthread.h>
#include <rtl_ipc.h>
#include <semaphore.h>
#include <rtl_barrier.h>
#include <rtl_printf.h>
#include <unistd.h>
#include <rtl_posixio.h>
#include "examples.h"

#ifdef CONFIG_XTRATUM
#include <arch/XtratuM_API.h>
#endif

extern pthread_t thread1;
extern pthread_t thread2;
extern pthread_t thread3;
extern pthread_t thread4;
extern pthread_t thread5;
extern pthread_t thread6;
extern pthread_t thread7;
extern pthread_t thread8;
extern pthread_t thread9;
extern pthread_t thread10;
extern pthread_t thread11;
extern pthread_t thread12;
extern pthread_t thread13;
extern pthread_t thread14[10];
extern pthread_t thread15[20];
extern pthread_t thread16;
extern pthread_t thread17;
extern pthread_t thread18;
extern pthread_t thread19;
extern pthread_t thread20;


#if CONFIG_OC_PBARRIERS && BARRIERS_EXAMPLE 
extern pthread_barrier_t   barrier; // barrier synchronization object
extern pthread_barrierattr_t barrier_attr;
#endif

#if _RTL_POSIX_SEMS && SEM_EXAMPLE
extern sem_t sem;
#endif

#if _RTL_POSIX_MUTEXS 
static pthread_mutex_t mutex;
static pthread_mutex_t withoutcas;
#endif

void *task1(void *arg);
void *task2(void *arg);
void *task3(void *arg);
void *task4(void *arg);
void *task5(void *arg);
void *task6(void *arg);
void *task7(void *arg);
void *task8(void *arg);
void *task9(void *arg);
void *task10(void *arg);
void *task11(void *arg);
void *task12(void *arg);
void *task13(void *arg);
void *task14(void *arg);
void *task15(void *arg);
void *task16(void *arg);
void *task17(void *arg);
void *task18(void *arg);
void *task19(void *arg);
void *task20(void *arg);

unsigned long mprot_prueba;

void init_tasks(void)
{
 struct sched_param sched_param;
 pthread_attr_t attr;
#ifdef CONFIG_XTRATUM
 xm_write_domain("Init Tasks\n",13);
#endif
 
#if CONFIG_OC_PBARRIERS && BARRIERS_EXAMPLE
 pthread_barrierattr_init(&barrier_attr);
 pthread_barrier_init (&barrier, &barrier_attr, 2);
 pthread_barrierattr_destroy(&barrier_attr);
#endif

#if _RTL_POSIX_SEMS && SEM_EXAMPLE
 sem_init (&sem, 1, 1);
#endif

#if _RTL_POSIX_MUTEXS
 pthread_mutex_init (&mutex, 0);
 pthread_mutex_init (&withoutcas, 0);
#endif
 
// rt_sem_init (&sem, RT_SEM_BINARY, 1);
//

  // PERIODIC THREAD EXAMPLE 
#if PERIODIC_EXAMPLE
   pthread_create(&thread1,NULL,task1,0);
   pthread_create(&thread2,NULL,task2,0);
#endif
  // BARRIERS EXAMPLE
#if BARRIERS_EXAMPLE
   pthread_create(&thread3,NULL,task3,0);
   pthread_create(&thread4,NULL,task4,0);
#endif
  // MUTEX EXAMPLE
#if MUTEX_EXAMPLE
   pthread_create(&thread5,NULL,task5,0);
   pthread_create(&thread6,NULL,task6,0);
#endif
  // SEMAPHORE EXAMPLE  
#if SEM_EXAMPLE
   pthread_create(&thread7,NULL,task7,0);
   pthread_create(&thread8,NULL,task8,0);
#endif
  // MPROTECT EXAMPLE
#if MPROT_EXAMPLE
   pthread_create(&thread9,NULL,task9,0);
#endif
  // POSIXIO EXAMPLE
#if POSIXIO_EXAMPLE
   pthread_create(&thread10,NULL,task10,0); 
#endif
  // TERMINAL EXAMPLE
#if TERMINAL_EXAMPLE
   pthread_create(&thread11,NULL,task11,0); 
#endif
#if QUAJECT_EXAMPLE
  pthread_attr_init (&attr);
  sched_param.sched_priority = 100;
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_create(&thread12,&attr,task12,0); 
  pthread_attr_init (&attr);
  sched_param.sched_priority = 20;
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_create(&thread13,&attr,task13,0); 
#endif

#if YABIRO_EXAMPLE
  {	  
    int i=0;
//    for (i=0;i<1;i++) {
     pthread_attr_init (&attr);
     pthread_attr_setfp_np(&attr, 1);
     sched_param.sched_priority = 2;
     pthread_attr_setschedparam (&attr, &sched_param);
     pthread_create(&(thread14[i]),&attr,task14,(void *) i);
//    };
  }    
#endif

#if TANK_EXAMPLE
  pthread_attr_init (&attr);
  sched_param.sched_priority = 100;
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_attr_setfp_np(&attr, 1);
  pthread_create(&thread17,&attr,task17,0); 
  
  pthread_attr_init (&attr);
  sched_param.sched_priority = 100;
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_attr_setfp_np(&attr, 1);
  pthread_create(&thread18,&attr,task18,0); 
  
  pthread_attr_init (&attr);
  sched_param.sched_priority = 100;
  pthread_attr_setfp_np(&attr, 1);
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_create(&thread19,&attr,task19,0); 

  pthread_attr_init (&attr);
  sched_param.sched_priority = 20;       // Less prioritary
  pthread_attr_setfp_np(&attr, 1);
  pthread_attr_setschedparam (&attr, &sched_param);
  pthread_create(&thread16,&attr,task16,0); 
  
#endif
  
#if EXIT_EXAMPLE
  {
    int i;
    for (i=0;i<20;i++) {
     pthread_create(&(thread15[i]),NULL,task15,(void *) i);
    };
  }    
#endif

#if FP_EXAMPLE
  pthread_attr_init (&attr);
  pthread_attr_setfp_np(&attr, 1);
  pthread_create(&thread20,&attr,task20,0); 
#endif

  
}


