-
Notifications
You must be signed in to change notification settings - Fork 0
/
movements.c
151 lines (124 loc) · 3.8 KB
/
movements.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
#include "movements.h"
#include <fcntl.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/sem.h>
#define STEP_ROW_BYTES (DEVICE_COUNT * 3 + (DEVICE_COUNT - 1))
#define STEP_ROW_EOL "\n"
//Contatore dei movimenti
long movements_count;
//Puntatore a un blocco di memoria contenente tutti i movimenti presi dai device
movement *movements_mem_ptr;
//Inizializzazione dei movimenti
int initialize_steps(char *path)
{
//Apro il file delle posizioni
int fd = open(path, S_IRUSR);
if (fd == -1)
return -1;
//Informazioni del file
struct stat f_stat;
if (fstat(fd, &f_stat) == -1)
return -1;
//Conteggio righe del file
movements_count = f_stat.st_size / (long)(STEP_ROW_BYTES + sizeof(STEP_ROW_EOL) - 1);
//Alloco memoria per ogni riga di movimenti
movements_mem_ptr = malloc(sizeof(movement) * movements_count);
if (movements_mem_ptr == NULL)
return -1;
//Inizializzo una riga
char buf[STEP_ROW_BYTES];
for (int step_i = 0; step_i < movements_count; step_i++)
{
//Leggo la riga
if (read(fd, buf, STEP_ROW_BYTES) < STEP_ROW_BYTES)
return -1;
//Setto l'offset per la prossima lettura
if (lseek(fd, 1, SEEK_CUR) == -1)
return -1;
//Setto la posizione del singolo movimento per ogni device
for (int device_i = 0; device_i < DEVICE_COUNT; device_i++)
{
movements_mem_ptr[step_i][device_i].x = buf[device_i * 4] - '0';
movements_mem_ptr[step_i][device_i].y = buf[device_i * 4 + 2] - '0';
}
}
//Chiusura del file delle posizioni
if (close(fd) == -1)
return -1;
return 0;
}
//Chiusura dei movimenti
void teardown_steps()
{
//Se esiste il blocco di memoria, cancellalo
if (movements_mem_ptr != NULL)
free(movements_mem_ptr);
}
//Semaforo dei movimenti
static int steps_sem_id;
//Inizializzazione dei semafori per movimenti
int initialize_move_semaphores()
{
//Creazione del semaforo (6 semafori)
steps_sem_id = semget(IPC_PRIVATE, DEVICE_COUNT + 1, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
if (steps_sem_id == -1)
return -1;
//Array di char per settare i semafori a 0
unsigned char *initializer[DEVICE_COUNT + 1] = {0};
//Set dei semafori a 0
if (semctl(steps_sem_id, 0, SETALL, initializer) == -1)
return -1;
return 0;
}
//Chiusura dei semafori per movimenti
int teardown_move_semaphores()
{
//Se il semaforo non è nullo o vuoto
if (steps_sem_id != 0 && steps_sem_id != -1)
//Cancellazione del semaforo
if (semctl(steps_sem_id, 0, IPC_RMID) == -1)
return -1;
return 0;
}
//Variabile movimento corrente
int current_movement = 0;
//Turno di attesa
int wait_turn(int device_i)
{
//Creazione dell'operazione del semaforo
struct sembuf op = {.sem_num = device_i, .sem_op = -1};
//Set del semaforo nel semaforo dei movimenti
if (semop(steps_sem_id, &op, 1) == -1)
return -1;
return 0;
}
//Passa il turno al successivo
int pass_turn(int device_i)
{
//Creazione dell'operazione del semaforo
struct sembuf op = {.sem_num = device_i + 1, .sem_op = +1};
//Set del semaforo nel semaforo dei movimenti
if (semop(steps_sem_id, &op, 1) == -1)
return -1;
return 0;
}
//Effettua movimento
int perform_step()
{
for (int i = 0; i < 2; i++)
{
//Creazione dell'operazione del semaforo
struct sembuf op = {.sem_num = 0, .sem_op = +1};
//Set del semaforo nel semaforo dei movimenti
if (semop(steps_sem_id, &op, 1) == -1)
return -1;
op.sem_num = DEVICE_COUNT;
op.sem_op = -1;
//Set del semaforo nel semaforo dei movimenti
if (semop(steps_sem_id, &op, 1) == -1)
return -1;
}
current_movement++;
return 0;
}