//=========================================================================== // // // Claire Launay // ArchOS Project 5--The barbershop. // Due April 21 // Finished May 11, 2:30 pm // // Assignment: Write an implementation of the barber shop program // using shared memory and semaphores. // Parameters to program: // 1.Parameter 1 - How long (in seconds) the Consumer process should // sleep before starting, default = 1, i.e., time it takes Barber to // have coffee. // 2.Parameter 2 - Used to determine if the Barber Shop contents (the // queue) should be printed out by the Monitor/Lieutenant (print // entire circular buffer in addition to normal printout: default = // 0, no print). An example will be posted. You are to Match the // posted format in your output. // 3.Parameter 3 - How long the Producer should sleep between each // search of the wait area, default = 3. // Input to program is from the command line, or redirected from a // file. The file should contain lines consisting or two digits // indicating what kind of person is waiting for a haircut and how // long his haircut will take. // -The first digit indicates the person's food chain position (0 for // grunts, 1 for ncs, and 2 for officers) // -the second digit provides the time for a haircut // Shared memory structures: // I use shared memory for two purposes. One is for the waiting // room, which is an array of MAX_ROOM_SIZE=20 chairs. The waiting // room is in reality an array containing 4 doubly linked queues. // One for the free list, and one for each of the kinds of people. // Here are the declarations for the waiting room: // enum foodchain{FREE, GRUNT, NC, OFFICER}; // //each individual chair in the waiting room // //holds all the information about the person in the chair // struct chair // { // //whether the individual in this chair is a grunt or an nc or an // //officer, or if this chair is in the freelist. // foodchain kind_of_person; // //in anticipation of the second project, I use priority to determine // //what priority queue an individual should be in, regardless of who he // //actually is. // foodchain priority; // //how long it takes for the barber to cut this individual's hair. // int cut_time; // //the next person in the queue that this person is in. // int next; // //the previous peron in the queue that this person is in. // int prev; // }; // chair* waiting_room; //shared array of the waiting room // To keep track of everything else, I have another shared array of // integers that keeps track of all of the other information that all // of the processes need to know. Specifically, it keeps track of: // -the flags indicating if the barber or sergeant are alive or dead // -how many people are waiting in the waiting room // -who is currently in the barber's chair // -the heads and tails of the free, grunt, nc, and officer lists // -how many grunts, ncs, and officers have entered // -how many grunts, ncs, and officers are currently in the waiting room // Implementation: // In main, I read in the parameters, do some basic checking for // validity of input, allocate all of the shared memory, and then // initialized the waiting room so that all the chairs in the waiting // room are in the free list. I also initialize all of the variables // in the state array, such as the heads and tails of all the lists // and the number of people who are waiting, and so on. Then, I fork // off the sergeant, and have it call a sergeant function. Then, I // fork off the barber, and call a barber function. Then, the parent // process calls the lieutenant function. // Sergeant function: // The sergeant reads in people from the command line. As long as // the waiting room isn't full, the sergeant sleeps for the amount of // time dictated by the appropriate parameter, then takes a chair // from the head of the free list, and adds the person to the tail of // the appropriate list (corresponding to the position in the food // chain of the person.) If the waiting room is full, he blocks // until the barber has taken someone from the room. The sergeant // dies when there are no more people to be added to the waiting // room. // Barber function: // As long as the waiting room isn't empty, the barber takes someone // from the tail of the appropriate list (an officer, if there are // any, otherwise, an nc, if there are any, otherwise a grunt), and // adds the chair that person was sitting in to the head of the // freelist. In this way, if there is only one kind of person, then // that list acts as a circular buffer. The barber then takes that // person, puts him in the barber chair and then sleeps for the // amount of time dictated by the input. After that, the barber // frees the chair, and goes to look for someone else. If the // waiting room is empty, the barber blocks until the sergeant adds // someone to the room. The barber dies when the sergeant has died // and the waiting room has emptied. // Lieutenant function: // Every 2 seconds, the lieutenant pokes his head into the waiting // room and looks at what the state of the room is. He prints how // many people of each kind have entered the room, are waiting, and // have had their hair cut. He also prints out how many people are // currently in the waiting room, how many chairs are empty, and what // kind of person is in the barber's chair. The lieutenant dies when // the sergeant and the barber have both died. // Semaphores used: 4 // I used 4 semaphores. 2 were mutual exclusion semaphores. One of // these was for the waiting room, and the other was for the array of // states. The other two semaphores were for dealing with the // waiting room being empty or full. After the sergeant added a // person to the room, causing the room to be full, he downed the // full room semaphore, and thus blocked. If the barber took a // person from a full room, he upped the full room semaphore, thus // allowing the sergeant to stop blocking and go back to adding // people to the waiting room. Similarly, if the barber found the // waiting room empty, and the sergeant still alive, he blocked by // downing an empty room semaphore until the sergeant upped it upon // adding someone to an empty room. // Child processes termination: // 1. Sergeant--The sergeant terminates when he reaches the end of the // input file (or if he reaches some bad data in the input file.) // Before terminating, he sets a flag in the shared states array // indicating that he has died. // 2. Barber--The barber terminates when the sergeant is dead and // the waiting room is empty. When he terminates, he sets a flag in // the shared state array indicating that he has died. // 3. Lieutenant--The lieutenant runs until both the sergeant and // the barber have died. Once they have both died, the lieutenant // waits on his two child processses, and then detaches the shared // memory and takes care of returning all the shared memory and the // semaphores. Then, he too, dies, and the barbershop closes. // Miscellaneous notes: // 1. In the webpage for the output format, it said line numbers were for // reference only, so I didn't print them out when formatting the output. // 2. Whenever someone steps out of the barber's chair, the chair is // considered free until the next person steps into it. This means that // when the room is empty but the sergeant is not yet dead, and the // barber is waiting for the sergeant to add someone to the room, the // chair is free. // Similarities to scheduling: // The barbershop is very similar to a scheduler. Each individual // person can be thought of as a process, and each of the different // processes has a different priority. In this implementation, since // people do not change priorities, low-level people, ie, grunts, can // get starved if higher priority people keep coming into the // barbershop. The same can happen with scheduling processes, if // there is a strict, unchangeable priority. The next implementation // of the barbershop seeks to fix that somewhat by allowing people to // up their priorities after they have been in a queue for long // enough, in a manner similar to multi-level feedback queues. //===========================================================================