A semaphore is an operation used for mutual exclusion and synchronization.
Conceptually, semaphores can be viewed as a bucket. When you allocate a semaphore, you create a virtual bucket. Inside the bucket are a number of keys. No process can be executed without first having a key. So, if a specific process requires a key, only a finite number of occurrences of that process can be in progress simultaneously. All others must wait until a key is returned to the virtual bucket.
Semaphore Allocation ::
To allocate a semaphore, you must use the alloc() system function.
Syntax : function integer alloc(SEMAPHORE, integer semaphore_id,integer semaphore_count, integer key_count);
The alloc() function returns the base semaphore ID if the semaphores are successfully created. Otherwise, it returns 0.
semaphore_id :::
is the ID number of the particular semaphore being created. It must be an integer value. You should generally use 0. When you
use 0, a semaphore ID is automatically generated by the simulator. Using any other number explicitly assigns an ID to the
semaphore being created.
semaphore_count:::
specifies how many semaphore â~@~\bucketsâ~@~] you want to create. It must be an integer value.
key_count :::
specifies the number of keys initially allocated to each semaphore â~@~\bucketâ~@~] you are creating.
Using Semaphore Keys ::
To check that there are enough keys left in the semaphore, you must use the semaphore_get() system function.
Syntax : function integer semaphore_get(NO_WAIT | WAIT,integer semaphore_id, integer key_count);
To put keys back into a semaphore, you must use the semaphore_put() system task.
EXAMPLE : simaphore program vshell {
integer sema,get;
sema = alloc(SEMAPHORE,1,3,2);
if(!sema)
error("Semaphore Allocation failed\n");
repeat(3) {
fork {
printf("Before getting key 1\n");
get = semaphore_get(NO_WAIT,sema,2);
if(!get)
error(" No sempahore key for inject2 \n");
else printf(" Got Key from 1 \n");
if(!get)
error(" No sempahore key for inject2 \n");
else printf(" Got Key from 2 \n");
semaphore_put(sema + 1,2);
delay(10);
}
join all
}
delay(1000);
}
RESULTS
Before getting key 1 Got Key from 1 Putting back key Before getting key 2 Got Key from 2 Before getting key 1 Got Key from 1 Putting back key Before getting key 2 Got Key from 2 Before getting key 1 Got Key from 1 Putting back key Before getting key 2 Got Key from 2
The number of keys in the bucket can increase if more keys are put into the bucket than are removed. Therefore, key_count is not necessarily the maximum number of keys in the bucket.
EXAMPLE: program vshell {
integer sema,get;
sema = alloc(SEMAPHORE,0,1,1);
if(!sema)
error("Semaphore Allocation failed\n");
printf("Before getting key 1\n");
get = semaphore_get(WAIT,sema,1);
if(!get)
error(" No sempahore key for inject2 \n");
else printf(" Got Key from 1 \n");
semaphore_put(sema,1);
printf(" Putting back key \n");
semaphore_put(sema,1);
printf(" Putting back key \n");
printf("Before getting key 1\n");
get = semaphore_get(WAIT,sema,1);
if(!get)
error(" No sempahore key for inject2 \n");
else printf(" Got Key from 1 \n");
printf("Before getting key 1\n");
get = semaphore_get(WAIT,sema,1);
if(!get)
error(" No sempahore key for inject2 \n");
else printf(" Got Key from 1 \n");
delay(1000);
}
RESULTS:
Before getting key 1 Got Key from 1 Putting back key Putting back key Before getting key 1 Got Key from 1 Before getting key 1 Got Key from 1