I) 1) A file that can be mapped to the virtual address space of a process is called a memory mapped file. Reads and writes to a file system become reads and writes to virtual memory; hence, faster. Problems with consistency include 2) Access Control List is a protection mechanism wherein associated with each object is a list containing all the domains that may access the object, and how. Revocation of privileges is easy, as the owner of an object can change its ACL at anytime. Capability is associated with each domain. Capability contains a list of objects that may be accessed, along with the operations allowed on those objects. Revocation of access to an object is quite difficult, as it is hard to find all outstanding capabilities. 3) The superblock contains information describing the layout of the file system. It contains information about the number of inodes, number of disk blocks, and addresses of up to 100 free blocks. Each file has an i-node structure that contains the information required to access the file. This information includes, among others, protection information, file size, and disk addresses of blocks on which the file is stored. 4) AFS uses complete file caching; a file cached is assumed to be valid unless the server revokes the call back NFS uses block level caching; a block cached is valid for 3 secs if it is dir block, 30 secs if it is dir block. If the time has expired, then the client need to check with the server to see if the block is still valid 5)User level threads are managed by runtime library routines that are linked into each application so that thread management operations require no kernel level intervention. The OS has no knowledge of threads within a process and hence any blocking call will result in the blocking of entire process and no parallelism on multiprocessors as kernel can only schedule processes. With kernel level threads, the program must cross an extra protection boundary on every thread operation. The kernel can do thread level scheduling and hence true parallelism on multiprocessors can be achieved. Monitor Barber_shop { int chair[2] = {0,0} int tcount =0 int count[2]={0,0} condition barber_available[2],chair_occupied[2] /* Monitor procedures */ get-haircut (int t) finish_cut(int t) { if tcount ! = n { tcount --; count[t]--; { tcount ++; count[t]++; if(count[t] > 0)signal(barber_available[t]) if (count[t] > 1) wait (barber_available[t]) } chair[t] = 1; signal(chair_occupied[t]) return(true) } else return(false) } get_nextcustomer(int t) { while (chair[t] == 0) wait(chair_occupied[t]); chair[t] = 0; } } /* End monitor barber shop */ Process M_barber() Process M_Customer() While(TRUE) { If (get_haircut(0) == TRUE) { get_nextcustomer(0) { Get hair cut; Give a cut; } finish_cut(0);}} Process F_barber() Process F_Customer() While(TRUE) { If (get_haircut(1) == TRUE) { get_nextcustomer(1) { Get hair cut; Give a cut;} finish_cut(1);}} 2) condition printer[n]; int P[3]={False,False,False} acquire(int id) { while (P[0] && p[1] && p[2]) wait(printer[id]); if p[0] == False then printer-id =0 else if p[1] == False then printer-id =1 else printer-id = 2 P[printer-id]=true; return (printer-id) } release(int printer-id) { p[printer-id] = False; for (i=0; i