Hi! I have modified rtt-sender.c and rtt-responder.c in the way you see in attachments, i use them in two different shells with the two commands (on the same machine):

1. ./rtt-sender -d 127.0.0.1
2. ./rtt-responder -l 127.0.0.1

rtt-sender goes in Segmentation Fault and rtt-responder remains up. What i do wrong?

I see in debug messages that sendto_rt in transmitter function doesnt't send anything! Why?
the messages are:

sendo failed - perror: Success.

The segmentation fault happens after the first pthread_join, in __nptl_death_event() from /lib/tls/libthread.so.0

--
Teresa Noviello
Chiedersi Sempre:"Avro' il tempo di rifarlo?"
/***
 *
 *  examples/xenomai/posix/rtt-responder.c
 *
 *  Round-Trip Time Responder - listens and sends back a packet
 *
 *  Based on Ulrich Marx's module, later ported over user space POSIX.
 *
 *  Copyright (C) 2002 Ulrich Marx <[EMAIL PROTECTED]>
 *                2002 Marc Kleine-Budde <[EMAIL PROTECTED]>
 *                2004, 2006 Jan Kiszka <[EMAIL PROTECTED]>
 *
 *  RTnet - real-time networking example
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/mman.h>
#include <arpa/inet.h>

#include <rtnet.h>

//my defines
#define DEBUG 1

extern void switch_errno(int);

char *dest_ip_s = "";
char *local_ip_s  = "";
unsigned int reply_size = 0;

pthread_t rt_thread;

#define RCV_PORT    36000
#define XMT_PORT    35999

struct sockaddr_in dest_addr;

int sock;

char buffer[65536];


void *responder(void* arg)
{
    RT_TASK *task;
    struct msghdr       rx_msg;
    struct iovec        iov;
    ssize_t             ret;


    if (dest_addr.sin_addr.s_addr == INADDR_ANY) {
        rx_msg.msg_name    = &dest_addr;
        rx_msg.msg_namelen = sizeof(dest_addr);
    } else {
        rx_msg.msg_name    = NULL;
        rx_msg.msg_namelen = 0;
    }
    rx_msg.msg_namelen     = sizeof(struct sockaddr_in);
    rx_msg.msg_iov         = &iov;
    rx_msg.msg_iovlen      = 1;
    rx_msg.msg_control     = NULL;
    rx_msg.msg_controllen  = 0;

//create rt_task
if (!(task = rt_task_init_schmod(nam2num("Responder"), 0, 0, 0, SCHED_FIFO, 0xF))) {
                printf("CANNOT INIT Responder TASK\n");
                exit(1);
        }

mlockall(MCL_CURRENT|MCL_FUTURE);

rt_make_hard_real_time();

    while(1) {
        iov.iov_base = &buffer;
        iov.iov_len  = sizeof(buffer);

        ret = recvmsg_rt(sock, &rx_msg, 0);
        if (ret <= 0) {
            printf("terminating responder thread\n");
            return NULL;
        }

        sendto_rt(sock, &buffer, reply_size ? : ret, 0,
               (struct sockaddr *)&dest_addr,
               sizeof(struct sockaddr_in));
  }
}


void catch_signal(int sig)
{
}


int main(int argc, char *argv[])
{
    RT_TASK *task;
    struct sockaddr_in local_addr;
    int add_rtskbs = 30;
    pthread_attr_t thattr;
    int ret;


    while (1) {
        switch (getopt(argc, argv, "d:l:s:")) {
            case 'd':
                dest_ip_s = optarg;
                break;

            case 'l':
                local_ip_s = optarg;
                break;

            case 's':
                reply_size = atoi(optarg);
                break;

            case -1:
                goto end_of_opt;

            default:
                printf("usage: %s [-d <dest_ip>] [-l <local_ip>] "
                       "[-s <reply_size>]\n", argv[0]);
                return 0;
        }
    }
 end_of_opt:

    if (dest_ip_s[0])
        inet_aton(dest_ip_s, &dest_addr.sin_addr);
    else
        dest_addr.sin_addr.s_addr = INADDR_ANY;

    if (local_ip_s[0])
        inet_aton(local_ip_s, &local_addr.sin_addr);
    else
        local_addr.sin_addr.s_addr = INADDR_ANY;

    if (reply_size > 65505)
        reply_size = 65505;
    else if (reply_size < sizeof(struct timespec))
        reply_size = sizeof(struct timespec);

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    signal(SIGHUP, catch_signal);


    printf("destination ip address: %s = %08x\n",
           dest_ip_s[0] ? dest_ip_s : "SENDER", dest_addr.sin_addr.s_addr);
    printf("local ip address: %s = %08x\n",
           local_ip_s[0] ? local_ip_s : "INADDR_ANY", local_addr.sin_addr.s_addr);
    printf("reply size: %d\n", reply_size);

//create rt_task
if (!(task = rt_task_init_schmod(nam2num("MainResp"), 0, 0, 0, SCHED_FIFO, 0xF))) {
                printf("CANNOT INIT MainResp TASK\n");
                exit(1);
        }

    mlockall(MCL_CURRENT|MCL_FUTURE);

    /* create rt-socket */
    if ((sock = socket_rt(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
	switch_errno(errno);
        perror("\n\t***\t\nsocket cannot be (_rt) created");
        return 1;
    }

    /* bind the rt-socket to local_addr */
    local_addr.sin_family = AF_INET;
    local_addr.sin_port   = htons(RCV_PORT);
    if ((ret = bind_rt(sock, (struct sockaddr *)&local_addr,
                    sizeof(struct sockaddr_in))) < 0) {
        close_rt(sock);
        perror("cannot bind_rt to local ip/port");
        return 1;
    }

    /* extend the socket pool */
    ret = ioctl_rt(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != add_rtskbs)
        printf("WARNING: ioctl_rt(RTNET_RTIOC_EXTPOOL) = %d\n", ret);

    /* create reply rt-thread */
    pthread_attr_init(&thattr);
    pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setstacksize(&thattr, PTHREAD_STACK_MIN);
    ret = pthread_create(&rt_thread, &thattr, &responder, NULL);
    if (ret) {
        close(sock);
        perror("pthread_create failed");
        return 1;
    }

    pause();

    /* Important: First close the socket! */
    while ((close_rt(sock) < 0) && (errno == EAGAIN)) {
        printf("socket busy - waiting...\n");
        sleep(1);
    }

    pthread_kill(rt_thread, SIGHUP);
    pthread_join(rt_thread, NULL);

    return 0;
}
/***
 *
 *  examples/xenomai/posix/rtt-requester.c
 *
 *  Round-Trip Time Requester - sends packet, receives echo, evaluates
 *                              and displays per-station round-trip times
 *
 *  Based on Ulrich Marx's module, adopted to RTmac and later ported over
 *  user space POSIX.
 *
 *  Copyright (C) 2002 Ulrich Marx <[EMAIL PROTECTED]>
 *                2002 Marc Kleine-Budde <[EMAIL PROTECTED]>
 *                2006 Jan Kiszka <[EMAIL PROTECTED]>
 *
 *  RTnet - real-time networking example
 *  RTmac - real-time media access control example
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

//my defines
#define DEBUG 1
#define __NOSEND__ 0


//#if DEBUG
#include <rtai_mq.h>
//#else
//#include <mqueue.h>
//#endif


#include <errno.h>
#include <pthread.h>
#include <signal.h>

#include <netinet/in.h>
#include <sys/mman.h>
#include <arpa/inet.h>

#include <rtai_lxrt.h>
#include <rtnet.h>
#include <time.h>


char *dest_ip_s = "127.0.0.1";
char *local_ip_s = "";
unsigned int cycle = 100000; /* 100 ms */

pthread_t xmit_thread;
pthread_t recv_thread;

#define RCV_PORT    35999
#define XMT_PORT    36000

struct sockaddr_in dest_addr;

int sock;
mqd_t mq;

#define BUFSIZE 1500
union {
    char            data[BUFSIZE];
    struct timespec tx_date;
} packet;

struct station_stats {
    struct in_addr  addr;
    long long       last, min, max;
    unsigned long   count;
};

struct packet_stats {
    struct in_addr  addr;
    long long       rtt;
};

#define MAX_STATIONS 100
static struct station_stats station[MAX_STATIONS];

extern void switch_errno(int);

static struct station_stats *lookup_stats(struct in_addr addr)
{
    int i;

    for (i = 0; i < MAX_STATIONS; i++) {
        if (station[i].addr.s_addr == addr.s_addr)
            break;
        if (station[i].addr.s_addr == 0) {
            station[i].addr = addr;
            station[i].min  = LONG_MAX;
            station[i].max  = LONG_MIN;
            break;
        }
    }
    if (i == MAX_STATIONS)
        return NULL;
    return &station[i];
}


void *transmitter(void *arg)
{
    RT_TASK *task;
    struct timespec     next_period;
    struct timespec     tx_date;

//sostituiscimi
    clock_gettime(CLOCK_MONOTONIC, &next_period);

//create rt_task
if (!(task = rt_task_init_schmod(nam2num("Transmitter"), 0, 0, 0, SCHED_FIFO, 0xF))) {
                printf("CANNOT INIT Transmitter TASK\n");
                exit(1);
        }

mlockall(MCL_CURRENT|MCL_FUTURE);

rt_make_hard_real_time();

    while(1) {
        next_period.tv_nsec += cycle * 1000;
        if (next_period.tv_nsec >= 1000000000) {
            next_period.tv_nsec = 0;
            next_period.tv_sec++;
        }

//sostituiscimi
        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_period, NULL);
//sostituiscimi
        clock_gettime(CLOCK_MONOTONIC, &tx_date);

        /* transmit the request packet containing the local time */
        if (sendto_rt(sock, &tx_date, sizeof(tx_date), 0,
                   (struct sockaddr *)&dest_addr,
                   sizeof(struct sockaddr_in)) < 0) {
			printf("sendto_rt non riuscita, chiamo switch_errno\n");
			switch_errno(errno);

            	if (errno == EBADF){
                	printf("terminating transmitter thread\n");
            	}
		else
                	perror("sendto failed - perror");
		
		//rt_make_soft_real_time();
		//rt_task_delete(task);
           	return NULL;
        }
    } //fine while

rt_make_soft_real_time();
rt_task_delete(task);

}

