Distributed resource management system using hashing operation to direct resource request from different processors to the processor controlling the requested resource5301337Abstract A resource managing method operates in a computer system in which a variety of processes run essentially simultaneously on a group of processors, each processor being provided with a respective section of memory which is also accessible by the other processors in the group though typically not as quickly as by the respective processor. Resource data objects corresponding to particular resources are located by means of a hash table which is divided into portions which are distributed over respective sections of the overall system memory. A resource manager program, which is essentially replicated for each processor, implements a hashing algorithm which directs requests for access to designated resources to the corresponding portion of the hash table irrespective of which processor originated the request. Each section of the hash table includes a series of entries which provide pointers to respective lists of resource data objects which hash to that entry. The resource data objects, as well as various other data objects, are distributed over the different memory sections and include data elements which implement basic protection latches using a read-modify-write instruction. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
______________________________________
NODE .fwdarw.
lmi.sub.-- node
CID .fwdarw.
i.sub.-- cid
NID .fwdarw.
i.sub.-- nid
NODE COUNT .fwdarw.
i.sub.-- numnodes
PROCESS QUEUE .fwdarw.
i.sub.-- procs
NODE DIRECTORY .fwdarw.
i.sub.-- nodepp
HASH SIZES .fwdarw.
i.sub.-- hash.i.sub.-- hashsize,
i.sub.-- hash.i.sub.-- nodesize,
i.sub.-- hash.i.sub.-- thissize
HASH PTR .fwdarw.
i.sub.-- hash.i.sub.-- hashp
PROCESS .fwdarw.
lmi.sub.-- proc
PID .fwdarw.
i.sub.-- pid
CHECK .fwdarw.
i.sub.-- check
LOCK QUEUE .fwdarw.
i.sub.-- locks
CALLBACK QUEUE .fwdarw.
i.sub.-- calls
NODE ENTRY .fwdarw.
i.sub.-- nodeq
RESOURCE .fwdarw.
lmi.sub.-- res
NAME .fwdarw.
i.sub.-- name
GRANTED QUEUE .fwdarw.
i.sub.-- granted
REQUESTED QUEUE .fwdarw.
i.sub.-- requested
HASH ENTRY .fwdarw.
i.sub.-- hashq
LOCK .fwdarw.
lmi.sub.-- lock
RESOURCE PTR .fwdarw.
i.sub.-- resp
PROCESS PTR .fwdarw.
i.sub.-- procp
GRANTED .fwdarw.
i.sub. -- level
REQ STATUS .fwdarw.
i.sub.-- req.sub.-- stat
REQUESTED .fwdarw.
i.sub.-- req.sub.-- level
RESOURCE ENTRY .fwdarw.
i.sub.-- resq
PROCESS ENTRY .fwdarw.
i.sub.-- procq
CALLBACK ENTRY .fwdarw.
i.sub.-- callq
______________________________________
As indicated previously, the resource manager of the present invention provides functionality substantially beyond simple record or file locking. In particular, the resource manager of the present invention provides a mechanism for shared consensual access to resources at various levels, some of which may coexist. While the different levels might accurately be described as levels of "access", they are conventionally referred to, for historical reasons, as levels of "lock". Accordingly, for purposes of present description, levels of lock should be understood as being essentially synonymous with levels of access. The particular embodiment of the invention described herein provides for six levels of lock. These levels of lock may be described as follows: LM.sub.-- NL--The null level serves as an indicator of interest and a place holder for future lock conversions, with no read or write access granted. Locks are opened at the null level. LM.sub.-- CR--The concurrent read level provides shared read access to the resource, and allows sharing with other readers and concurrent writers. It is generally used for "unprotected" reads which allow simultaneous writes It can also be used in a hierarchical name locking scheme to mark the names on the rooted path to a name being locked for protected read; this keeps the ancestral names from being locked for protected write, while allowing "cousin names to still be locked for protected read or write. In this sort of hierarchical locking scheme, a protected read lock on an ancestral name allows all of its descendants to be read with protection without individually locking each descendant. LM.sub.-- CW--The concurrent write level provides write access to the resource, and allows sharing with other concurrent readers and writers. It is generally used for "unprotected" writes which allow concurrent readers and writers, but no protected readers or writers. It can also be used in a hierarchical name locking scheme to mark the names on the rooted path to a name being locked for protected write; this keeps the ancestral names from being locked for protected read or write, while allowing "cousin" names to still be locked for protected read or write. In this sort of hierarchical locking scheme, a protected write lock on an ancestral name allows all of its descendants to be written with protection without individually locking each descendant. LM.sub.-- PR--The protected read level provides a traditional shared read lock, allowing other readers but no writers. LM.sub.-- PW--The protected write level provides a traditional write update lock, allowing concurrent readers, but no protected readers and no other writers. LM.sub.-- EX--The exclusive level provides a traditional exclusive lock with write access, allowing no other readers or writers. A lock is initially opened by lm.sub.-- open at LM.sub.-- NL, and the level can be changed using the lm.sub.-- convert function. In general, a resource can be locked at several levels at once. The following table summarizes the compatibility of the various lock levels. When a resource is already locked by some process at the "held" level, an attempt to get at the "get" level does the following:
__________________________________________________________________________
held get .fwdarw.
LM.sub.-- NL
LM.sub.-- CR
LM.sub.-- CW
LM.sub.-- PR
LM.sub.-- PW
LM.sub.-- EX
__________________________________________________________________________
LM.sub.-- NL
succeeds
succeeds
succeeds
succeeds
succeeds
succeeds
LM.sub.-- CR
succeeds
succeeds
succeeds
succeeds
succeeds
blocks
LM.sub.-- CW
succeeds
succeeds
succeeds
blocks
blocks
blocks
LM.sub.-- PR
succeeds
succeeds
blocks
succeeds
blocks
blocks
LM.sub.-- PW
succeeds
succeeds
blocks
blocks
blocks
blocks
LM.sub.-- EX
succeeds
blocks
blocks
blocks
blocks
blocks
__________________________________________________________________________
While the source code for the preferred embodiment of the computer resource managing method of the present invention, written in the C++programming language, is appended to this specification, the following description of the general mode of operation of the program will convey its essential nature. An application program or constituent process thereof desiring to use a resource under the lock manager initially calls for the opening of a lock by issuing a lm.sub.-- open function call as referenced at 40 in FIG. 2. The resource manager program, upon receiving an lm.sub.-- open call, checks to see that the named memory object exists, as indicated at reference character 41. If the named memory object does not exist, an error code is returned as indicated at step 42. The program also checks to determine if a process object corresponding to the corresponding process already exists at step 45. As noted previously, a process can have locks open on many objects so the needed process object may already exist even though the application program is calling for the opening of a new lock. If the process object does not exist, an error code is returned as indicated at 47. Once the appropriate process object is determined to exist, the manager obtains a lock object from the pool of available lock objects as indicated at step 49. As indicated previously, resources are named and the name of the sought resource is hashed to determine the appropriate entry into the hash table. This step is indicated at reference character 51. As noted previously, each copy of the resource manager program utilizes the same hashing algorithm so that a particular resource name will direct the program to the same portion of the hash table in the same section of memory, irrespective of which node initiated the inquiry. As described previously, each entry in the hash table contains a pointer to a linked list of resource objects whose names hash to that entry. While the number of resource objects corresponding to each entry is preferably small, it will be understood by those skilled in the art that the nature of the hashing process necessarily allows that more than one resource object can exist for any hash table entry. The resources corresponding to each entry are stored as a doubly linked list. The resource manager program scans this list to determine if a resource object corresponding to the unique resource name and request already exists (step 53) and, if it does not, the resource object is created as indicated at step 55. The lock object is initially set at null level (NL) as indicated at step 57. As indicated previously, cooperative application programs establish or set up locks relatively infrequently, e.g. typically only at the start and close respectively of a given process or program thread, but change level of lock frequently so as to minimize the time when a given resource is blocked for access by other processes which may be running essentially simultaneously on either the same or other nodes. With reference to FIG. 3, the procedure for changing lock level is essentially as follows. Initially, the program must scan the queue of granted locks or accesses of the particular resource object to determine the state of accesses or locks already granted. From this information, the program determines whether the change or conversion sought is possible in accordance with table of permitted conversions given previously. If the change is possible, it is made as indicated at step 65. Particularly if the change in level is to a lower level, the possibility of granting pending requests may be changed by the change in level implemented by the current call. Accordingly, the program scans the queue of requested converts corresponding to the particular resource object as indicated at step 67. If any of the requesting locks can be adjusted in status, these changes are made and the callback queue is similarly updated, this being indicated by reference character 69. The callback queue is available to be checked by processes which may have been previously blocked. Such processes may, for example, have been "put to sleep" under the control of their respective application programs but such processes are typically awakened periodically by the operating system so that they can check the status of the condition which caused the blocking. As will be understood by those skilled in the art, processes in multiprocessor environments may be blocked or put to sleep for various reasons, e.g. synchronization in addition to non-availability of resources such as are managed by the method of the present invention. If the desired change in lock level is not possible, the requesting process is entered into the requested queue corresponding to the resource object. As indicated previously, the state of the entry in the requested queue may subsequently be altered by a change in the state of granted locks, e.g. an exclusive level lock may be lowered, and at such time the callback queue will also be changed so that the blocked process continue. If a given change is not possible, a program also updates the call back entries of the corresponding lock and process objects so that the blocked processes are notified of the fact. As described previously, changes in level occur much more frequently than the opening and closing of locks. It is an important aspect of the present invention that the procedure for converting levels as described with reference to FIG. 3 does not require accessing of its corresponding portion of the hash table or obtaining any related data objects. Accordingly, changes in level are performed with relatively little machine time overhead as compared with the opening and closing operations. The process for closing locks is essentially complementary to the process for opening locks and operates to restore the status of the involved data objects. As indicated previously, the source code for one particular embodiment of the resource manager is appended to this specification. The program is written in multiple sections and subroutines and a brief description of each of these is as follows. lockman.h--Contains definitions for public interface functions and interface structure definitions used by code outside the lock manager. This includes definitions of interface functions and their arguments, flags and option structures that can be passed to interface functions status and error code definitions, and status reporting functions and structures. lm.sub.-- face.cxx--Contains the public interface functions called by code outside the lock manager. These interface functions generally do some argument validation and conversion, and then call C++methods on the underlying data objects to do the real work. lmi.hxx--Contains internal definitions of the lock manager data structures and functions. The definitions of all the major internal data structures and methods that operate on them are here. lmi.sub.-- mapmem.cxx--Contains C++methods for the named shared memory object. These are the methods used to attach and detach from a given named shared memory segment. lmi.sub.-- node.cxx--Contains C++methods for the node object. There is a node object for each distinct processor/memory node on which the lock manager is being used. lmi.sub.-- hash.cxx Contains C++methods for the hash table object. There is a hash object in each node, to handle that node's share of the resource name hash table. lmi.sub.-- proc.cxx--Contains C++methods for the process object. Storage for new process objects is kept in free lists on each node, and a new process object is allocated when a process attaches to the lock manager, and freed when it detaches All code that modifies a field of the process object is here. lmi.sub.-- res.cxx--Contains C++methods for the resource object. Allocation and freeing of resources, conversions, and so forth are handled here. This code is also allowed to access fields in the lock object to expedite making changes to other locks when a lock level is changed. lmi.sub.-- lock.cxx Contains C++methods for the lock object. Allocations and freeing of resources and interfaces to other lock operations are handled here. The resource methods are also allowed to work on lock objects, so much of the actual work is done in the resource methods. lmi.sub.-- pool.cxx--Contains C++methods for storage pool and free list management. The node object contains free list pools of storage for new processes, resources, and locks. lmi.sub.-- queue.cxx--Contains C++methods implementing queues as doubly linked lists. Many of the methods provide specialized services for particular queues and entries in queues. lmi.sub.-- sim.cxx--Contains C++methods implementing the simple latches used to protect and synchronize parallel access to data structures. lmi.sub.-- simwait.cxx--Contains functions that help to tune the spin loops used to implement simple latches. realtime.hxx--Contains definitions for 64 bit realtime clock system service that returns current time in microseconds. unsigned64.hxx--Contains C++definitions for unsigned 64 bit data class. lmi.sub.-- unsigned64.c--Contains methods that implement unsigned 64 data class, for unsigned 64 bit arithmetic. This is used in implementing simple latches to measure the passage of real time using a system service that returns a 64 bit time in microseconds. lmi.sub.-- md.c--Contains machine dependent helper functions for the lock manager library. These encapsulate the interface to the operating system services used. lm.sub.-- msg.cxx--Contains functions and declarations related to lock manager status codes and error messages. lm.sub.-- print.cxx--Contains debugging print functions for lock manager status structures. lm.sub.-- prcookie.cxx--Contains the default print function for debugging printout of "cookies". lm.sub.-- prendfun.cxx--Contains the default print function for debugging printout of completion function pointers. lm.sub.-- prnotfun.cxx--Contains the default print function for debugging printout of blocking notify function pointers. lm.sub.-- prvalp.cxx--Contains the default print function for debugging printout of user value buffer pointers. lm.sub.-- rvalue.cxx--Contains the default print function for debugging printout of resource and lock value buffers. lm.sub.-- checkp.cxx--Contains just the initialized global declaration for lm.sub.-- checkp. In view of the foregoing it may be seen that several objects of the present invention are achieved and other advantageous results have been attained. As various changes could be made in the above constructions without departing from the scope of the invention, it should be understood that all matter contained in the above description or shown in the accompanying drawings shall be interpreted as illustrative and not in a limiting sense. ##SPC1##
|
Same subclass Same class Consider this |
||||||||||
