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