Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Semaphores
yes no
value >= 1
value = nothing
value -1
C
B
yes no
value >= 1
value = Go to sleep
value -1
B C
yes no
process
waiting?
Wakeup a value =
waiting value +1
B C
sem_wait(sem);
LOAD R1, M(counter); // load the counter value to register R1
INC R1; // increment the register R1
STORE R1, M(counter); // store the result back to counter
sem_post(sem);
1
pshared is used for multiple processes to share the same semaphore. Since BrickOS does not support
processes, so this option is not applicable and is ignored.
T1 T2 T3
S1 S2
S3
S4
T1 T2 T3
.
S1 S2
sem_post(sem1); sem_wait(sem1); sem_post(sem2);
sem_wait(sem2);
S3
sem_post(sem3);
sem_wait(sem3);
S4
sem_t pntr_sem;
sem_t mutex;
int main() {
sem_init(&pntr_sem, 0, 3);
sem_init(&mutex, 0, 1);
execi(thread_fun, …);
execi(thread_fun, …);
}
void thread_fun() {
printer = allocate_pntr();
// use printer
deallocate(printer);
}
int allocate() {
sem_wait(&pntr_sem);
sem_wait(&mutext);
int printer = get_printer();
sem_post(&mutex);
return printer;
}
void deallocate(int printer) {
sem_wait(&mutex);
release_printer(printer);
sem_post(&mutex);
sem_post(&pntr_sem);
}
class Semaphore {
private:
sem_t sem;
public:
Semaphore() { Semaphore(1); }
Semaphore(int val) {
sem_init(&sem, 0, val);
}
int wait() {
return sem_wait(&sem);
}
int trywait() {
return sem_trywait(&sem);
}
int signal() {
return sem_post(&sem);
}
int getValue() {
int value;
sem_getvalue(&sem, &value);
return value;
}
void destroy() {
sem_destroy(&sem);
}
~Semaphore() {
sem_destroy(&sem);
}
};
// filename: critical-sec.C
#include <config.h>
#include <conio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dlcd.h>
#include <sys/tm.h>
#include "Semaphore.H"
class Shared {
private:
int shared[10];
public:
Shared(int x) {
for (int i=0; i<10; i++) shared[i] = x;
}
void set(int idx, int y) {
shared[idx] = y;
}
void print() {
for (int i=0; i<10; i++) {
lcd_int(shared[i]);
sleep(2);
lcd_clear();
sleep(1);
}
}
};
Shared shared(10);
Semaphore *mutex;
int value1 = 3;
int value2 = 5;
int main(int argc, char **argv)
{
tid_t pid1, pid2;
mutex = new Semaphore(1);
pid1 = execi(&thread1, 0, 0, 15, DEFAULT_STACK_SIZE);
lcd_int(pid1);
pid2 = execi(&thread2, 0, 0, 15, DEFAULT_STACK_SIZE);
lcd_int(pid1);
sleep(1);
cputs("before");
sleep(5);
shared.print();
cputs("after");
}
int thread1(int val, char** ptr) {
lcd_int(mutex->getValue());
mutex->wait();
lcd_int(mutex->getValue());
class Semaphore {
private int value;
Semaphore(int value) {
if (value < 0) throws
new IllegalArgumentException(value + “<0”);
this.value = value;
}
public synchronized down() throws InterruptedException {
while (value < 1) wait();
value = value –1;
}
public synchronized void up() {
value = value + 1;
notifyAll();
}
};
References