00001 /* 00002 * CntmLib - Подсчет ссылок, потоки, синхронизация, асинхронные процедуры, события 00003 * Copyright (c) 2005, Овсеевич Роман, CntmLib@mail.ru 00004 * _______________________________________________________________________________ 00005 * Разрешено свободное использование, копирование, распространение, изменение 00006 * (изменение сведений об авторских правах запрещено). Запрещена продажа и 00007 * включение всей библиотеки или ее частей в другие библиотеки. В сведениях об 00008 * авторских правах на программу (или сведениях о программе, об авторах, 00009 * использованных средствах разработки и т.д.) должна быть указана информация 00010 * о библиотеке CntmLib, ее авторе и, возможно, сайте или email'е. 00011 * Библиотека поставляется "как есть", без каких-либо гарантий со стороны автора. 00012 */ 00013 00014 #ifndef CNTM_SYNCUTILS_H 00015 #define CNTM_SYNCUTILS_H 00016 #include <sched.h> 00017 #include <unistd.h> 00018 #include <Cntm/SystemUtils/AtomicUtils.h> 00019 00020 namespace Cntm 00021 { 00022 namespace SpecUtils 00023 { 00024 00025 /** 00026 * Класс быстрого нерекурсивного мьютекса. Используется для коротких критических секций. 00027 * @author Овсеевич Р. 00028 * \ingroup SystemUtils 00029 */ 00030 class FastMutex 00031 { 00032 public: 00033 00034 /** 00035 * Класс блокировки для быстрого мьютекса. 00036 * @author Овсеевич Р. 00037 */ 00038 class Lock 00039 { 00040 public: 00041 00042 /** 00043 * Конструктор. Захватывает мьютекс. 00044 */ 00045 Lock(FastMutex& Mutex): mutex(&Mutex) { mutex->Enter(); } 00046 00047 /** 00048 * Конструктор. Захватывает мьютекс. 00049 */ 00050 Lock(FastMutex* Mutex): mutex(Mutex) { mutex->Enter(); } 00051 00052 /** 00053 * Деструктор. Освобождает мьютекс. 00054 */ 00055 ~Lock() { mutex->Leave(); } 00056 00057 private: 00058 00059 /** 00060 * Указатель на мьютекс. 00061 */ 00062 FastMutex* mutex; 00063 }; 00064 00065 /** 00066 * Конструктор. 00067 */ 00068 FastMutex(): flag(-1) {} 00069 00070 /** 00071 * Войти в критическую секцию. Если критеческая сеция занята, то производит ожидание ее освобождения. Повторный вызов из того же потока приведет к зависанию. 00072 */ 00073 void Enter() 00074 { 00075 // Пока после увеличения флаг не примет значение 0, 00076 // перевести его в предыдущее состояние и ожидать. 00077 while (!flag.IncAndTest()) 00078 { 00079 flag.Dec(); 00080 sched_yield(); 00081 } 00082 } 00083 00084 /** 00085 * Выйти из критической секции. 00086 */ 00087 void Leave() { flag.Dec(); } 00088 00089 private: 00090 00091 /** 00092 * Флаг занятости критической секции. -1 - свободна, >= 0 - занята. 00093 */ 00094 AtomicVariable flag; 00095 }; 00096 00097 /** 00098 * Функция ожидания момента, когда занчение переменной Variable перестанет равняться BadValue. 00099 * \ingroup SystemUtils 00100 */ 00101 template < typename T > 00102 inline void FastWaitNoEqual(volatile const T* Variable, T BadValue) 00103 { 00104 while (*Variable == BadValue) 00105 sched_yield(); 00106 } 00107 00108 /** 00109 * Функция ожидания момента, когда занчение переменной Variable перестанет равняться Value. В этот момент она атомарно опять устанавливает Value и возвращает то значение, которое было до установки Value. 00110 * \ingroup SystemUtils 00111 */ 00112 template < typename T > 00113 inline T* FastWaitPtrNoEqualAndSet(T*volatile* Variable, T* Value) 00114 { 00115 T* res; 00116 while ((res = AtomicSwapPtr(Variable, Value)) == Value) 00117 sched_yield(); 00118 return res; 00119 } 00120 00121 /** 00122 * Функция ожидания момента, когда занчение переменной Variable станет равной NeedValue. 00123 * \ingroup SystemUtils 00124 */ 00125 template < typename T > 00126 inline void FastWaitEqual(volatile const T* Variable, T NeedValue) 00127 { 00128 while (*Variable != NeedValue) 00129 sched_yield(); 00130 } 00131 00132 /** 00133 * Функция ожидания момента, когда занчение атомарной переменной станет равной NeedValue. 00134 * \ingroup SystemUtils 00135 */ 00136 inline void FastWaitEqual(const AtomicVariable& Variable, 00137 AtomicVariable::Type NeedValue) 00138 { 00139 while (Variable.Value() != NeedValue) 00140 sched_yield(); 00141 } 00142 00143 } 00144 } 00145 00146 #endif //CNTM_SYNCUTILS_H
© Овсеевич Р.В. Документация по CntmLib 1.1.4 от 28 May 2008. Создано системой 1.5.3 |