Improve semaphore

This commit is contained in:
Baptiste Wicht 2016-07-09 15:54:16 +02:00
parent e1a555482a
commit ad6cd47457

View File

@ -8,7 +8,7 @@
#ifndef SEMAPHORE_H #ifndef SEMAPHORE_H
#define SEMAPHORE_H #define SEMAPHORE_H
#include <queue.hpp> #include <circular_buffer.hpp>
#include <lock_guard.hpp> #include <lock_guard.hpp>
#include "spinlock.hpp" #include "spinlock.hpp"
@ -18,39 +18,60 @@ struct semaphore {
private: private:
spinlock lock; spinlock lock;
size_t value; size_t value;
std::queue<scheduler::pid_t> queue; circular_buffer<scheduler::pid_t, 16> queue;
public: public:
void init(size_t v){ void init(size_t v){
value = v; value = v;
} }
void wait(){ void acquire(){
std::lock_guard<spinlock> l(lock); lock.acquire();
if(value > 0){ if(value > 0){
--value; --value;
lock.release();
} else { } else {
queue.push(scheduler::get_pid()); auto pid = scheduler::get_pid();
scheduler::block_process(scheduler::get_pid()); queue.push(pid);
scheduler::block_process_light(pid);
lock.release();
scheduler::reschedule();
} }
} }
void signal(){ void release(){
std::lock_guard<spinlock> l(lock); std::lock_guard<spinlock> l(lock);
if(queue.empty()){ if(queue.empty()){
++value; ++value;
} else { } else {
auto pid = queue.top(); auto pid = queue.pop();
scheduler::unblock_process(pid); scheduler::unblock_process(pid);
queue.pop();
//No need to increment value, the process won't //No need to increment value, the process won't
//decrement it //decrement it
} }
} }
void release(size_t v){
std::lock_guard<spinlock> l(lock);
if(queue.empty()){
value += v;
} else {
while(v && !queue.empty()){
auto pid = queue.pop();
scheduler::unblock_process(pid);
--v;
}
if(v){
value += v;
}
}
}
}; };
#endif #endif