Page 343 - DCAP103_Principle of operating system
P. 343

Principles of Operating Systems



                   Notes         Each object header also contains a quota charge field, which is the charge levied against a process
                                 for opening the object. If a file object costs 1 point and a process belongs to a job that has 10
                                 file points worth of quota, the processes in that job can only open 10 files in total. In this way
                                 resource limits can be enforced for each object type separately.
                                 Objects occupy valuable real estate—pieces of kernel virtual address space, so when an object
                                 is no longer needed it should be removed and its address space reclaimed. The mechanism
                                 for reclamation is to have a reference counter in each object’s header. It counts the number of
                                 open handles held by processes. This counter is incremented every time the object is opened
                                 and decremented every time it is closed. When it hits 0, no more users hold handles to the
                                 object. When an object is acquired or released by an executive component, a second counter is
                                 incremented or decremented, even though no actual handle is issued. When both counters hit 0, no
                                 user process is using the object and no executive process is using the object, so the object can
                                 be removed and its memory freed.
                                 The object manager needs to maintain dynamic data structures (its objects), but it is not the only
                                 part of the executive with this need. Other pieces also need to allocate and release chunks of
                                 kernel memory dynamically. To meet these needs, the executive maintains two page pools in
                                 kernel address space—for objects and for other dynamic data structures. Such pools operate as
                                 heaps, similar to the C language calls malloc and free for managing dynamic data. One pool is
                                 paged and the other is nonpaged (pinned in memory). Objects that are needed often are kept
                                 in the nonpaged pool; objects that are rarely accessed, such as registry keys and some security
                                 information, are kept in the paged pool. When memory is tight, the latter can be paged out and
                                 faulted back on demand. In fact, substantial portions of the operating system code and data
                                 structures are also pageable, to reduce memory consumption. Objects that may be needed when
                                 the system is running critical code (and when paging is not permitted) must go in the nonpaged
                                 pool. When a small amount of storage is needed, a page can be taken from either pool and then
                                 broken up into units as small as 8 bytes.
                                 Objects are typed, which means each one has certain properties common to all objects of its
                                 type. The type is indicated by a pointer in the header to a type object, as shown in Figure 11.3.
                                 The type object information includes items such as the type name, whether a thread can wait
                                 on the object (yes for mutexes, no for open files), and whether new objects of this type go on
                                 the paged or nonpaged pool. Each object points to its type object.
                                 The last thing a type object has is also the most important: pointers to the code for certain standard
                                 operations such as open, close, and delete. Whenever one of these operations is invoked on an
                                 object, the pointer to the type object is followed and the relevant code located and executed.
                                 This mechanism gives the system the opportunity to initialize new objects, and recover storage
                                 when they are deleted.
                                 Executive components can create new types dynamically. There is no definite list of object types,
                                 but some of the more common ones are listed in Figure 11.4. Let us briefly go over the object
                                 types in Figure 11.4. Process and thread are obvious. There is one object for every process and
                                 every thread, which holds the main properties needed to manage the process or thread. The
                                 next three objects, semaphore, mutex, and event, all deal with interprocess synchronization.
                                 Semaphores  and  mutexes  work  as  expected,  but  with  various  extra  bells  and  whistles  (e.g.,
                                 maximum values and timeouts). Events can be in one of two states: signaled or nonsignaled.
                                 If a thread waits on an event that is in signaled state, the thread is released immediately. If the
                                 event is in nonsignaled state, it blocks until some other thread signals the event, which releases
                                 all blocked threads. An event can also be set up, so after a signal has been successfully waited
                                 for, it automatically reverts back to nonsignaled state, rather than staying in signaled state.




        336                               LOVELY PROFESSIONAL UNIVERSITY
   338   339   340   341   342   343   344   345   346   347   348