注册 登录
自由的生活_软路由 返回首页

心想事成的个人空间 https://bbs.routerclub.com/?681 [收藏] [复制] [分享] [RSS]

日志

在内核中使用线程与skb队列发送数据

已有 445 次阅读2011-4-7 23:40 |个人分类:内核

在内核中我们发送数据一般使用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;
}

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/force_eagle/archive/2009/12/11/4983490.aspx


路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

QQ|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )

GMT+8, 2024-5-19 17:50 , Processed in 0.042975 second(s), 6 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2023 Discuz! Team.

返回顶部