problem with rtl-lwip

Xin WANG <[email protected]>
Newsgroups gmane.linux.real-time.rtlinux.general
Message-ID <[email protected]>
If i use one socket to transmit data, the transmit speed is very high.
But if i use two sockets to transmit data, the trasmit speed becomes
unbebievable low.
I don't know why. Is there anyone has some ideas?Thank you!


below is my code:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <rtl.h>
//#include <pthread.h>
#include "lwip/ip_addr.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"

#define NUM_OF_THREAD 	1
#define NUM_OF_SOCKET	1
#define SERVER_PORT	9999

void test_thread1(void *arg);
void network_thread(void *arg);
void cleanup_threads(int num);
void init_thread_sched(int i);
int start_threads(void);
int server_listen(void);
int server_accept(void);
int writen(int sock, void *buffer, size_t len);
int readn(int sock, void *buffer, size_t len);
void cleanup_accepted_socket(int num);
void cleanup_listen_socket(void);
void memset_int(void *buffer, size_t len, unsigned int start_index);
int check_data(void *buffer, size_t len, unsigned int start_index);

//task thread struct
struct task_thread
{
	void		*id;
	unsigned char	created;		//1:created 0:not created
//	int		sched_policy;
	int		sched_priority;
	unsigned long	sched_period;
	void 		(*routine)(void *arg);	//thread routine
};

struct task_thread test_thread[NUM_OF_THREAD] =
{
//	{ 0, 0, 1, 500000000, test_thread1 },
//	{ 0, 0, 1, 500000000, test_thread1 },
//	{ 0, 0, 1, 500000000, test_thread1 },
//	{ 0, 0, 1, 500000000, test_thread1 },
	{ 0, 0, 1,   3000000, network_thread }
};

//listen socket
//struct socket *lsock = NULL;
int lsock = -1;
//accepted sockets
//struct socket *asock[NUM_OF_SOCKET];
int asock[NUM_OF_SOCKET] =
	{
//		-1,
		-1
	};

//data to send
char data[4096];// = { 0x0F };

//////////////////////////////////////////
//delete created threads form i to 0
//////////////////////////////////////////
void
cleanup_threads(int num)
{
	for( ; num >=0; num-- ) {
		if( test_thread[num].created ) {
			sys_thread_delete( (void *)test_thread[num].id );
			test_thread[num].created = 0;
			rtl_printf( "thread deleted index=%d, id=%d\n",
					num, test_thread[num].id );
		}
	}
}

/////////////////////////////////////////
//set thread schedule parameter
/////////////////////////////////////////
void
init_thread_sched(int i)
{
}
	
//////////////////////////////////////////
//test thread 1
//////////////////////////////////////////
void 
test_thread1(void *arg)
{
#if 0
	int	i = 0;
	int	index = (int)arg;
	hrtime_t	start, end;

	init_thread_sched( index );

	while(1) {
		pthread_wait_np();
		start = gethrtime();
		for( i = 0; i < 10000; i++ )
			NULL;
		end = gethrtime();
		rtl_printf( "thread:%x, time:%d\n",
				index, end - start );
	}
#endif
	return;
}

//////////////////////////////////////////////////
//network thread
//////////////////////////////////////////////////
void
network_thread(void *arg)
{
	int		j = 0;
//	int		i = (int)arg;
	int		ret = 0;
	unsigned int	count = 0;

	ret = server_listen();
	if( -1 == ret ) {
		cleanup_listen_socket();
		sys_thread_exit();
	}
	ret = server_accept();
	if( -1 == ret ) {
		cleanup_listen_socket();
		sys_thread_exit();
	}

	cleanup_listen_socket();
	while( count++ < 1000 ) {
		pthread_wait_np();
		memset_int( data, sizeof( data ), count );
		for( j = 0; j < NUM_OF_SOCKET; j++ ) {
			ret = writen( asock[j], data, sizeof( data ) );
			if( ret != sizeof( data ) ) {
				rtl_printf( "send error: %d %d\n", j, ret );
				break;
			}
		}
		if( count%5000 == 0 )
		rtl_printf( "count:%d\n", count );
	}
	cleanup_accepted_socket( NUM_OF_SOCKET - 1 );

	sys_thread_exit();
}

//////////////////////////////////////////////////
//create all test threads
//0:all threads created sucessfully
//-1:failed
//////////////////////////////////////////////////
int 
start_threads(void)
{
	int	i = 0;
//	int	ret = 0;

	for( i =0; i < NUM_OF_THREAD; i++ )
	{
		test_thread[i].id = sys_thread_new( test_thread[i].routine,
				(void *)i, test_thread[i].sched_period );
		if( !(void *)test_thread[i].id ) {
			rtl_printf( "sys_thread_new failed:%d\n", i );
			cleanup_threads( --i );
			return -1;
		} else {
			rtl_printf( "sys_thread_new success:%p\n",
					test_thread[i].id );
			test_thread[i].created = 1;
		}
	}

	return 0;
}

