您的位置:首页 > 娱乐 > 明星 > 北京做网站最牛的公司_互联云主机_今天的最新新闻内容_seo关键词怎么填

北京做网站最牛的公司_互联云主机_今天的最新新闻内容_seo关键词怎么填

2024/10/5 22:28:04 来源:https://blog.csdn.net/qq_30896803/article/details/142454120  浏览:    关键词:北京做网站最牛的公司_互联云主机_今天的最新新闻内容_seo关键词怎么填
北京做网站最牛的公司_互联云主机_今天的最新新闻内容_seo关键词怎么填

原子操作是指指令以原子的方式操作,执行过程不会被打断。linux内核提供了atomic_t类型的原子变量,它的实现依赖于不同的体系结构。

include/linux/types.h

typedef struct {

int counter;

} atomic_t;

#ifdef CONFIG_64BIT

typedef struct {

long counter;

} atomic64_t;

#endif

ARM使用ldrex和strex指令来保证操作的原子性

ldrex Rt,[Rn] 把Rn寄存器指向内存地址的内容加载到Rt寄存器中

strex Rd,Rt,[Rn] 把Rt寄存器的值保存到Rn寄存器指向的内存地址中,Rd保存更新的结果,0表示更新成功,1:表示失败。

下面分析ARM中原子操作实现,其中涉及到arm内嵌汇编的一些内容,大家可以先简单查阅下内嵌汇编的内容,本文这里默认大家熟悉这些内容。

#define ATOMIC_OP(op, c_op, asm_op)					\
static inline void atomic_##op(int i, atomic_t *v)			\
{									\unsigned long tmp;						\int result;							\\prefetchw(&v->counter);						\__asm__ __volatile__("@ atomic_" #op "\n"			\
"1:	ldrex	%0, [%3]\n"						\
"	" #asm_op "	%0, %0, %4\n"					\
"	strex	%1, %0, [%3]\n"						\
"	teq	%1, #0\n"						\
"	bne	1b"							\: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)		\: "r" (&v->counter), "Ir" (i)					\: "cc");							\
}	
#define ATOMIC_OP_RETURN(op, c_op, asm_op)				\
static inline int atomic_##op##_return(int i, atomic_t *v)		\
{									\unsigned long tmp;						\int result;							\\smp_mb();							\prefetchw(&v->counter);						\\__asm__ __volatile__("@ atomic_" #op "_return\n"		\
"1:	ldrex	%0, [%3]\n"						\
"	" #asm_op "	%0, %0, %4\n"					\
"	strex	%1, %0, [%3]\n"						\
"	teq	%1, #0\n"						\
"	bne	1b"							\: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)		\: "r" (&v->counter), "Ir" (i)					\: "cc");							\\smp_mb();							\\return result;							\/*返回原子变量v的旧值*/
}
static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{int oldval;unsigned long res;smp_mb();prefetchw(&ptr->counter);do {__asm__ __volatile__("@ atomic_cmpxchg\n""ldrex	%1, [%3]\n"   /*存放ptr->counter值到oldval*/"mov	%0, #0\n"	  /*res=0*/"teq	%1, %4\n"     /*测试oldval(ptr->counter值)和old值是否相等*/"strexeq %0, %5, [%3]\n" /*如果相等则将new赋值给ptr->counter,最终将strex结果存放到res中*/: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter): "r" (&ptr->counter), "Ir" (old), "r" (new): "cc");} while (res); /*res!=0表示独占访问失败,继续尝试*/smp_mb();return oldval;
}
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{int oldval, newval;unsigned long tmp;smp_mb();prefetchw(&v->counter);__asm__ __volatile__ ("@ atomic_add_unless\n"
"1:	ldrex	%0, [%4]\n" /*将v->counter赋值给oldval*/
"	teq	%0, %5\n"	    /*测试oldval值和u是否相等*/
"	beq	2f\n"			/*相等则不做任何操作,跳转到2初*/
"	add	%1, %0, %6\n"   /*newval=oldval+a*/
"	strex	%2, %1, [%4]\n" /*v->counter=newval*/
"	teq	%2, #0\n"	/*测试独占访问是否成功,失败跳转到1处*/
"	bne	1b\n"
"2:": "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter): "r" (&v->counter), "r" (u), "r" (a): "cc");if (oldval != u)smp_mb();return oldval; /*返回旧值*/
}

#define ATOMIC_OPS(op, c_op, asm_op) \

ATOMIC_OP(op, c_op, asm_op) \

ATOMIC_OP_RETURN(op, c_op, asm_op)

/*atomic_add,atomic_add_return*/

ATOMIC_OPS(add, +=, add)

/*atomic_sub,atomic_sub_return*/

ATOMIC_OPS(sub, -=, sub)

#undef ATOMIC_OPS

#undef ATOMIC_OP_RETURN

#undef ATOMIC_OP

#define atomic_xchg(v, new) (xchg(&((v)->counter), new))

/*下面的宏定义都是依赖atomic_add,atomic_add_return,atomic_sub,atomic_sub_return的实现*/

#define atomic_inc(v) atomic_add(1, v)

#define atomic_dec(v) atomic_sub(1, v)

#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)

#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)

#define atomic_inc_return(v) (atomic_add_return(1, v))

#define atomic_dec_return(v) (atomic_sub_return(1, v))

#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)

#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com