Revision 1006
Threading issues worked out better... Ready to add motion.
robot.c | ||
---|---|---|
20 | 20 |
#include <sys/types.h> |
21 | 21 |
#include <sys/shm.h> |
22 | 22 |
#include <errno.h> |
23 |
#include <pthread.h> |
|
23 | 24 |
|
24 | 25 |
#include "robot.h" |
26 |
#include "gtk_gui.h" |
|
25 | 27 |
|
26 | 28 |
void sig_chld_handler(int sig); |
27 | 29 |
|
... | ... | |
30 | 32 |
// an expanding array of robots |
31 | 33 |
Robot* robots = NULL; |
32 | 34 |
int robots_size = 0; |
35 |
int num_robots = 0; |
|
33 | 36 |
|
34 | 37 |
int iterator_pos = 0; |
35 | 38 |
|
39 |
// signalled when all robots have run for a bit |
|
40 |
pthread_mutex_t all_finished_mutex; |
|
41 |
pthread_cond_t all_finished_cond; |
|
42 |
int finished = 0; |
|
43 |
|
|
36 | 44 |
int robots_initialize(void) |
37 | 45 |
{ |
38 | 46 |
int i; |
... | ... | |
46 | 54 |
memset(robots, 0, sizeof(Robot) * robots_size); |
47 | 55 |
for (i = 0; i < robots_size; i++) |
48 | 56 |
robots[i].id = -1; |
57 |
|
|
58 |
finished = 0; |
|
59 |
pthread_mutex_init(&all_finished_mutex, NULL); |
|
60 |
pthread_cond_init(&all_finished_cond, NULL); |
|
49 | 61 |
|
50 | 62 |
return 0; |
51 | 63 |
} |
... | ... | |
59 | 71 |
int pid; |
60 | 72 |
int id = first_available_id; |
61 | 73 |
Robot* r = &robots[id]; |
74 |
printf("ID: %d\n", id); |
|
62 | 75 |
// do shared memory stuff here |
63 | 76 |
key_t key = IPC_PRIVATE; |
64 | 77 |
//Memory accessible only to children with r/w privileges |
... | ... | |
120 | 133 |
do { |
121 | 134 |
first_available_id++; |
122 | 135 |
} while (first_available_id < robots_size && |
123 |
robots[first_available_id].id != 0);
|
|
136 |
robots[first_available_id].id != -1);
|
|
124 | 137 |
// resize the array if necessary |
125 | 138 |
if (first_available_id >= robots_size) |
126 | 139 |
{ |
... | ... | |
133 | 146 |
} |
134 | 147 |
} |
135 | 148 |
} |
149 |
|
|
150 |
num_robots++; |
|
136 | 151 |
|
137 | 152 |
return id; |
138 | 153 |
} |
... | ... | |
182 | 197 |
// allocated memory |
183 | 198 |
Robot* robot_iterator_next(void) |
184 | 199 |
{ |
200 |
if (iterator_pos >= robots_size) |
|
201 |
return NULL; |
|
202 |
do iterator_pos++; |
|
185 | 203 |
while (iterator_pos < robots_size && |
186 |
robots[iterator_pos].id == -1) |
|
187 |
iterator_pos++; |
|
204 |
robots[iterator_pos].id == -1); |
|
188 | 205 |
|
189 | 206 |
if (iterator_pos >= robots_size) |
190 | 207 |
return NULL; |
... | ... | |
194 | 211 |
|
195 | 212 |
void sig_chld_handler(int sig) |
196 | 213 |
{ |
197 |
pid_t pid; |
|
198 |
int cstat; |
|
214 |
pthread_mutex_lock(&all_finished_mutex); |
|
215 |
finished++; |
|
216 |
if (finished >= num_robots) |
|
217 |
{ |
|
218 |
pthread_cond_signal(&all_finished_cond); |
|
219 |
} |
|
220 |
pthread_mutex_unlock(&all_finished_mutex); |
|
221 |
} |
|
199 | 222 |
|
200 |
printf("SIGCHLD: parent waiting\n"); |
|
223 |
void* robot_event_loop(void* arg) |
|
224 |
{ |
|
225 |
int i; |
|
226 |
//TODO: errors |
|
201 | 227 |
|
202 |
pid = waitpid(0, &cstat, WUNTRACED); |
|
228 |
while (1) |
|
229 |
{ |
|
230 |
pthread_mutex_lock(&all_finished_mutex); |
|
231 |
// TODO: race condition for adding robots? |
|
232 |
if (finished < num_robots) |
|
233 |
{ |
|
234 |
pthread_cond_wait(&all_finished_cond, &all_finished_mutex); |
|
235 |
} |
|
236 |
finished = 0; |
|
237 |
pthread_mutex_unlock(&all_finished_mutex); |
|
238 |
for (i = 0; i < robots_size; i++) |
|
239 |
{ |
|
240 |
if (robots[i].id == -1) |
|
241 |
continue; |
|
242 |
kill(robots[i].pid, SIGCONT); |
|
243 |
} |
|
203 | 244 |
|
204 |
printf("got %d from %d\n", cstat, pid); |
|
205 |
|
|
206 |
kill(pid, SIGCONT); |
|
245 |
gui_refresh(); |
|
246 |
} |
|
207 | 247 |
} |
208 | 248 |
|
Also available in: Unified diff