void *receiver(void *arg)
{
    RT_TASK *task;
    struct msghdr       msg;
    struct iovec        iov;
    struct sockaddr_in  addr;
    struct timespec     rx_date;
    struct packet_stats stats;
    int                 ret;

    msg.msg_name       = &addr;
    msg.msg_namelen    = sizeof(addr);
    msg.msg_iov        = &iov;
    msg.msg_iovlen     = 1;
    msg.msg_control    = NULL;
    msg.msg_controllen = 0;

//create rt_task
if (!(task = rt_task_init_schmod(nam2num("Receiver"), 0, 0, 0, SCHED_FIFO, 0xF))) {
                printf("CANNOT INIT Receiver TASK\n");
                exit(1);
        }

mlockall(MCL_CURRENT|MCL_FUTURE);
rt_make_hard_real_time();


    while (1) {
        iov.iov_base = &packet;
        iov.iov_len  = sizeof(packet);
        ret = recvmsg_rt(sock, &msg, 0);
		if (ret <= 0) {
		printf("pacchetti non rt-ricevuti nel threads receiver!Invoco switch_errno\n");
		switch_errno(errno);
   		printf("terminating receiver thread\n");
		perror("error from perror\n");
		rt_make_soft_real_time();
		rt_task_delete(task);
            	return NULL;
        	}
        clock_gettime(CLOCK_MONOTONIC, &rx_date);
        stats.rtt = rx_date.tv_sec * 1000000000LL + rx_date.tv_nsec;
        stats.rtt -= packet.tx_date.tv_sec * 1000000000LL +
        packet.tx_date.tv_nsec;
        stats.addr = addr.sin_addr;
        mq_send(mq, (char *)&stats, sizeof(stats), 0);
    }

rt_make_soft_real_time();
rt_task_delete(task);

}