////////////////////////////////////
//server listen
//0:success
//-1:failed
////////////////////////////////////
int
server_listen(void)
{
	int	ret = 0;
	struct sockaddr_in server;
		
	rtl_printf( "server start to listen\n" );

	lsock = socket( AF_INET, SOCK_STREAM, 0 );
	if( lsock < 0 ) {
		rtl_printf( "socket failed: listen socket:%d\n", lsock );
		return -1;
	}
	
	rtl_printf( "socket: listen socket:%x\n", lsock );

	server.sin_family	= AF_INET;
	server.sin_addr.s_addr	= htonl( INADDR_ANY );
	server.sin_port		= htons((unsigned short) SERVER_PORT );

	ret = bind( lsock, (struct sockaddr *) &server, sizeof( server ) );
	if( ret < 0 ) {
		rtl_printf( "bind failed: listen socket\n" );
		return -1;
	}

	ret = listen( lsock, 8 );
	if( ret != 0 ) {
		rtl_printf( "listen failed: listen socket\n" );
		return -1;
	}

	rtl_printf( "server finished listening\n" );

	return 0;
}

/////////////////////////////////////////////
//accpet new connection
//0:success
//-1:failed
///////////////////////////////////////////
int
server_accept(void)
{
	int	i = 0;
//	int 	ret = 0;
	size_t	len = 0;
	struct sockaddr_in local;

	rtl_printf( "server start to accept\n" );
	for( i = 0; i < NUM_OF_SOCKET; i++ ) {
		len = sizeof( local );
		asock[i] = accept( lsock, (struct sockaddr *)&local, &len );
		if( asock[i] < 0 ) {
			rtl_printf( "accept failed: accpet socket:%d\n", asock[i] );
			return -1;
		}
		rtl_printf( "%d connection accepted\n", i );
	}
	rtl_printf( "server finished accepting\n" );
	
	return 0;
}

int
writen(int sock, void *buffer, size_t len)
{
	size_t	nleft = len;
	size_t	nsent = 0;
	char	*ptr = buffer;

	while( nleft > 0 ) {
		if( (nsent = write( sock, ptr, nleft ) ) <= 0 ) {
			if( -EINTR == errno )
				nsent = 0;
			else
				return -1;
		}
		nleft -= nsent;
		ptr += nsent;
	}
	
	return len;
}

int
readn(int sock, void *buffer, size_t len)
{
	size_t	nleft = len;
	size_t	nrecved = 0;
	char	*ptr = buffer;

	while( nleft > 0 ) {
		if( (nrecved = read( sock, ptr, nleft ) ) < 0 ) {
			if( EINTR == errno )
				nrecved = 0;
			else
				return -1;
		} else if( 0 == nrecved )	//EOF
			break;
		nleft -= nrecved;
		ptr += nrecved;
	}
	
	return len;
}

void
cleanup_accepted_socket(int num)
{
	for( ; num >=0; num-- ) {
		if( asock[num] >= 0 ) {
			close( asock[num] );
			asock[num] = -1;
			rtl_printf( "accepted socket released index=%d\n", num );
		}
	}
}

void
cleanup_listen_socket(void)
{
	if( lsock >= 0 )
	{
		close( lsock );
		lsock = -1;
		rtl_printf( "listen socket released\n" );
	}
}

void
memset_int(void *buffer, size_t len, unsigned int start_index)
{
	int		i = 0;
	unsigned int	*ptr = buffer;
	unsigned int	content = start_index;

	for( i = 0; i < len / sizeof( start_index ); i++, content++ ) {
		ptr[i] = content;
	}
}

int
check_data(void *buffer, size_t len, unsigned int start_index)
{
	int		i = 0;
	unsigned int	*ptr = buffer;
	unsigned int	content = start_index;

	for( i = 0; i < len / sizeof( start_index ); i++, content++ ) {
		if( ptr[i] != content )
			return i;
	}

	return 0;
}

int 
init_module(void) 
{
	int	ret = 0;
	ret = start_threads();
	if( -1 == ret )
		return ret;
#if 0
#endif
	return 0;
}

void 
cleanup_module(void) 
{
#if 0
#endif
	cleanup_threads( NUM_OF_THREAD - 1 );
	cleanup_accepted_socket( NUM_OF_SOCKET - 1 );
}
_______________________________________________
Rtl mailing list
[email protected]
http://www2.fsmlabs.com/mailman/listinfo/rtl
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.