Зачем нужно несколько блокировок в одной структуре данных? - PullRequest
0 голосов
/ 26 июня 2019

Я изучал какой-то существующий код 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);
}

1 Ответ

0 голосов
/ 10 июля 2019

Здесь происходит пара вещей.

Во-первых, не думайте, что спин-блокировка и мьютекс обязательно должны быть "для" структуры данных, просто потому, что они "в" структуре данных.В этом случае спин-блокировка кажется тем, что вы описываете, блокировка доступа к структуре данных.Мьютекс, по-видимому, является замком для действия команды wiimote.

Далее, спин-блокировки и мьютексы совершенно разные, ключ в том, что мьютексы блокируют и опрашивают спин-блокировки до тех пор, пока ресурс не станет доступен.

Наконец, хотя это не то, что я вижу здесь, модуль может содержать как спин-блокировки, так и мьютексы, выполняющие аналогичную функцию, если они были реализованы в разное время разными разработчиками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...