Merge branch 'master' of gitlab.ibr.cs.tu-bs.de:vss/teaching/ws25/v_bsb2/Gruppe_003
This commit is contained in:
@@ -20,7 +20,9 @@ struct Vault {
|
|||||||
Bellringer bellringer;
|
Bellringer bellringer;
|
||||||
BBuffer<Key, 16> keys;
|
BBuffer<Key, 16> keys;
|
||||||
Semaphore keys_sem;
|
Semaphore keys_sem;
|
||||||
|
static constexpr int MAX_SEMS =32;
|
||||||
|
|
||||||
|
Semaphore sems[MAX_SEMS];
|
||||||
// Ignore this for now, this is for a bonus task
|
// Ignore this for now, this is for a bonus task
|
||||||
Graphics graphics;
|
Graphics graphics;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ class Semaphore {
|
|||||||
// Prevent copies and assignments
|
// Prevent copies and assignments
|
||||||
Semaphore(const Semaphore&) = delete;
|
Semaphore(const Semaphore&) = delete;
|
||||||
Semaphore& operator=(const Semaphore&) = delete;
|
Semaphore& operator=(const Semaphore&) = delete;
|
||||||
unsigned counter;
|
|
||||||
Queue<Thread> waiting;
|
Queue<Thread> waiting;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -33,7 +32,8 @@ class Semaphore {
|
|||||||
* \param c Initial counter value
|
* \param c Initial counter value
|
||||||
*/
|
*/
|
||||||
explicit Semaphore(unsigned c = 0) : counter(c) {}
|
explicit Semaphore(unsigned c = 0) : counter(c) {}
|
||||||
|
unsigned counter;
|
||||||
|
bool used;
|
||||||
/*! \brief Wait for access to the critical area.
|
/*! \brief Wait for access to the critical area.
|
||||||
*
|
*
|
||||||
* Enter/decrement/wait operation: If the counter is greater than 0, then
|
* Enter/decrement/wait operation: If the counter is greater than 0, then
|
||||||
|
|||||||
@@ -50,6 +50,19 @@ extern "C" size_t syscall_handler(size_t sysnum, size_t p1, size_t p2,
|
|||||||
case Syscall::ID::READ:
|
case Syscall::ID::READ:
|
||||||
;
|
;
|
||||||
break;
|
break;
|
||||||
|
case Syscall::ID::SEM_INIT:
|
||||||
|
Syscall::Skeleton::sem_init(Guard::enter().vault(), p1, p2);
|
||||||
|
break;
|
||||||
|
case Syscall::ID::SEM_DESTROY:
|
||||||
|
Syscall::Skeleton::sem_destroy(Guard::enter().vault(), p1);
|
||||||
|
break;
|
||||||
|
case Syscall::ID::SEM_WAIT:
|
||||||
|
Syscall::Skeleton::sem_wait(Guard::enter().vault(), p1);
|
||||||
|
break;
|
||||||
|
case Syscall::ID::SEM_SIGNAL:
|
||||||
|
Syscall::Skeleton::sem_signal(Guard::enter().vault(), p1);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<size_t>(-1);
|
return static_cast<size_t>(-1);
|
||||||
|
|||||||
@@ -46,25 +46,39 @@ void sleep(Vault &vault, size_t ms) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool sem_init(Vault &vault, size_t id, uint32_t value) {
|
bool sem_init(Vault &vault, size_t id, uint32_t value) {
|
||||||
(void)vault;
|
if (id >= vault.MAX_SEMS) {
|
||||||
(void)id;
|
return false; // out‐of‐range id
|
||||||
(void)value;
|
}
|
||||||
return false;
|
if (vault.sems[id].used==1){
|
||||||
|
return false; //already in use
|
||||||
}
|
}
|
||||||
|
|
||||||
void sem_destroy(Vault &vault, size_t id) {
|
vault.sems[id].counter=value;
|
||||||
(void)vault;
|
return true;
|
||||||
(void)id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sem_signal(Vault &vault, size_t id) {
|
bool sem_destroy(Vault &vault, size_t id) {
|
||||||
(void)vault;
|
if (id >= vault.MAX_SEMS) {
|
||||||
(void)id;
|
return false; // out‐of‐range id
|
||||||
|
}
|
||||||
|
if (vault.sems[id].used==0){
|
||||||
|
return false; //already in free
|
||||||
}
|
}
|
||||||
|
|
||||||
void sem_wait(Vault &vault, size_t id) {
|
vault.sems[id].used=0;
|
||||||
(void)vault;
|
vault.sems[id].counter=0;
|
||||||
(void)id;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sem_signal(Vault &vault, size_t id) {
|
||||||
|
vault.sems[id].v(vault);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sem_wait(Vault &vault, size_t id) {
|
||||||
|
vault.sems[id].p(vault);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit(Vault &vault) { (void)vault; }
|
void exit(Vault &vault) { (void)vault; }
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ size_t write(Vault &vault, uint32_t id, const void *buffer, size_t size);
|
|||||||
size_t read(Vault &vault, uint32_t id);
|
size_t read(Vault &vault, uint32_t id);
|
||||||
void sleep(Vault &vault, size_t ms);
|
void sleep(Vault &vault, size_t ms);
|
||||||
bool sem_init(Vault &vault, size_t id, uint32_t value);
|
bool sem_init(Vault &vault, size_t id, uint32_t value);
|
||||||
void sem_destroy(Vault &vault, size_t id);
|
bool sem_destroy(Vault &vault, size_t id);
|
||||||
void sem_signal(Vault &vault, size_t id);
|
bool sem_signal(Vault &vault, size_t id);
|
||||||
void sem_wait(Vault &vault, size_t id);
|
bool sem_wait(Vault &vault, size_t id);
|
||||||
void exit(Vault &vault);
|
void exit(Vault &vault);
|
||||||
void kill(Vault &vault, size_t pid);
|
void kill(Vault &vault, size_t pid);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ enum class ID : size_t {
|
|||||||
TEST = 0,
|
TEST = 0,
|
||||||
WRITE = 1,
|
WRITE = 1,
|
||||||
READ = 2,
|
READ = 2,
|
||||||
|
//SLEEP =3,
|
||||||
|
SEM_INIT=4,
|
||||||
|
SEM_DESTROY=5,
|
||||||
|
SEM_WAIT=6,
|
||||||
|
SEM_SIGNAL=7,
|
||||||
|
//SYS_GETPID=8,
|
||||||
|
//SYS_EXIT= 9,
|
||||||
|
//SYS_KILL=10
|
||||||
};
|
};
|
||||||
} // namespace Syscall
|
} // namespace Syscall
|
||||||
|
|
||||||
@@ -32,3 +40,18 @@ extern "C" ssize_t sys_safe_call(Syscall::ID id, size_t p1, size_t p2,
|
|||||||
[[gnu::always_inline]] static inline int read(int fd, void *buf, size_t len){
|
[[gnu::always_inline]] static inline int read(int fd, void *buf, size_t len){
|
||||||
return sys_call(Syscall::ID::READ, fd, (size_t)buf, len, 0, 0);
|
return sys_call(Syscall::ID::READ, fd, (size_t)buf, len, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]] static inline int sem_init(int fd, int semid, int value) {
|
||||||
|
return sys_call(Syscall::ID::SEM_INIT, fd, semid, value, 0,0);
|
||||||
|
}
|
||||||
|
[[gnu::always_inline]] static inline int sem_destroy(int fd, int semid) {
|
||||||
|
return sys_call(Syscall::ID::SEM_DESTROY, fd, semid,0,0,0);
|
||||||
|
}
|
||||||
|
[[gnu::always_inline]] static inline int sem_wait(int fd, int semid) {
|
||||||
|
return sys_call(Syscall::ID::SEM_WAIT, fd, semid,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[gnu::always_inline]] static inline int sem_signal(int fd, int semid) {
|
||||||
|
return sys_call(Syscall::ID::SEM_SIGNAL, fd, semid,0,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user