歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> uclinux-2008R1-RC8(bf561)到VDSP5的移植(30):atomic_t

uclinux-2008R1-RC8(bf561)到VDSP5的移植(30):atomic_t

日期:2017/3/3 16:43:37   编辑:關於Linux

atomic的相關操作定義都在include/asm/atomic.h中,各個平台有不同的實現方法,比如在x86平台上,CPU提供了在指令執行期間對總線加鎖的手段。CPU芯片上有一條引線#HLOCK pin,如果匯編語言的程序中在一條指令前面加上前綴"LOCK",經過匯編以後的機器代碼就使CPU在執行這條指令的時候把#HLOCK pin的電位拉低,持續到這條指令結束時放開,從而把總線鎖住,這樣同一總線上別的CPU就暫時不能通過總線訪問內存了,保證了這條指令在多處理器環境中的原子性。

在uclinux目前對atomic的實現中,有這樣一個注釋:

/*
 * Atomic operations that C can't guarantee us. Useful for
 * resource counting etc..
 *
 * Generally we do not concern about SMP BFIN systems, so we don't have
 * to deal with that.
 *
 * Tony Kou ([email protected])   Lineo Inc.   2001
 */

也就是它並不考慮SMP的情況,我希望對此進行適當的修改。但是在bf561中,它並沒有提供類似x86這樣鎖定總線的功能,它有的僅僅是一個TESTSET的指令,而無法在硬件上提供其它的鎖定機制,因此我們需要為其添加一個類似於spinlock這樣的鎖。

查了下linux-2.6.19的內核代碼,在asm-sparc/atomic.h中有一個類似的作法:

/* We do the bulk of the actual work out of line in two common
 * routines in assembler, see arch/sparc/lib/atomic.S for the
 * "fun" details.
 *
 * For SMP the trick is you embed the spin lock byte within
 * the word, use the low byte so signedness is easily retained
 * via a quick arithmetic shift. It looks like this:
 *
 *   ----------------------------------------
 *   | signed 24-bit counter value | lock | atomic_t
 *   ----------------------------------------
 *   31                          8 7      0
 */

為省事,干脆單獨在atomic_t的結構體中加上一個spinlock:

typedef struct {
     int counter;
     testset_t lock;
} atomic_t;

相應的操作函數也作一下修改,如:

#define atomic_add_negative(a, v)  (atomic_add_return((a), (v)) < 0)
static inline int atomic_sub_return(int i, atomic_t * v)
{
 int __temp = 0;
 long flags;

 adi_acquire_lock(&v->lock);

 local_irq_save(flags);
 v->counter -= i;
  __temp = v->counter;
 local_irq_restore(flags);

 adi_release_lock(&v->lock);

 return __temp;
}

以後再考慮一下性能問題。

Copyright © Linux教程網 All Rights Reserved