Phoenix
Object-oriented orthogonally persistent operating system
|
00001 /* 00002 * /phoenix/kernel/sys/lock.h 00003 * 00004 * This file is a part of Phoenix operating system. 00005 * Copyright (c) 2011-2012, Artyom Lebedev <artyom.lebedev@gmail.com> 00006 * All rights reserved. 00007 * See COPYING file for copyright details. 00008 */ 00009 00014 #ifndef LOCK_H_ 00015 #define LOCK_H_ 00016 00017 #include <md_lock.h> 00018 00019 template <size_t numTokens> 00020 class Semaphore { 00021 private: 00022 SpinLock lock; 00023 size_t _numTokens; 00024 public: 00025 Semaphore() { _numTokens = 0; } 00026 00030 inline void Acquire(size_t tokens = 1) 00031 { 00032 ASSERT(tokens <= numTokens); 00033 bool acquired = false; 00034 do { 00035 lock.Lock(); 00036 if (_numTokens + tokens <= numTokens) { 00037 _numTokens += tokens; 00038 acquired = true; 00039 } 00040 lock.Unlock(); 00041 if (!acquired) { 00042 cpu::Pause(); 00043 } 00044 } while (!acquired); 00045 } 00046 00050 inline void Release(size_t tokens = 1) 00051 { 00052 lock.Lock(); 00053 ASSERT(tokens <= _numTokens); 00054 _numTokens -= tokens; 00055 lock.Unlock(); 00056 } 00057 }; 00058 00059 #endif /* LOCK_H_ */