Chinaunix首页 | 论坛 | 博客
  • 博客访问: 593574
  • 博文数量: 353
  • 博客积分: 1104
  • 博客等级: 少尉
  • 技术积分: 1457
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-23 23:02
个人简介

1、刚工作时做Linux 流控;后来做安全操作系统;再后来做操作系统加固;现在做TCP 加速。唉!没离开过类Unix!!!但是水平有限。。

文章存档

2015年(80)

2013年(4)

2012年(90)

2011年(177)

2010年(1)

2009年(1)

分类:

2011-12-08 13:09:39

原文地址:用户空间原子操作的实现 作者:CUDev

使用lock指令前缀:
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
/* Technically wrong, but this avoids compilation errors on some gcc
   versions. */
#define ADDR "=m" (*(volatile long *) addr)
#else
#define ADDR "+m" (*(volatile long *) addr)
#endif

#ifdef CONFIG_SMP
#define LOCK_PREFIX "lock; "
#else /* ! CONFIG_SMP */
#define LOCK_PREFIX ""
#endif

typedef struct {
    int counter;
} atomic_t;

#define atomic_read(v)        ((v)->counter)
#define atomic_set(v, i)        (((v)->counter) = (i))

static inline void atomic_inc(atomic_t *v)
{
    asm volatile(LOCK_PREFIX "incl %0"
             : "=m" (v->counter)
             : "m" (v->counter));
}

static inline void atomic_dec(atomic_t *v)
{
    asm volatile(LOCK_PREFIX "decl %0"
             : "=m" (v->counter)
             : "m" (v->counter));
}

static inline void set_bit(int nr, volatile void *addr)
{
    asm volatile(LOCK_PREFIX "bts %1,%0" : ADDR : "Ir" (nr) : "memory");
}

static inline int test_and_set_bit(int nr, volatile void *addr)
{
    int oldbit;

    asm volatile(LOCK_PREFIX "bts %2,%1\n\t"
             "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");

    return oldbit;
}

static inline void clear_bit(int nr, volatile void *addr)
{
    asm volatile(LOCK_PREFIX "btr %1,%0" : ADDR : "Ir" (nr));
}

static inline int test_and_clear_bit(int nr, volatile void *addr)
{
    int oldbit;

    asm volatile(LOCK_PREFIX "btr %2,%1\n\t"
             "sbb %0,%0"
             : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");

    return oldbit;
}

使用gcc的内建函数来进行原子访问:
#ifndef _ATOMIC_H
#define _ATOMIC_H
 
/**
* Atomic type.
*/

 
typedef struct {
volatile int counter;
} atomic_t;
 
#define ATOMIC_INIT(i) { (i) }
 
/**
* Read atomic variable
* @param v pointer of type atomic_t
*
* Atomically reads the value of @v.
*/

#define atomic_read(v) ((v)->counter)
 
/**
* Set atomic variable
* @param v pointer of type atomic_t
* @param i required value
*/

#define atomic_set(v,i) (((v)->counter) = (i))
 
/**
* Add to the atomic variable
* @param i integer value to add
* @param v pointer of type atomic_t
*/

static inline void atomic_add( int i, atomic_t *v )
{
(void)__sync_add_and_fetch(&v->counter, i);
}
 
/**
* Subtract the atomic variable
* @param i integer value to subtract
* @param v pointer of type atomic_t
*
* Atomically subtracts @i from @v.
*/

static inline void atomic_sub( int i, atomic_t *v )
{
(void)__sync_sub_and_fetch(&v->counter, i);
}
 
/**
* Subtract value from variable and test result
* @param i integer value to subtract
* @param v pointer of type atomic_t
*
* Atomically subtracts @i from @v and returns
* true if the result is zero, or false for all
* other cases.
*/

static inline int atomic_sub_and_test( int i, atomic_t *v )
{
return !(__sync_sub_and_fetch(&v->counter, i));
}
 
/**
* Increment atomic variable
* @param v pointer of type atomic_t
*
* Atomically increments @v by 1.
*/

static inline void atomic_inc( atomic_t *v )
{
(void)__sync_fetch_and_add(&v->counter, 1);
}
 
/**
* @brief decrement atomic variable
* @param v: pointer of type atomic_t
*
* Atomically decrements @v by 1. Note that the guaranteed
* useful range of an atomic_t is only 24 bits.
*/

static inline void atomic_dec( atomic_t *v )
{
(void)__sync_fetch_and_sub(&v->counter, 1);
}
 
/**
* @brief Decrement and test
* @param v pointer of type atomic_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/

static inline int atomic_dec_and_test( atomic_t *v )
{
return !(__sync_sub_and_fetch(&v->counter, 1));
}
 
/**
* @brief Increment and test
* @param v pointer of type atomic_t
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
* other cases.
*/

static inline int atomic_inc_and_test( atomic_t *v )
{
return !(__sync_add_and_fetch(&v->counter, 1));
}
 
/**
* @brief add and test if negative
* @param v pointer of type atomic_t
* @param i integer value to add
*
* Atomically adds @i to @v and returns true
* if the result is negative, or false when
* result is greater than or equal to zero.
*/

static inline int atomic_add_negative( int i, atomic_t *v )
{
return (__sync_add_and_fetch(&v->counter, i) < 0);
}
 
#endif



参考:
http://golubenco.org/blog/atomic-operations/

http://hi.baidu.com/wrap/blog/item/d8e40f2e7fb022554fc226a0.html

阅读(477) | 评论(0) | 转发(0) |
0

上一篇:linux下的异常处理

下一篇:lock指令

给主人留下些什么吧!~~