1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
|
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <semaphore.h>
#define NBR_CYCLE 3
#define NBR_TRAME 1
#define PTU 2000 // 2ms
#define HIGHEST_PRIORITY 99
////////////////////////////////////////////////////////////////////
int nodes_nbr;
char *schedule_table[NBR_CYCLE][NBR_TRAME];
int using_priority_sched;
int priority_queu;
int master_ID;
int sync_sig=0;
/////////////////// CREATION DES SEMAPHORES
sem_t sync_pass, slave_pass;
/////////////////// MASTER_FUNC
void *master_func ()
{
int global_cycle = 0 ;
struct timeval begin, last, current;
long long int difference = 0;
sleep(1);
gettimeofday(&begin, NULL);
fprintf(stdout,"start [%ld.%06ld]\n", begin.tv_sec, begin.tv_usec);
current = begin;
while(1)
{
difference = 0;
do
{
last = current;
gettimeofday(¤t, NULL);
if ((current.tv_sec - begin.tv_sec) > 5)
{fprintf(stdout,"Exit timeout");
pthread_exit(NULL);
}
difference += 1000000 * (current.tv_sec - last.tv_sec);
difference += (current.tv_usec - last.tv_usec);
}while(difference < PTU);
//Le master_thread demande le semaphore
sem_wait(&sync_pass);
fprintf(stdout,"The Master is talking (%d) \n",sync_sig);
sync_sig++;
sync_sig %= NBR_CYCLE;
//Le master_thread relache le semaphore
if (sync_sig==0)
{
global_cycle=global_cycle+1;
fprintf(stdout,"New cycle (%d) and sync (%d)\n", global_cycle,sync_sig);
}
fprintf(stdout,"[%ld.%6ld] sync frame %4d diff = %6lld\n", current.tv_sec, current.tv_usec, sync_sig, difference);
sem_post(&sync_pass);
sched_yield();
}
return(0);
}
///////////////////// SLAVE_FUNC
void *slave_func(void *slave_data)
{
int j;
struct timeval tv;
while(1)
{
sem_wait(&slave_pass);
sem_wait(&sync_pass);
sync_sig++;
fprintf(stdout,"slave (%lu) is talking the current sync is (%d) \n",pthread_self(),sync_sig);
sem_post(&sync_pass);
sem_post(&slave_pass);
}
return(0);
}
////////////////MAIN
int main (int argc, char *argv[])
{
int val,i,j;
int err;
struct sched_param param_processus;
struct sched_param param_master_thr , param_slave_thr ;
pthread_attr_t master_attr , slave_attr;
////////////////// INITIALISATION DES SEMAPHORES
if (sem_init(&sync_pass,0,1)==-1)
{
perror("sync sem init");
exit (EXIT_FAILURE);
}
val=atoi(argv[1]);
fprintf(stdout,"val vaut: %d \n",val);
if (sem_init(&slave_pass,0,val)==-1)
{
perror("slave sem init");
exit (EXIT_FAILURE);
}
///////////////// AFFECTATION PRIORITE TEMPS REEL FIFO
param_processus.sched_priority = HIGHEST_PRIORITY;
if (sched_setscheduler(0, SCHED_FIFO, ¶m_processus) != 0)
{
perror("processus sched_setscheduler");
exit(EXIT_FAILURE);
}
///////////////// PREPARATION DES ATTRIBUTS DU MASTER_THREAD
pthread_attr_init(&master_attr);
if ((err=pthread_attr_setschedpolicy(&master_attr,SCHED_FIFO))!=0)
{
fprintf(stderr,"setschedpolicy master thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
if ((err=pthread_attr_setinheritsched(&master_attr,PTHREAD_EXPLICIT_SCHED))!=0)
{
fprintf(stderr,"setinheritshed master thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
param_master_thr.sched_priority = 99;
if ((err=pthread_attr_setschedparam(&master_attr,¶m_master_thr))!=0)
{
fprintf(stderr,"setschedparam master thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
///////////////// PREPARATION DES ATTRIBUTS DU SLAVE_THREAD
pthread_attr_init(&slave_attr);
if ((err=pthread_attr_setschedpolicy(&slave_attr,SCHED_FIFO))!=0)
{
fprintf(stderr,"setschedpolicy slave thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
if ((err=pthread_attr_setinheritsched(&slave_attr,PTHREAD_EXPLICIT_SCHED))!=0)
{
fprintf(stderr,"setinheritshed slave thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
param_slave_thr.sched_priority = 99;
if ((err=pthread_attr_setschedparam(&slave_attr,¶m_slave_thr))!=0)
{
fprintf(stderr,"setschedparam slave thread: %s\n",strerror(err));
exit(EXIT_FAILURE);
}
///////////////////////////////////////////////////// PREPARATION MILCAN_DATA
nodes_nbr=atoi(argv[1]);
using_priority_sched=atoi(argv[2]);
master_ID=atoi(argv[3]);
pthread_t master_thr ,
slave_thr[nodes_nbr];
//////////// REMPLISSAGE SCHEDULE TABLE
for ( i=0;i<NBR_CYCLE;i++)
{
for ( j=0;j<NBR_TRAME;j++)
{
schedule_table[i][j]=(char*)malloc(3 * sizeof(char));
sprintf(schedule_table[i][j],"%d.%d",i,j);
}
}
///////////////////// EXECUTION DES THREAD
if((err=pthread_create(&master_thr,NULL,master_func,NULL)!=0))
{
fprintf(stderr,"can't create master thread %s \n",strerror(err));
exit(EXIT_FAILURE);
}
for ( i=0;i<nodes_nbr;i++)
{
if((err=pthread_create(&slave_thr[i],NULL,slave_func,NULL)!=0))
{
fprintf(stderr,"can't create slave thread %s \n",strerror(err));
exit(EXIT_FAILURE);
}
}
// ATTENTE DE TOUS LES THREApthread_join(master_thr, NULL);
for ( i=0;i<nodes_nbr;i++)
{
pthread_join(slave_thr[i], NULL);
}
//DESALLOCATION MEMOIRE
for ( i=0;i<NBR_CYCLE;i++)
{
for ( j=0;j<NBR_TRAME;j++)
{
free(schedule_table[i][j]);
}
}
return 0;
} |
Partager