void catch_signal(int sig)
{
    mq_close(mq);
}


int main(int argc, char *argv[])
{
	RT_TASK *task;

	struct sched_param param = { .sched_priority = 1 };
	struct sockaddr_in local_addr;
	int add_rtskbs = 30;
	pthread_attr_t thattr;
	char mqname[16];
	struct mq_attr mqattr;
	int max_stations = 0;
	int ret;

    while (1) {
        switch (getopt(argc, argv, "d:l:c::h")) {
            case 'd':
                dest_ip_s = optarg;
                break;

            case 'l':
                local_ip_s = optarg;
                break;

            case 'c':
                cycle = atoi(optarg);
                break;

            case -1:
                goto end_of_opt;

		case 'h':
                printf("usage: %s [-d <dest_ip>] [-l <local_ip>] "
                       "[-c <cycle_microsecs>]\n", argv[0]);
                return 0;
		
            default:
                printf("usage: %s [-d <dest_ip>] [-l <local_ip>] "
                       "[-c <cycle_microsecs>]\n", argv[0]);
                return 0;
        }
    }
 end_of_opt:

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port   = htons(XMT_PORT);
    if (dest_ip_s[0])
        inet_aton(dest_ip_s, &dest_addr.sin_addr);
    else
        dest_addr.sin_addr.s_addr = INADDR_ANY;

    if (local_ip_s[0])
        inet_aton(local_ip_s, &local_addr.sin_addr);
    else
        local_addr.sin_addr.s_addr = INADDR_ANY;

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    signal(SIGHUP, catch_signal);

    printf("destination ip address: %s = %08x\n",
           dest_ip_s[0] ? dest_ip_s : "SENDER", dest_addr.sin_addr.s_addr);
    printf("local ip address: %s = %08x\n",
           local_ip_s[0] ? local_ip_s : "INADDR_ANY", local_addr.sin_addr.s_addr);
    printf("cycle: %d us\n", cycle);

//create rt_task
if (!(task = rt_task_init_schmod(nam2num("Prova"), 0, 0, 0, SCHED_FIFO, 0xF))) {
                printf("CANNOT INIT PROVA TASK\n");
                exit(1);
        }

    /* create rt-socket */
if ((sock = socket_rt(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        switch_errno(errno);
        perror("\n\t***\t\nsocket cannot be (_rt) created:\n");
        return 1;
    }


/* bind the rt-socket to local_addr */
    local_addr.sin_family = AF_INET;
    local_addr.sin_port   = htons(RCV_PORT);
    if ((ret = bind_rt(sock, (struct sockaddr *)&local_addr,
                    sizeof(struct sockaddr_in))) < 0) {
        close_rt(sock);
        perror("cannot bind_rt to local ip/port");
        return 1;
    }

    /* extend the socket pool */
//debug
#if DEBUG
	printf("stampo RTNET_RTIOC_EXTPOOL:\t%d\n",RTNET_RTIOC_EXTPOOL);
#endif

ret = ioctl_rt(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != add_rtskbs)
        printf("WARNING: ioctl_rt(RTNET_RTIOC_EXTPOOL) = %d\n", ret);
	if(ret < 0){
		switch_errno(errno);
		perror("L'errore nella ioctl_rt e'...\n");
	}


    /* create statistic message queue */
    snprintf(mqname, sizeof(mqname), "rtt-sender-%d", getpid());
	
//debug
#if DEBUG
printf("Terminata la inizializzazione di nome di coda di messaggi:\n"
	"scrivo il nome della coda di messaggi:`t%s\n",mqname);
#endif

    mqattr.mq_flags   = 0;
    mqattr.mq_maxmsg  = 100;
    mqattr.mq_msgsize = sizeof(struct packet_stats);
    mqattr.mq_curmsgs = 0;

//debug
#if DEBUG
printf("Terminata inizializzazione attributi della coda di messaggi\n");
#endif

    mq = mq_open(mqname, O_RDWR | O_CREAT | O_EXCL, 0600, &mqattr);
	
//debug
#if DEBUG
printf("Terminata la mq_open\n");
#endif
    if (mq == (mqd_t)-1) {
        perror("opening mqueue failed");
        close_rt(sock);
        return 1;
    }


//creazione dei threads, modalita' normale - non hard real time

   /* create transmitter rt-thread */
    pthread_attr_init(&thattr);
    pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setstacksize(&thattr, PTHREAD_STACK_MIN);

//debug
#if DEBUG
printf("Creazione del transmitter pthread\n");
#endif
    ret = pthread_create(&xmit_thread, &thattr, &transmitter, NULL);
    if (ret) {
        close_rt(sock);
        mq_close(mq);
        perror("pthread_create(transmitter) failed");
        return 1;
    }


//debug
#if DEBUG
printf("Creazione del receiver pthread\n");
#endif

    ret = pthread_create(&recv_thread, &thattr, &receiver, NULL);
    if (ret) {
        close_rt(sock);
        mq_close(mq);
        perror("pthread_create(receiver) failed");
        return 1;
    }

//debug
#if DEBUG
printf("Terminata creazione dei pthreads\n");
#endif

    mlockall(MCL_CURRENT|MCL_FUTURE);

//se la chiamata a rt_make_hard_real_time
//viene fatta prima della ioctl non va bene!!
rt_make_hard_real_time();
//debug
#if DEBUG
printf("Invocata rt_make_hard_real_time();\n");
#endif

 
    while (1) {
        struct packet_stats pack;
        struct station_stats *pstat;
        int nr;

        ret = mq_receive(mq, (char *)&pack, sizeof(pack), NULL);
        if (ret < (int)sizeof(pack))
            break;

        pstat = lookup_stats(pack.addr);
        if (!pstat)
            continue;

        pstat->last = pack.rtt;
        if (pstat->last < pstat->min)
            pstat->min = pstat->last;
        if (pstat->last > pstat->max)
            pstat->max = pstat->last;
        pstat->count++;

        nr = pstat - &station[0];
        if (nr > max_stations)
            max_stations = nr;

        printf("%s\t%.3f us, min=%.3f us, max=%.3f us, count=%ld\r"
               "\033[%dA\n", inet_ntoa(pack.addr), (float)pstat->last/1000,
               (float)pstat->min/1000, (float)pstat->max/1000,
               pstat->count, nr);
    }

    /* This call also performs the required switch to secondary mode for
       socket cleanup. */
    printf("\033[%dB\n", max_stations);

    /* Important: First close the socket! */
    while ((close_rt(sock) < 0) && (errno == EAGAIN)) {
        printf("socket busy - waiting...\n");
        sleep(1);
    }

rt_make_soft_real_time();
rt_task_delete(task);

//le join vanno fatte alla fine, dopo rt_make_soft_real_time
    pthread_join(xmit_thread, NULL);
    pthread_kill(recv_thread, SIGHUP);
    pthread_join(recv_thread, NULL);

    return 0;
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
RTnet-users mailing list
RTnet-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rtnet-users

Reply via email to