I3MUP1+Exercise+4

toc =Exercise 4=

Assignment 4.1
In this exercise you will get some routine in using thread synchronization mechanisms. First, you will rectify the problem from Lab Exercise 3.2 using a semaphore. Then, you will create a generic (template) class that ensures atomic access to the data it protects.

4.1.1
//Which type of semaphore is the correct one to use to solve the problems in Lab Exercise 3?//

It would probably be optimal to use Mutex seing as we need resource protection in exercise 3.2 to completely avoid the shared data problem.

4.1.2
//Modify your program from Lab Exercise 3.2-3 and 3.2-4 to create and use a semaphore of the type determined above so that the shared resource is accessed automically. Does it work?//

Yes, it works......

But to elaborate, what we did was that we started out by creating our mutex object. After creating the object we went into the incrementer and reader function respectively and encased the point of which we used the shared data with mutex locking and unlocking. Example is shown below: code void * incrementer(void * shared) {   while(1) {       pthread_mutex_lock(&myMutex); (*(int*)(shared))++; pthread_mutex_unlock(&myMutex); sleep(1); }   return NULL; } code

In our main function the mutex object is initialized and, as expected, the program runs with no problems. We finish up by destroying the mutex object using pthread_mutex_destroy(&myMutex).

4.1.3
//Implement the class ScopedLocker and use it in class Vector to protect the resource.//

We implement the ScopedLocker class because we wish to ensure that whenever a mutex is locked it is unlocked before we "leave" the element we wanted to protect. Unfortunately bad programming(such as 'goto' or reckless use of break etc) and unexpected exceptions can cause the program to exit the function call before the mutex is released.

Below you will see the very simple but effective ScopedLocker class : code format="cpp" ScopedLocker::ScopedLocker(Mutex & m) { myMutex = m;   pthread_mutex_lock(myMutex); }

Scopedlocker::~ScopedLocker {   pthread_mutex_unlock(myMutex); } code

The implementation in the Vector class function "setandTest" is done by simply calling the constructor before doing anything else. Because the constructor is called locally in the class, the program will call the destructor once we exit the scope thereby releasing the mutex. We have now ensured the releasing of the mutex regardless of how we exit the scope.

Assignment 4.2
//In this exercise you will implement a Parking Lot Control System (PLCS) which monitors a parking lot and// //grants access for cars to enter and exit the parking lot.//

4.2.1
//Use the Park-a-Lot 2000 example of the recent lecture as an example of how a car may interact with the// //PLCS entry (or exit) guard to request access to enter (or exit) the parking lot and receive permission to do// //so.//


 * Parkeringsforløb**


 * Car arrives at entrance.
 * Car requests access to parking lot
 * If slots are available. Car is granted access.
 * Car waits a while
 * Car arrives at exit.
 * Car requests exit from parking lot.
 * Car exits parking lot
 * Car waits a while
 * Rinse and Repeat...

Each car is granted a thread in our system and with only a limited amount of slots on the parking lot a counting semaphore is used to handle the amount of spots left on the parking lot. Whenever a car arrives at the entrance its thread requests the semaphore and releases it again once it arrives at its slot. The thread is then put to sleep for a short while. The car's thread once again requests the semaphore when it arrives at the exit and releases it once the car has exited the parking lot.

4.2.2-3
//Implement the PLCS. Test PLCS using a number of cars – make sure that all cars enter and exit the parking// //lot correctly.//

Creating and initializing the semaphores.

code format=cpp sem_t emptySlots; sem_t usedSlots;

sem_init(&emptySlots, 0, 10); sem_init(&usedSlots, 0, 0);

code

Below you will see the implementation of both exitGuard and enterGuard. When manipulating with our counter variable we protect it with a scopedlocker to bypass the shared data problem.

code format=cpp void* enterGuard(void* counter) { while(1) { sem_wait(&emptySlots); increase(counter); sem_post(&usedSlots); sleep(1); } }

void * exitGuard(void * counter) { sleep(1); sem_wait(&usedSlots); decrease(counter); sem_post(&emptySlots); } code