Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> mutex/condition_variable как работают изнутри? 
V
    Опции темы
boostcoder
Дата 31.8.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 16
Всего: 110



всем доброго дня.
подскажите, как мьютекс к примеру, работает изнутри? при локе он устанавливает в шедулере какой-то флаг, при повторном локе которого, шедулер перестает обрабатывать все остальные потоки?
мьютексы/переменные_состояния - объекты ядра?

спасибо.

Добавлено @ 14:37
зы
если бы кто-то сориентировал ссылками на исходники ядра с интересующими моментами, был бы невероятно признателен smile

Это сообщение отредактировал(а) boostcoder - 31.8.2011, 14:37
PM WWW   Вверх
newbee
Дата 31.8.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бревно
**


Профиль
Группа: Участник
Сообщений: 703
Регистрация: 24.8.2011

Репутация: нет
Всего: 19



/usr/src/linux/Documentation/mutex-design.txt

Читай в самом конце, там и отсылки к исходникам.


--------------------
You're face to face
With man who sold the world
PM   Вверх
azesmcar
Дата 31.8.2011, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 1
Всего: 211



Цитата(boostcoder @  31.8.2011,  14:36 Найти цитируемый пост)
как мьютекс к примеру, работает изнутри? 

Есть разные алгоритмы, не думаю, что ОС обязывается себя использовать какой-то конкретный.
Можешь посмотреть для примера Алгоритм ПетерсонаДеккера
Если задаешься такими вопросами, то пора читать это.

Это сообщение отредактировал(а) azesmcar - 31.8.2011, 15:31
PM   Вверх
boostcoder
Дата 31.8.2011, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 16
Всего: 110



Цитата(newbee @  31.8.2011,  14:54 Найти цитируемый пост)
/usr/src/linux/Documentation/mutex-design.txt

вот он: тыц.
mutex.h.
mutex.c.
нужно разбираться...

но из декларации "struct mutex;" некоторые моменты понятны.
Код

/*
 * Simple, straightforward mutexes with strict semantics:
 *
 * - only one task can hold the mutex at a time
 * - only the owner can unlock the mutex
 * - multiple unlocks are not permitted
 * - recursive locking is not permitted
 * - a mutex object must be initialized via the API
 * - a mutex object must not be initialized via memset or copying
 * - task may not exit with mutex held
 * - memory areas where held locks reside must not be freed
 * - held mutexes must not be reinitialized
 * - mutexes may not be used in hardware or software interrupt
 *   contexts such as tasklets and timers
 *
 * These semantics are fully enforced when DEBUG_MUTEXES is
 * enabled. Furthermore, besides enforcing the above rules, the mutex
 * debugging code also implements a number of additional features
 * that make lock debugging easier and faster:
 *
 * - uses symbolic names of mutexes, whenever they are printed in debug output
 * - point-of-acquire tracking, symbolic lookup of function names
 * - list of all locks held in the system, printout of them
 * - owner tracking
 * - detects self-recursing locks and prints out all relevant info
 * - detects multi-task circular deadlocks and prints out all affected
 *   locks and tasks (and only those tasks)
 */
struct mutex {
    /* 1: unlocked, 0: locked, negative: locked, possible waiters */
    atomic_t        count;
    spinlock_t        wait_lock;
    struct list_head    wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
    struct thread_info    *owner;
#endif
#ifdef CONFIG_DEBUG_MUTEXES
    const char        *name;
    void            *magic;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
    struct lockdep_map    dep_map;
#endif
};


Добавлено через 4 минуты и 17 секунд
Цитата(azesmcar @  31.8.2011,  15:31 Найти цитируемый пост)
Можешь посмотреть для примера Алгоритм Петерсона, Деккера

по описанию, довольно простые алгоритмы..

PM WWW   Вверх
azesmcar
Дата 31.8.2011, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 1
Всего: 211



Цитата(boostcoder @  31.8.2011,  16:30 Найти цитируемый пост)
по описанию, довольно простые алгоритмы..

