mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-19 01:25:05 -04:00
Improve semaphore
This commit is contained in:
parent
e1a555482a
commit
ad6cd47457
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user