Chinaunix首页 | 论坛 | 博客
  • 博客访问: 699207
  • 博文数量: 183
  • 博客积分: 2650
  • 博客等级: 少校
  • 技术积分: 1428
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-22 17:02
文章分类
文章存档

2017年(1)

2015年(46)

2014年(4)

2013年(8)

2012年(2)

2011年(27)

2010年(35)

2009年(60)

分类: LINUX

2010-11-22 14:03:38

在内核中我们发送数据一般使用dev_queue_xmit. 但是每次都需要通读等待返回, 通过线程的方式, 可以实现异步模式, 无需等待发送完成.可以大大加快发送速度.以下是示例代码:

static int xmit_thread_worker(void *arg);

///////////////////////////////////////////////////////////////////////////////
static struct task_struct *xmit_thread = NULL;
// 等待线程启动与完成
static struct completion start_done;
static struct completion end_done;
// 线程状态
static u32   thread_state = 0x0;
// 终止线程标记
static volatile u32 xmit_stop = 0x0;
// skb发送队列
struct sk_buff_head pkt_xmit;
///////////////////////////////////////////////////////////////////////////////

int xmit_thread_init(void)
{
int rc = 0x0;
// 初始化队列与completion
skb_queue_head_init( &pkt_xmit );
init_completion( &start_done );
init_completion( &end_done );
// 创建线程
xmit_thread = kthread_create( xmit_thread_worker, NULL, " ");
if ( IS_ERR( xmit_thread ) ) {
xmit_thread = NULL;
pr_err( "kthread_create occur error.\n" );
rc = -1;
}
else {
pr_emerg( "kthread_create success.\n" );
                // 唤醒线程
wake_up_process( xmit_thread );
                // 等待线程启动完成
wait_for_completion( &start_done );
pr_emerg( "xmit thread worker run success.\n" );
}
return rc;
}
// skb入队列发送
void xmit_enqueue( struct sk_buff *skb )
{
        // skb 入队列
skb_queue_tail( &pkt_xmit, skb );
if ( NULL != xmit_thread ){
                // 唤醒线程
wake_up_process( xmit_thread );
}
}
// 销毁线程
void xmit_thread_fini(void)
{
struct sk_buff *skb = NULL;
pr_emerg( "wait for xmit thread done\n" );
if ( NULL == xmit_thread ){
return ;
}
// 设置线程终止标记
xmit_stop = 0x1;
        // 等待完成
wait_for_completion( &end_done );
// 释放队列中未发送skb
do {
skb = __skb_dequeue( &pkt_xmit );
if ( NULL != skb ) {
kfree_skb( skb );
}
}while( NULL != skb );
}

static int xmit_thread_worker(void *arg)
{
struct sk_buff *skb = NULL;
        // 通知启动完成
complete( &start_done );
while( 1 ) {
thread_state = 0x0;
                // 调度
schedule_timeout_interruptible(2);

//__set_current_state(TASK_RUNNING);
thread_state = 0x1;
// 是否终止?
if ( xmit_stop ) {
pr_emerg( "%s end.\n", __func__ );
break;
}
do {
                        // 取skb发送队列并发送
skb = skb_dequeue( &pkt_xmit );
if ( NULL != skb ) {
dev_queue_xmit( skb );
}
// 是否终止?
if ( xmit_stop ) {
pr_emerg( "%s end.\n", __func__ );
goto _out;
}
}while( NULL != skb );
};
_out:
        // 通知线程终止
complete( &end_done );
return 0;
}
阅读(2542) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-11-24 13:28:28

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com