diff --git a/kernel/interrupt/guard.h b/kernel/interrupt/guard.h index 16c20fc..021b737 100644 --- a/kernel/interrupt/guard.h +++ b/kernel/interrupt/guard.h @@ -20,7 +20,9 @@ struct Vault { Bellringer bellringer; BBuffer keys; Semaphore keys_sem; +static constexpr int MAX_SEMS =32; + Semaphore sems[MAX_SEMS]; // Ignore this for now, this is for a bonus task Graphics graphics; diff --git a/kernel/sync/semaphore.h b/kernel/sync/semaphore.h index cb0a9bd..17b3655 100644 --- a/kernel/sync/semaphore.h +++ b/kernel/sync/semaphore.h @@ -25,7 +25,6 @@ class Semaphore { // Prevent copies and assignments Semaphore(const Semaphore&) = delete; Semaphore& operator=(const Semaphore&) = delete; - unsigned counter; Queue waiting; public: @@ -33,7 +32,8 @@ class Semaphore { * \param c Initial counter value */ explicit Semaphore(unsigned c = 0) : counter(c) {} - + unsigned counter; + bool used; /*! \brief Wait for access to the critical area. * * Enter/decrement/wait operation: If the counter is greater than 0, then diff --git a/kernel/syscall/handler.cc b/kernel/syscall/handler.cc index fdf609f..f55febb 100644 --- a/kernel/syscall/handler.cc +++ b/kernel/syscall/handler.cc @@ -50,7 +50,20 @@ extern "C" size_t syscall_handler(size_t sysnum, size_t p1, size_t p2, case Syscall::ID::READ: ; 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(-1); } diff --git a/kernel/syscall/skeleton.cc b/kernel/syscall/skeleton.cc index 5f7acf8..04694e1 100644 --- a/kernel/syscall/skeleton.cc +++ b/kernel/syscall/skeleton.cc @@ -46,25 +46,39 @@ void sleep(Vault &vault, size_t ms) { } bool sem_init(Vault &vault, size_t id, uint32_t value) { - (void)vault; - (void)id; - (void)value; - return false; + if (id >= vault.MAX_SEMS) { + return false; // out‐of‐range id + } + if (vault.sems[id].used==1){ + return false; //already in use + } + + vault.sems[id].counter=value; + return true; } -void sem_destroy(Vault &vault, size_t id) { - (void)vault; - (void)id; +bool sem_destroy(Vault &vault, size_t id) { + if (id >= vault.MAX_SEMS) { + return false; // out‐of‐range id + } + if (vault.sems[id].used==0){ + return false; //already in free + } + + vault.sems[id].used=0; + vault.sems[id].counter=0; + return true; } -void sem_signal(Vault &vault, size_t id) { - (void)vault; - (void)id; +bool sem_signal(Vault &vault, size_t id) { + vault.sems[id].v(vault); + + return true; } -void sem_wait(Vault &vault, size_t id) { - (void)vault; - (void)id; +bool sem_wait(Vault &vault, size_t id) { + vault.sems[id].p(vault); + return true; } void exit(Vault &vault) { (void)vault; } diff --git a/kernel/syscall/skeleton.h b/kernel/syscall/skeleton.h index 5f9f831..7ab0464 100644 --- a/kernel/syscall/skeleton.h +++ b/kernel/syscall/skeleton.h @@ -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); void sleep(Vault &vault, size_t ms); bool sem_init(Vault &vault, size_t id, uint32_t value); -void sem_destroy(Vault &vault, size_t id); -void sem_signal(Vault &vault, size_t id); -void sem_wait(Vault &vault, size_t id); +bool sem_destroy(Vault &vault, size_t id); +bool sem_signal(Vault &vault, size_t id); +bool sem_wait(Vault &vault, size_t id); void exit(Vault &vault); void kill(Vault &vault, size_t pid); diff --git a/kernel/syscall/stub.h b/kernel/syscall/stub.h index 379ec7d..8661b48 100644 --- a/kernel/syscall/stub.h +++ b/kernel/syscall/stub.h @@ -9,6 +9,14 @@ enum class ID : size_t { TEST = 0, WRITE = 1, 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 @@ -26,9 +34,24 @@ extern "C" ssize_t sys_safe_call(Syscall::ID id, size_t p1, size_t p2, } [[gnu::always_inline]] static inline int write(int fd, const void *buf, size_t len, int x = -1, int y = -1) { - return sys_call(Syscall::ID::WRITE, fd, (size_t)buf, len, x, y); + return sys_call(Syscall::ID::WRITE, fd, (size_t)buf, len, x, y); } [[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); } + +[[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); +} +