forked from piergo98/Ping-pong-robot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPTask.c
167 lines (131 loc) · 4.69 KB
/
PTask.c
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
#include "PTask.h"
/*Definizione delle funzioni che operano sulle variabili temporali*/
void time_copy (struct timespec *td, struct timespec ts){ //copia ts nella variabile temporale puntata da td
td->tv_sec = ts.tv_sec;
td->tv_nsec = ts.tv_nsec;
}
void time_add_ms (struct timespec *t, int ms){ //aggiunge ms (in millisecondi) alla variabile puntata da t
t->tv_sec += ms/1000;
t->tv_nsec += (ms%1000)*1000000;
if (t->tv_nsec > 1000000000){
t->tv_sec += 1;
t->tv_nsec -= 1000000000;
}
}
int time_cmp (struct timespec t1, struct timespec t2){ //compara due variabili e ritorna 0 se t1 = t2, 1 se t1 > t2, -1 se t1 < t2
if (t1.tv_sec > t2.tv_sec) return 1;
if (t1.tv_sec < t2.tv_sec) return -1;
if (t1.tv_nsec > t2.tv_nsec) return 1;
if (t1.tv_nsec < t2.tv_nsec) return -1;
return 0;
}
/*Definizione delle funzioni di PTASK*/
int task_create (void* (*task) (void *), int i, int period, int drel, int prio){ //crea un task
pthread_attr_t myatt; //definisco un puntatore alla struttura degli attributi
struct sched_param mypar; //definisco la struttura mypar, del tipo sched_param
int tret;
if (i > NT) return -1;
//sem_wait(&s1);
tp[i].arg = i;
tp[i].period = period;
tp[i].deadline = drel;
tp[i].priority = prio;
tp[i].dmiss = 0;
//sem_post(&s1);
pthread_attr_init (&myatt);
pthread_attr_setinheritsched (&myatt, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy (&myatt, SCHED_RR);
//sem_wait(&s1);
mypar.sched_priority = tp[i].priority;
//sem_post(&s1);
pthread_attr_setschedparam (&myatt, &mypar); //applica le modifiche agli attributi del thread
//sem_wait(&s1);
tret = pthread_create (&tid[i], &myatt, task, (void*)(&tp[i]));
//sem_post(&s1);
return tret;
}
int get_task_index (void* arg){ //restituisce l'indice del task
struct task_par *tpar;
tpar = (struct task_par *) arg;
return tpar->arg;
}
void set_activation (int i){ //legge il tempo corrente e calcola l'attivazione successiva e la deadline assoluta
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
//sem_wait(&s1);
time_copy(&(tp[i].at), t);
time_copy(&(tp[i].dl), t);
time_add_ms(&(tp[i].at), tp[i].period);
time_add_ms(&(tp[i].dl), tp[i].deadline);
//sem_post(&s1);
}
int deadline_miss (int i){ //conta il numero di deadline misses
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
//sem_wait(&s1);
if (time_cmp(now, tp[i].dl) > 0){
tp[i].dmiss++;
return 1;
}
//sem_post(&s1);
return 0;
}
void wait_for_activation (int i){ //sospende l'esecuzione del thread fino alla prossima attivazione
//sem_wait(&s1);
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &(tp[i].at), NULL);
time_add_ms(&(tp[i].at), tp[i].period);
time_add_ms(&(tp[i].dl), tp[i].deadline);
//sem_post(&s1);
}
int wait_for_end(int i){ //attende la terminazione del task
return pthread_join(tid[i], NULL);
}
void show_dmiss(int i){
char string[DIM_S];
switch(i){
case 0:
pthread_mutex_lock(&s14);
ball_miss += 1;
pthread_mutex_unlock(&s14);
break;
case 1:
pthread_mutex_lock(&s15);
camera_miss += 1;
pthread_mutex_unlock(&s15);
break;
case 2:
pthread_mutex_lock(&s16);
motor_x_miss += 1;
pthread_mutex_unlock(&s16);
break;
case 3:
pthread_mutex_lock(&s17);
motor_z_miss += 1;
pthread_mutex_unlock(&s17);
break;
case 4:
pthread_mutex_lock(&s18);
adv_x_miss += 1;
pthread_mutex_unlock(&s18);
break;
case 5:
pthread_mutex_lock(&s19);
adv_z_miss += 1;
pthread_mutex_unlock(&s19);
break;
case 6:
pthread_mutex_lock(&s20);
display_miss += 1;
pthread_mutex_unlock(&s20);
break;
case 7:
pthread_mutex_lock(&s21);
tastiera_miss += 1;
pthread_mutex_unlock(&s21);
break;
default: break;
}
}
void autokill(int i){
pthread_exit(NULL);
}