Multics Technical Bulletin MTB-557 Rev. 1 DM: Lock Manager Functional Spec To: Distribution From: R. Michael Tague Date: 04/03/84 Subject: Data Management: Lock Manager Functional Specification 1 ABSTRACT This document describes the functions provided by the Lock Manager. For each of these functions, a description of the services provided by the function and the user interface to the function is given. This revision describes several new lock manager functions to facilitate initialization, metering, copying the lock manager data base, and concurrency control of the lock manager data base. Send comments on this MTB by one of the following means: By Multics Mail, on MIT or System M: Tague.Multics By Telephone: HVN 261-9358 or (617)-492-9358 _________________________________________________________________ Multics project internal working documentation. Not to be reproduced or distributed outside the Multics project without the consent of the author or the author's management. CONTENTS Page 1 Abstract . . . . . . . . . . . . . . i 2 Introduction . . . . . . . . . . . . 1 3 Summary of changes for Revision 1 . 1 4 Locking Characteristics . . . . . . 2 Locking Objects . . . . . . . . . . 2 Locking Modes . . . . . . . . . . . 2 Lock Identifier . . . . . . . . . . 4 Fast Locks . . . . . . . . . . . . 4 lock_manager_ . . . . . . . . . . . 6 Fast Locks . . . . . . . . . . . 6 Data management locks . . . . . 6 Lock modes . . . . . . . . . . . 6 The lock hierarchy . . . . . . . 7 Lock mode names . . . . . . . . 7 Deadlock detection . . . . . . . 8 Locking and Transactions . . . . 8 $lock . . . . . . . . . . . . . 9 $unlock_all . . . . . . . . . . 11 $unlock . . . . . . . . . . . . 12 $init_per_system . . . . . . . . 13 $reset_system_meters . . . . . . 14 $lock_lock_data . . . . . . . . 15 $unlock_lock_data . . . . . . . 16 $system_segment_count . . . . . 17 $copy_data . . . . . . . . . . . 18 The lm_copy_data structure . . . 18 $lock_fast . . . . . . . . . . . 20 $unlock_fast . . . . . . . . . . 21 Multics Technical Bulletin MTB-557 Rev. 1 DM: Lock Manager Functional Spec 2 INTRODUCTION The purpose of Lock Management within the Data Management Architecture is to provide concurrency protection for access to data base objects (files and records within files). This document contains a detailed functional description of Lock Management, as viewed by a user of Lock Management. A user in | this context is not an end user, but other subsystems of the Data | Management Architecture. This document contains a description of all externally available entries into Lock Management. For each entry, a complete description of the calling sequence is given, along with additional information required for a user to make proper use of the entry. 3 SUMMARY OF CHANGES FOR REVISION 1 | An entry point has been added for initialization: | o init_per_system | Two entry points have been added to facilitate copying the lock | manager data base: | o system_segment_count | o copy_data | A pair of entry points have been added to fast lock the lock | manager data base: | o lock_lock_data | o unlock_lock_data | One entry point for reseting system meters on lock manager was | added: | o reset_system_meters | Three entrypoints were not needed, so they have been removed: | o cleanup_process | o priv_clean_up_process | o init_fast_lock | Three entrypoints remain unimplemented, and have been removed | from the revised MTB: | MTB-557 Rev. 1 Multics Technical Bulletin DM: Lock Manager Functional Spec | o checkpoint | o unlock_to_checkpoint | o resolve_deadlock | A reference to Container Access Layer was removed and all | occurences of "page file" were changed to "file". | 4 LOCKING CHARACTERISTICS | Locking Objects | A data base is implemented as a set of files. Each file consists | of a number of physical records of the same size called control | intervals. Logical records in the data base are stored in one or more control intervals, and a given control interval may contain more than one logical record. | Two types of objects may be locked - control intervals and files. | Any lock held on a file applies by implication to all control | intervals in the file. Locking Modes | A lock may be held in either of the modes: o S - Share o X - Exclusive | Additionally locks on files may be held in one of the following | modes: o IS - Intend Share o IX - Intend Exclusive o SIX - Share with Intend Exclusive To ensure concurrency protection, a user of Lock Management must adhere to the following conventions: | Before reading a control interval, the user must lock the | control interval or the file containing the control interval | in either share(S) or exclusive(X) mode. Multics Technical Bulletin MTB-557 Rev. 1 DM: Lock Manager Functional Spec Before modifying a control interval, the user must lock the | control interval or the containing file in exclusive(X) | mode. | For most users of Lock Management, only share(S) and exclusive(X) | modes are relevant. The remaining file lock modes are used | internally by Lock Management to indicate the type of locks that | are held on control intervals within the file. When Lock | Management intends to acquire a control interval lock, it first | acquires an intend lock on the file containing the control | interval, and then acquires the actual control interval lock, | hence the intend name. These additional modes are available for | more sophisticated applications. They have the following | meanings: | IS - The transaction has locked one or more control | intervals in share(S) mode, and no control interval in | exclusive(X) mode. | IX - The transaction has locked at least one control | interval in exclusive(X) mode. | SIX - | The transaction has locked the file in share(S) mode, | and at least one control interval within the file has | been locked is exclusive(X) mode. | For communication with Lock Management, the lock modes are referenced as integers. The correspondence of modes to integer values is described in Attachment 1. MTB-557 Rev. 1 Multics Technical Bulletin DM: Lock Manager Functional Spec Lock Identifier Associated with each object which may be locked is an identifier which is unique within the system. For the user of Lock Management, this identifier is an ordered pair (UID, CI Number), which is interpreted as follows: UID | is the Multics File System unique identifier associated | with the file or with the file to which the control | interval belongs. In the initial implementation of the | Data Management Architecture, a file is a Multics | Multi-Segment File. For the purposes of Lock Management, the unique identifier of a Multi-Segment File is the Multics File System unique identifier of component zero. CI Number | is the relative control interval number within the file | (with 0 representing the first control interval in the | file). For the purposes of Lock Management, control | interval number -1 refers to the file itself, rather than to a specific control interval. Fast Locks Many of the Data Management subsystems require concurrency protection on internal, per-system tables which they maintain. The type of concurrency protection required for these tables is | qualitatively different from that required for user objects | (control intervals or files): Tables need be locked only for predictably short amounts of time. Deadlocks can be avoided, as tables can be locked in predictable sequences. Data in the tables is neither journalized nor recovered. Fast Locks provide this type of concurrency protection. A Fast Lock is a double-word of virtual memory (the lock double-word) which by convention protects a shared table or other shared object. The lock double-word is shared by all processes which require access to the shared object. By convention, a process must obtain a lock on the lock double-word before accessing the shared object. Lock Management supports Fast Locks by providing Multics Technical Bulletin MTB-557 Rev. 1 DM: Lock Manager Functional Spec services to lock and unlock Fast Locks, and to synchronize processes contending for Fast Locks. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Name: lock_manager_ Provides concurrency control for data management internal data bases and data management objects. The lock_manager_ provides two kinds of locking services: fast locks, and data management locks. Fast locks are used to control concurrent access by processes to data management internal databases. Data management locks are used to control concurrent access by transaction to files and control intervals. Few entries in the lock_manager_ may be called by user programs. Most of the entries are only available from within the data management protected ring. Some are available to the data management daemon or other privileged users in the user ring. Those entries that may be called by user programs are concerned with metering and tracing. Fast Locks Fast locks are locks maintained for control of data management internal databases. In the current implementation, fast locks are two word objects. Fast locks are conceptually similiar to the set_lock_ interface, save that they offer improved efficiency. No deadlock detection is done for fast locks. They must be locked and unlocked in accordance with the established hierarchy of locks. Data management locks Data management locks are locks on data management objects. In the current implementation, only files and control intervals within files may be locked. In general, locks on files and control intervals are obtained by the file manager as needed. For example, the file manager will get a share lock whenever a control interval is fetched, and an exclusive lock when it is put. Lock modes Data management locking provides multiple-reader, single writer concurrent access control. A "read lock" is called a Share, or "S" lock. A write lock is called an Exclusive, or "X" lock. Files or control intervals may be locked for is S or X mode. In addition, there are other special modes which may be used for files, as explained below under "Lock hierarchy". An S _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ lock allows other transactions to get S locks, but not X locks. An X lock allows no other transaction to acquire a lock. The lock hierarchy When a control interval is locked, the file it belongs to is implicitly locked as well. For example, it would be inappropriate to allow a transaction to acquire an X lock on a file within which another transaction holds an S lock on a control interval. To avoid having to investigate the possible existence of control interval locks when a file lock is requested, special "Intend" locks are provided for files. Before a transaction may lock a control interval, it must first acquire an appropriate intend lock on the file. The intend lock modes are: "Intend Share (IS)", indicating that one or more control intervals are locked is S mode; "Intend Exclusive (IX)", indicating that one or more control intervals are locked in S or X mode; and "Shared Intend Exclusive (SIX)", indicating that all of the control intervals are to be considered locked in S mode, and that one or more are explicitly locked in X mode. Lock mode names Named constants for the lock modes are provided in the include file dm_lock_modes.incl.pl1 dcl LOCK_MODE_S fixed bin static options (constant) init|(2); dcl LOCK_MODE_X fixed bin static options (constant) init|(3); dcl LOCK_MODE_IS fixed bin static options (constant) init|(4); dcl LOCK_MODE_IX fixed bin static options (constant) init|(5); dcl LOCK_MODE_SIX fixed bin static options (constant) init|(6); dcl LOCK_ENTIRE_FILE fixed bin (24) static options (constant)|init (-1); dcl LOCK_MODE_NAMES (2:6) char (3) int static options (constant)| init ("S", "X", "IS", "IX", "SIX"); | S Share | Let others read it but not modify it. | X Exclusive | Let nobody else read or modify it. | IS Intend Share | I am only using S locks, because I am only reading CIs.| _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ | IX Intend Exclusive | I am using S and X locks, because I am reading and modifying CIs. | SIX Share with Intend Exclusive | I am reading control intervals, but only locking the ones I modify. Deadlock detection The lock_manager_ detects deadlock situations involving data management locks. If a transaction attempts to acquire a lock, and waiting for that lock would result in a deadlock, the youngest transaction involved in the deadlock will have an error reflected to it, so that it can roll back or abort. Locking and Transactions It is important to remember that all locks are held for the duration of the transaction that obtains them. All locks are automatically released when a transaction commits, aborts, rolls back, or is killed. Thus a transaction builds a set of locks accretively; and any given call to lock an object may find that it is already locked with a suitable lock. No error indication is returned in these circumstances, but the actual lock mode held is returned as it may be stronger than the mode requested. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$lock Attempts to acquire a lock on a file or control interval in a given mode. If the transaction already holds a lock on the object that is as least as strong as the desired mode, the that locks is considered sufficient. If a control interval lock is requested through this entry, an appropriate Intend lock on the file will be acquired automatically. Usage dcl lock_manager_$lock entry (bit (36) aligned, fixed bin (24), fixed bin, fixed bin (71), fixed bin, fixed bin (35)); call lock_manager_$lock (file_uid, control_interval, desired_mode, timeout_time, mode_obtained, code); where: file_uid (Input) is the data management Unique Identifier of the file. In the current MSF implementation, this is the UID of the first component of the file MSF. control_interval (Input) is the numeric index of the control interval to be locked. If it is LOCK_ENTIRE_FILE (-1), a lock is obtained on the entire file. desired_mode (Input) is the lock mode required. Lock modes are documented above, and named constants are declared in dm_lock_modes.incl.pl1. timeout_time (Input) is the maximum time, in microseconds, to wait for the lock to be available. If this much time passes before the lock can be acquired, dm_error_$lock_timeout is returned. mode_obtained (Output) is the actual lock mode obtained. If the transaction already held a stronger lock than Desired_Mode, that mode will be returned. For example, if the transaction held an X lock and requested an S lock, _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ LOCK_MODE_X would be returned here. code (Output) will be nonzero if the arguments were not valid or if the lock could not be acquired after waiting for the timeout time. If the Desired_Mode is not a valid mode, dm_error_$lock_invalid_mode is returned. If the timeout time passes and the lock cannot be acquired, dm_error_$lock_timeout is returned. If a deadlock is detected, and the calling transaction has been selected to roll back, dm_error_$lock_deadlock is returned. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$unlock_all unlocks all locks held by a transaction. This entry may be called from other processes than the one in which the transaction was started, to clean up the transaction. However, it still depends on the values of variables in dm_data_ to define the transaction to be cleaned up. Usage dcl lock_manager_$unlock_all entry (); | call lock_manager_$unlock_all (); | where: This entry has no arguments its contract is to unlock all locks, and there are no defined circumstances under which it may fail to do so. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$unlock Unlocks a single data management lock. This entrypoint, while implemented, is NOT YET SUPPORTED FOR USE. It is indended for a future "soft concurrency" service in which transaction would unlock control intervals on which they obtained S locks, or were using concurrency control without integrity control. Usage dcl lock_manager_$unlock entry (bit (36) aligned, fixed bin (24), fixed bin (35)); call lock_manager_$unlock (file_uid, control_interval, code); where: file_uid (Input) is the unique identifier of the file in question. control_interval (Input) is the control interval index of the control interval in question, or LOCK_ENTIRE_FILE. code (Output) is a standard status code, which should always be zero. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$init_per_system runs per-system initialization for the lock manager for both fast and data management locks. Usage dcl lock_manager_$init_per_system entry (fixed bin (35)); call lock_manager_$init_per_system (code); where: code (Output) is nonzero if initialization fails. Note that sub_err_ is used to provide more illuminating error diagnostics in this case. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ | Entry: lock_manager_$reset_system_meters | resets lock manager system meters to zero. | Usage | dcl lock_manager_$reset_system_meters entry (); | call lock_manager_$reset_system_meters (); _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$lock_lock_data is an internal interface that allows programs within the lock manager to lock its internal databases. Usage dcl lock_manager_$lock_lock_data entry (fixed bin (35)); call lock_manager_$lock_lock_data (code); where: code (Output) is nonzero if an error was returned locking the fast lock on the lock manager's database. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$unlock_lock_data is an internal interface of the lock manager that unlocks its internal database. Usage dcl lock_manager_$unlock_lock_data entry (fixed bin (35)); call lock_manager_$unlock_lock_data (code); where: code (Output) is nonzero if an error was returned unlocking the fast lock on the lock manager's database. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$system_segment_count is a metering interface that returns the number of segments that make up the lock manager's database of data management locks. This entry is used in conjunction with lock_manager_$copy_data to get consistent copies of the database. Usage dcl lock_manager_$system_segment_count entry (fixed bin (35)) returns (fixed bin); segment_count = lock_manager_$system_segment_count (code); where: segment_count (Output) is the number of segments that constitute the database. code (Output) is a standard system status code. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$copy_data makes a consistent copy of the lock manager's database of data management locks into a set of user ring segments. This entry is used by metering and tuning programs. The entry lock_manager_$system_segment_count should be used to get the number of segments required. Since new segments may be created at any time, this entry may return an error code indicating that a larger set of segments is required. It still copies as many segments as it can, however. Usage dcl lock_manager_$copy_data entry (pointer, fixed bin (35)); call lock_manager_$copy_data (copy_info_ptr, code); where: copy_info_ptr (Input) is a pointer to the lm_copy_data structure, described below, and found in dm_lm_copy_data.incl.pl1. code (Output) is a standard system status code. If it is error_table_$smallarg, not enough segments were provided. copy_data.n_segments is set to the correct number. The lm_copy_data structure The declaration of the lm_copy_data structure follows, and is found in dm_lm_copy_data.incl.pl1. dcl lm_copy_data_ptr pointer; dcl 1 lm_copy_data aligned based (lm_copy_data_ptr), 2 version char (8) aligned, 2 n_system_segments fixed bin, 2 n_segments fixed bin, 2 segment_ptrs (lm_copy_data_n_segments refer (lm_copy_data.n_segments)) ptr; dcl lm_copy_data_n_segments fixed bin; dcl LM_COPY_DATA_VERSION_1 char(8) aligned init ("lmdt0001") int static options (constant); _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ where: version should be set to LM_COPY_DATA_VERSION_1. n_system_segments (Output) is set on output to the number of segments. If there are more system segments than output segments provided, then this variable is still set. n_segments is the number of segments provided by the caller to copy data into. segment_ptrs is an array of pointers to segments into which the data will be copied. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$lock_fast locks a double-word fast lock to the calling process. This entry returns error codes if the lock is already held to the calling process, or if the lock was held by a dead process. Usage dcl lock_manager_$lock_fast entry (pointer, fixed bin (71), fixed bin (35)); call lock_manager_$lock_fast (lock_pointer, timeout_time, code); where: lock_pointer (Input) is a pointer to a double word to be used as a fast lock. timeout_time (Input) is the maximum time to wait for the lock to be available, in microseconds. code (Output) is zero, or one of the following error codes: dm_error_$fast_lock_invalid_reset is returned if the lock was previously held by a daed process. The lock is locked to the calling process in this case. dm_error_$fast_lock_mylock is returned if the process already holds the requested fast lock. dm_error_$fast_lock_timeout is returned if the fast lock could not be locked in the specified time. All fast_lock_mylock and fast_lock_timeout errors are logged in the data management system log. _____________ _____________ lock_manager_ lock_manager_ _____________ _____________ Entry: lock_manager_$unlock_fast Unlocks a fast lock. Usage dcl lock_manager_$unlock_fast entry (pointer, fixed bin (35)); call lock_manager_$unlock_fast (lock_pointer, code); where: lock_pointer (Input) is a pointer to the lock to be unlocked. code (Output) is a standard status code. It will be dm_error_$fast_lock_not_locked if the lock was not locked.