![]() |
|
||||||||||||||
| | 首页 | 新闻 | 文库 | 方案 | 技术 | 独家 | 座谈 | 下载 | 电路图 | 开发套件 | 仿真器 | 邮购 | 帮助 | VIP会员 | 芯片代购 | | ||
|
||
|
|||||
| uclinux-2008R1-RC8(bf561)到VDSP5的移植(29):spinlock | |||||
作者:快乐虾 文章来源:http://blog.csdn.net/lights_joy 点击数: 更新时间:2008-5-12 ![]() |
|||||
|
spinlock是用于线程间同步的自旋锁,由于我们希望使用BF561的两个核,因此它就显得极为重要。
1 定义
在内核中声明一个spinlock可以使用DEFINE_SPINLOCK这个宏定义,它的定义在include/linux/spinlock_types.h中:
#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
其中spinlock_t是在include/linux/spinlock_types.h中定义的一个结构体:
typedef struct {
raw_spinlock_t raw_lock;
#if defined(CONFIG_PREEMPT) && defined(CONFIG_SMP)
unsigned int break_lock;
#endif
#ifdef CONFIG_DEBUG_SPINLOCK
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} spinlock_t;
因为我们只定义了CONFIG_SMP,因此这个结构体实际就是:
typedef struct {
raw_spinlock_t raw_lock;
} spinlock_t;
raw_spinlock_t的定义在include/asm/spinlock_types.h中:
typedef struct {
volatile unsigned int lock;
} raw_spinlock_t;
在此之前,我们只是简单地将其设置为volatile unsigned int的类型,而现在,我们则希望借助于VDSP的库进行核间同步,因此将其定义改为:
typedef struct {
testset_t lock;
} raw_spinlock_t;
因为testset_t自动就是volatile类型的,在此就不用声明了。
2 VDSP对核间同步的支持
以下内容来自VDSP的帮助:
Synchronization Functions
VisualDSP++ 5.0 provides functionality for synchronization. There are two compiler intrinsics (built-in functions) and three locking routines.
The compiler intrinsics are:
#include <ccblkfn.h>
int testset(char *);
void untestset(char *);
The testset() intrinsic generates a native TESTSET instruction, which can perform atomic updates on a memory location. The intrinsic returns the result of the CC flag produced by the TESTSET instruction. Refer to the instruction set reference for details.
The untestset() intrinsic clears the memory location set by the
testset() intrinsic. This intrinsic is recommended in place of a normal memory write because the untestset() intrinsic acts as a stronger barrier to code movement during optimization. The three locking routines are:
#include <ccblkfn.h>
void adi_acquire_lock(testset_t *);
int adi_try_lock(testset_t *);
void adi_release_lock(testset_t *);
The adi_acquire_lock() routine repeatedly attempts to claim the lock by issuing testset() until successful, whereupon it returns to the caller. In contrast, the adi_try_lock() routine makes a single attempt—if it successfully claims the lock, it returns nonzero, otherwise it returns zero.
The adi_release_lock() routine releases the lock obtained by either adi_acquire_lock() or adi_try_lock(). It assumes that the lock was already claimed and makes no attempt to verify that its caller is in fact the current owner of the lock. None of these intrinsics or functions disable interrupts—that is left to the caller’s discretion.
3 spin_lock
spin_lock的定义在include/linux/spinlock.h中:
#define spin_lock(lock) _spin_lock(lock)
_spin_lock的定义在include/linux/spinlock_api_smp.h中:
void __lockfunc _spin_lock(spinlock_t *lock) __acquires(lock);
而其实现则在kernel/spinlock.c中:
void __lockfunc _spin_lock(spinlock_t *lock)
{
preempt_disable();
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
_raw_spin_lock(lock);
}
_raw_spin_lock的实现则是不同的体系结构有不同的方法,但是其实现一般都放在asm/spinlock.h中,我们也这样做:
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
adi_acquire_lock(&lock->lock);
}
4 .spinlock.text
uclinux为spinlock相关的函数定义了一个段:
#define __lockfunc fastcall __attribute__((section(".spinlock.text")))
因此我们需要在LDF文件中加上它:
.text
{
INPUT_SECTION_ALIGN(4)
. = (. + 3) / 4 * 4;
__text = .;
_text = .;
__stext = .;
INPUT_SECTIONS($OBJECTS_CORE_A(sdram_bank0) $LIBRARIES_CORE_A(sdram_bank0))
INPUT_SECTIONS($OBJECTS_CORE_A(VDK_ISR_code) $LIBRARIES_CORE_A(VDK_ISR_code))
INPUT_SECTIONS($OBJECTS_CORE_A(program) $LIBRARIES_CORE_A(program))
INPUT_SECTIONS($OBJECTS_CORE_A(noncache_code) $LIBRARIES_CORE_A(noncache_code))
INPUT_SECTIONS($LIBRARIES_CORE_A(.text.*))
INPUT_SECTIONS($LIBRARIES_CORE_A(.fixup))
INPUT_SECTIONS($LIBRARIES_CORE_A(.spinlock.text))
INPUT_SECTION_ALIGN(16)
. = (. + 15) / 16 * 16;
___start___ex_table = .;
INPUT_SECTIONS($LIBRARIES_CORE_A(__ex_table))
___stop___ex_table = .;
INPUT_SECTION_ALIGN(4)
. = (. + 3) / 4 * 4;
__etext = .;
} > MEM_SDRAM
|
|||||
| 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| ucos-ii在嵌入式智能视觉监控 14bit 40 MSamples/s ADC应用 打造windows下的嵌入式开发工 DSP和FPGA在汽车电子中的广泛 [连载]ADSP-TSl01S系列之一 ADI ADIS1625x低功耗陀螺仪方 基于DSP的实时图像跟踪系统的 wxWidgets和MFC动态类型信息 用dll方式编译wxWidgets-2.8 Blackfin时钟控制 |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 本站介绍 | 合作联络 | 欢迎投稿 | 广告业务 | 网站地图 | 设为首页 | 加入收藏 | 友情链接 | 网站公告 | 联系我们 | | |||
|