Это для двух потоков.
PM   Вверх
null56
Дата 5.9.2011, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 721
Регистрация: 19.3.2008

Репутация: 4
Всего: 12



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

до самой структуры ты уже добрался (удалю отладочные поля)
Код

  48struct mutex {
  49        /* 1: unlocked, 0: locked, negative: locked, possible waiters */
  50        atomic_t                count;    // ключ занятости
  51        spinlock_t              wait_lock;    
  52        struct list_head        wait_list;    // ожидающие задачи освобождения
  63};

итого всего три поля:
типы atomic_t - платформозависимые, вот код для х86
http://lxr.linux.no/#linux+v3.0.4/arch/x86...de/asm/atomic.h

операции с типами spinlock, в случае однопроцессорной системы и без возможности вытеснения ядра, вообще по идее ничего не должны делать, в противном
случае имеют место платформозависимые ассемблерные вставки для работы с этими типами
вот основные интерфейсы
http://lxr.linux.no/#linux+v3.0.4/include/linux/spinlock.h
для х86 в многопроцессорной системе, попытка завладеть спинлоком, ВРОДЕ БЫ, сводилась к асмовской вставке, где в бесконечном цикле осуществлялась операция проверить-изменить переменную

далее основные методы
создание - ничего интересного, лишь инициализация
Код

  39void
  40__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
  41{
  42        atomic_set(&lock->count, 1);
  43        spin_lock_init(&lock->wait_lock);
  44        INIT_LIST_HEAD(&lock->wait_list);
  46
  48}


блокировка
Код

  83void __sched mutex_lock(struct mutex *lock)
  84{
  85        might_sleep();
  86        /*
  87         * The locking fastpath is the 1->0 transition from
  88         * 'unlocked' into 'locked' state.
  89         */
  90        __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
  91        mutex_set_owner(lock);
  92}

тут интерес вызывает __mutex_fast_lock, которая в случае занятости мьютекса (count) дергает другую функцию __mutex_lock_slowpath
http://lxr.linux.no/#linux+v3.0.4/arch/x86.../mutex_32.h#L24
вот код __mutex_lock_slowpath
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L401
которая вызывает другую функцию блокировки __mutex_lock_common
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L133
если убрать из нее различные примочки времени компиляции, то ключевыми тут будут
- запрет вытесняемости
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L140
- далее добавление в очередь ожидания, повторная попытка завладеть мьютексом, спать если мьютекс по прежнему занят (schedule)
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L204
- ну и выход из очереди
http://lxr.linux.no/linux+v3.0.4/kernel/mutex.c#L251
напоминаю: переменная current хранит адрес структуры текущего процесса/потока
Итог: если мьютекс заблокирован, то в в список ожидающих задач (поле wait_list) добавляется текущая и управление передается планировщику

освобождение мьютекса
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L110
опять ключевым является вызов функции fastpath_unlock
http://lxr.linux.no/#linux+v3.0.4/arch/x86.../mutex_32.h#L73
которая в случае обнаружения ожидающих задач (по значению count) дергает __mutex_unlock_common_slowpath
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L309
которая пробуждает первый ожидающий в очереди процесс/поток
http://lxr.linux.no/#linux+v3.0.4/kernel/mutex.c#L326

по поводу флагов, если судить по тем исходникам, что я привел, в структуре thread_info поле state принимает значение  TASK_UNINTERRUPTIBLE
видимо это что - то значит для планировщика  smile , что именно я не вникал
http://lxr.linux.no/#linux+v3.0.4/include/linux/sched.h#L172

извиняюсь, если понаделал каких - то ошибок в описании, хотел убрать лишнее, чтобы показать элементарный механизм блокировки/разблокировки
мьютекса и вызов ожидающих задач.
сейчас поздно, я уже сплю, поэтому я надеюсь, что правильно понял вопрос ТС


PM MAIL   Вверх
boostcoder
Дата 5.9.2011, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 16
Всего: 110



null56, спасибо. понял. все в тему!
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0482 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.