The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Таймеры ядра Linux"
Отправлено BigHo, 21-Янв-07 16:23 
так получается реализация подобная userspace вызову
pthread_rwlock_tryrdlock/pthread_rwlock_unlock. Реализацию, близкую к pthread_trylock/pthread_unlock имеют вызовы pthread_rwlock_trywrlock/pthread_rwlock_unlock.

Хотя речь идет о вызовах ядра, можно реализовать тройку вызовов, близких к:
- pthread_rwlock_tryrdlock (my_lock_rd);
- pthread_rwlock_trywrlock (my_lock_wr);
- pthread_rwlock_unlock (my_unlock_rd и my_unlock_wr).

struct my_lock {
.   ...
.   int mtx_lock_count; // если < 0, значит открыт на запись,
.                       // если > 0, то открыт на чтение,
.                       // если == 0, свободен от блокировок.
.   spinlock_t mtx_lock;
.   ...
};

// смысл mtx_lock_count в том, что читающих процессов может быть несколько,
// и только один - записывающий. Можно договориться использовать значение -1 в
// качестве обозначения блокировки на запись, и любое положительное число -
// блокировка на чтение.

int
my_lock_rd(struct my_lock *mtx) {
.   int ret = 0;
.
.   spin_lock(&mtx->mtx_lock);
.   if (mtx->mtx_lock_count >= 0)
.       mtx->mtx_lock_count++;
.   else
.       ret = mtx->mtx_lock_count;
.   spin_unlock(&mtx->mtx_lock);
.   return ret;
}

int
my_lock_wr(struct my_lock *mtx) {
.   int ret = 0;
.
.   spin_lock(&mtx->mtx_lock);
.   ret = mtx->mtx_lock_count; // вернем информацию о том, какая блокировка
.                              // имеет место быть. В нашем случае, ошибкой
.                              // является ненулевой код возврата.
// чтобы произвести WRITE блокировку, замок должен быть свободен
// от любых блокировок. Иногда для WRITE используется термин
// "исключающая блокировка", а для READ - "конкурирующая блокировка".
.   if (mtx->mtx_lock_count == 0)
.       mtx->mtx_lock_count = -1; // метка блокировки на запись.
.   spin_unlock(&mtx->mtx_lock);
.   return ret;
}

// разблокирование - существенно более легкая задача.
// можно произвести кучу проверок, но зачем ?

void
my_unlock_rd(struct my_lock *mtx) {
.   spin_lock(&mtx->mtx_lock);
.   mtx->mtx_lock_count--;
.   spin_unlock(&mtx->mtx_lock);
}

void
my_unlock_wr(struct my_lock *mtx) {
.   spin_lock(&mtx->mtx_lock);
.   mtx->mtx_lock_count = 0;
.   spin_unlock(&mtx->mtx_lock);
}

У тебя используется глобальная переменая. Это будет хорошо работать, если замок нужен только один. В других случаях лучше использовать метод блокировки, подобный данному.

 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.

На сайте действует частичное премодерирование - после публикации некоторые сообщения от анонимов могут автоматически скрываться ботом. После проверки модератором ошибочно скрытые сообщения раскрываются. Для ускорения раскрытия можно воспользоваться ссылкой "Сообщить модератору", указав в качестве причины обращения "скрыто по ошибке".



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру