erkk84
09-01-2011, 17:03
Ciao a tutti, sono in cerca d'aiuto per la comprensione di alcuni argomenti riguardanti il mondo del RT, in particolare i PThreads e la loro schedulazione; premetto che singolarmente e nella teoria mi sembra di averli capiti, è la loro applicazione che mi sta dando problemi.
Sto cercando di capire un programmino che li integra, sostanzialmente scrive a video su terminale le coordinate di una pallina in movimento; non posto tutto il codice (anche perchè è suddiviso in file), ma solo quelle parti che non penso di aver capito bene.
Cominciamo dal main:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include "output.h"
#include "system.h"
#include "control.h"
int main(int argc, char *argv[])
{
int res;
void *returnvalue;
pthread_t system_id, control_id, output_id;
/*const*/ double system_period = 0.005, control_period = 0.2;
/*const*/ int output_period = 300;
printf("Chiamo system_id\n");
res = pthread_create(&system_id, NULL, system_body, &system_period); //crea un pthread, al quale è associato un id, attr di default (NULL), funzione
//col codice (in system.c) che deve eseguire e l'argomento passato alla funzione
// (&system_period)
if (res) {
perror("pthread_create system");
return -1;
}
printf("Chiamo control_id\n");
res = pthread_create(&control_id, NULL, control_body, &control_period); //idem come sopra; funzione in control.c
if (res) {
perror("pthread_create control");
return -1;
}
printf("Chiamo output_id\n");
res = pthread_create(&output_id, NULL, output_body, &output_period); //idem come sopra; funzione in output.c
if (res) {
perror("pthread_create output");
return -1;
}
pthread_join(system_id, &returnvalue);
pthread_join(control_id, &returnvalue);
pthread_join(output_id, &returnvalue);
return 0;
}
i body dei pthreads sono:
void *system_body(void *p)
{
printf("Chiamo system_body\n");
double dt = *(double *)p; //p=0.005
struct periodic_task *t;
double th;
int j=0;
r = 1;
r1 = 0;
th = 0;
t = start_periodic_timer(0, 1000000.0 * dt);
while(j<20) {
th = c();
//printf("THETA: %d\n", (int)th);
r1 = f1(r1, th, dt);
r = f(r, r1, dt);
wait_next_activation(t);
j++;
}
return NULL;
}
void *control_body(void *p)
{
printf("Chiamo control_body\n");
double dt = *(double *)p;
struct periodic_task *t;
double u, u1;
const double kp = -3, kd = -3;
int i;
u = 0; u1 = 0;
i = 0;
t = start_periodic_timer(0, 1000000.0 * dt);
u1 = position();
while(1) {
wait_next_activation(t);
i++;
u = position();
theta = kp * (ref(dt * i) - u) - kd * (u - u1) / dt;
u1 = u;
}
void *output_body(void *p)
{
printf("Chiamo ouput_body\n");
int dt = *(int *)p;
struct periodic_task *t;
int i;
i = 0;
t = start_periodic_timer(0, 1000 * dt);
while(1) {
printf("%lf\t%lf\n", dt / 1000.0 * i, position());
fflush(stdout);
wait_next_activation(t);
i++;
}
Questi ultimi si trovano in file diversi; lasciate stare le funzioi chiamate internamente, quelle non mi danno particolari problemi, fanno dei loro calcoli matematici.
In ultimo, la parte relativa alle chiamate di sistema.
extern int clock_nanosleep(clockid_t __clock_id, int __flags,
__const struct timespec *__req,
struct timespec *__rem);
struct periodic_task {
struct timespec r;
int period;
} ;
#define NSEC_PER_SEC 1000000000ULL
static inline void timespec_add_us(struct timespec *t, uint64_t d)
{
d *= 1000;
d += t->tv_nsec;
while (d >= NSEC_PER_SEC) {
d -= NSEC_PER_SEC;
t->tv_sec += 1;
}
t->tv_nsec = d;
}
void wait_next_activation(struct periodic_task *pd)
{
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &pd->r, NULL);
timespec_add_us(&pd->r, pd->period);
}
struct periodic_task *start_periodic_timer(uint64_t offs, int t)
{
struct periodic_task *task;
task = malloc(sizeof(struct periodic_task));
clock_gettime(CLOCK_REALTIME, &task->r);
timespec_add_us(&task->r, offs);
task->period = t;
return task;
}
Il problema è: non riesco a capire come vengono gestiti i vari PThreads; cioè, io ad esempio avrei detto che viene chiamato prima il body "System", invece viene chiamato prima il control, poi l'output e poi il System...e questo è uno dei problemi;
Poi, non riesco a capire la schedulazione dei processi con le varie chiamate a start_periodic_timer, wait_next-activation, ecc...
C'è qualche buon'anima che mi potrebbe aiutare in questo senso?Magari allego il pacchetto dei file completii per avere un'idea migliore di come è strutturato il programma.
Grazie
Sto cercando di capire un programmino che li integra, sostanzialmente scrive a video su terminale le coordinate di una pallina in movimento; non posto tutto il codice (anche perchè è suddiviso in file), ma solo quelle parti che non penso di aver capito bene.
Cominciamo dal main:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <stdint.h>
#include "output.h"
#include "system.h"
#include "control.h"
int main(int argc, char *argv[])
{
int res;
void *returnvalue;
pthread_t system_id, control_id, output_id;
/*const*/ double system_period = 0.005, control_period = 0.2;
/*const*/ int output_period = 300;
printf("Chiamo system_id\n");
res = pthread_create(&system_id, NULL, system_body, &system_period); //crea un pthread, al quale è associato un id, attr di default (NULL), funzione
//col codice (in system.c) che deve eseguire e l'argomento passato alla funzione
// (&system_period)
if (res) {
perror("pthread_create system");
return -1;
}
printf("Chiamo control_id\n");
res = pthread_create(&control_id, NULL, control_body, &control_period); //idem come sopra; funzione in control.c
if (res) {
perror("pthread_create control");
return -1;
}
printf("Chiamo output_id\n");
res = pthread_create(&output_id, NULL, output_body, &output_period); //idem come sopra; funzione in output.c
if (res) {
perror("pthread_create output");
return -1;
}
pthread_join(system_id, &returnvalue);
pthread_join(control_id, &returnvalue);
pthread_join(output_id, &returnvalue);
return 0;
}
i body dei pthreads sono:
void *system_body(void *p)
{
printf("Chiamo system_body\n");
double dt = *(double *)p; //p=0.005
struct periodic_task *t;
double th;
int j=0;
r = 1;
r1 = 0;
th = 0;
t = start_periodic_timer(0, 1000000.0 * dt);
while(j<20) {
th = c();
//printf("THETA: %d\n", (int)th);
r1 = f1(r1, th, dt);
r = f(r, r1, dt);
wait_next_activation(t);
j++;
}
return NULL;
}
void *control_body(void *p)
{
printf("Chiamo control_body\n");
double dt = *(double *)p;
struct periodic_task *t;
double u, u1;
const double kp = -3, kd = -3;
int i;
u = 0; u1 = 0;
i = 0;
t = start_periodic_timer(0, 1000000.0 * dt);
u1 = position();
while(1) {
wait_next_activation(t);
i++;
u = position();
theta = kp * (ref(dt * i) - u) - kd * (u - u1) / dt;
u1 = u;
}
void *output_body(void *p)
{
printf("Chiamo ouput_body\n");
int dt = *(int *)p;
struct periodic_task *t;
int i;
i = 0;
t = start_periodic_timer(0, 1000 * dt);
while(1) {
printf("%lf\t%lf\n", dt / 1000.0 * i, position());
fflush(stdout);
wait_next_activation(t);
i++;
}
Questi ultimi si trovano in file diversi; lasciate stare le funzioi chiamate internamente, quelle non mi danno particolari problemi, fanno dei loro calcoli matematici.
In ultimo, la parte relativa alle chiamate di sistema.
extern int clock_nanosleep(clockid_t __clock_id, int __flags,
__const struct timespec *__req,
struct timespec *__rem);
struct periodic_task {
struct timespec r;
int period;
} ;
#define NSEC_PER_SEC 1000000000ULL
static inline void timespec_add_us(struct timespec *t, uint64_t d)
{
d *= 1000;
d += t->tv_nsec;
while (d >= NSEC_PER_SEC) {
d -= NSEC_PER_SEC;
t->tv_sec += 1;
}
t->tv_nsec = d;
}
void wait_next_activation(struct periodic_task *pd)
{
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &pd->r, NULL);
timespec_add_us(&pd->r, pd->period);
}
struct periodic_task *start_periodic_timer(uint64_t offs, int t)
{
struct periodic_task *task;
task = malloc(sizeof(struct periodic_task));
clock_gettime(CLOCK_REALTIME, &task->r);
timespec_add_us(&task->r, offs);
task->period = t;
return task;
}
Il problema è: non riesco a capire come vengono gestiti i vari PThreads; cioè, io ad esempio avrei detto che viene chiamato prima il body "System", invece viene chiamato prima il control, poi l'output e poi il System...e questo è uno dei problemi;
Poi, non riesco a capire la schedulazione dei processi con le varie chiamate a start_periodic_timer, wait_next-activation, ecc...
C'è qualche buon'anima che mi potrebbe aiutare in questo senso?Magari allego il pacchetto dei file completii per avere un'idea migliore di come è strutturato il programma.
Grazie