我一直在研究要编写的设备驱动程序的一些现有C代码。这是我第一次处理并发和锁定,也是我第一次处理与设备驱动程序这样的硬件相关的内容。我找到了一个代码,似乎使用多个锁来实现相同的数据结构。我想知道为什么有人会在相同数据结构中包括两个不同的锁定结构(既有旋转锁和互惠(,而不仅仅是一个锁定整个数据结构的单个锁?
struct wiimote_state {
spinlock_t lock;
__u32 flags;
__u8 accel_split[2];
__u8 drm;
__u8 devtype;
__u8 exttype;
__u8 mp;
/* synchronous cmd requests */
struct mutex sync;
struct completion ready;
int cmd;
__u32 opt;
/* results of synchronous requests */
__u8 cmd_battery;
__u8 cmd_err;
__u8 *cmd_read_buf;
__u8 cmd_read_size;
/* calibration/cache data */
__u16 calib_bboard[4][3];
__s16 calib_pro_sticks[4];
__u8 pressure_drums[7];
__u8 cache_rumble;
};
使用这些多个锁的代码段的示例:
static void wiimote_init_detect(struct wiimote_data *wdata)
{
__u8 exttype = WIIMOTE_EXT_NONE, extdata[6];
bool ext;
int ret;
wiimote_cmd_acquire_noint(wdata);
spin_lock_irq(&wdata->state.lock);
wdata->state.devtype = WIIMOTE_DEV_UNKNOWN;
wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
wiiproto_req_status(wdata);
spin_unlock_irq(&wdata->state.lock);
ret = wiimote_cmd_wait_noint(wdata);
if (ret)
goto out_release;
spin_lock_irq(&wdata->state.lock);
ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED;
spin_unlock_irq(&wdata->state.lock);
if (!ext)
goto out_release;
wiimote_cmd_init_ext(wdata);
exttype = wiimote_cmd_read_ext(wdata, extdata);
out_release:
wiimote_cmd_release(wdata);
wiimote_init_set_type(wdata, exttype);
/* schedule MP timer */
spin_lock_irq(&wdata->state.lock);
if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) &&
!(wdata->state.flags & WIIPROTO_FLAG_NO_MP))
mod_timer(&wdata->timer, jiffies + HZ * 4);
spin_unlock_irq(&wdata->state.lock);
}
static inline void wiimote_cmd_acquire_noint(struct wiimote_data *wdata)
{
mutex_lock(&wdata->state.sync);
}
static inline void wiimote_cmd_release(struct wiimote_data *wdata)
{
mutex_unlock(&wdata->state.sync);
}
这里发生了几件事。
首先,不要将Spinlock和Mutex视为"数据结构",仅仅是因为它们在"数据结构中"。在这种情况下,Spinlock似乎是您描述的,这是访问数据结构的锁。静音似乎是指挥Wiimote的动作的锁。
接下来,Spinlocks和sutexes完全不同,关键是静音正在阻止和自旋锁进行调查,直到资源可用为止。
最后,尽管这不是我在这里看到的,但是如果不同的时间在不同的时间实现了一个模块,则可以同时包含Spinlocks和Mutexes执行相似的功能。