ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ DB/C Newsletter ³ ³ July 1993 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Editor's Notes The ANSI DATABUS standardization process is moving toward the finish line. At the X3J15 meeting that was held June 27-30 in the offices of Subject, Wills & Company, the final modifications were made to the standard. One substantive change was made - based upon public comment, the RELEASE statement was added to the Standard. In addition, several minor editorial and technical changes were made. The Standard will next be forwarded to X3 for a secondary, 60 day public review period, after which it will be forwarded to ANSI for final approval. The current best estimate is for final approval to occur in February 1994. One of the features that was added to DB/C with release 7.0 was record locking. The first article in this month's newsletter helps to explain some of the intricacies of DB/C record locking. The second article is useful for UNIX users who need to understand their exact memory requirements. Memory is not as critical of a resource in UNIX as it is in MS-DOS, but performance can suffer if you don't have enough of it. DNW Record Locking Record locking is used to limit access to one or more records in a data file. This idea is similar to the FILEPI facility of DATABUS. However, FILEPI causes a file lock that prevents ALL users from accessing the WHOLE FILE. Because FILEPI locks the whole file the FILEPI file lock is expected to be released within a small amount of time (usually much less than one second) so that other users on the system will not be delayed for any noticeable amount of time and without using DISPLAY or KEYIN. This requires that the programmer accomplish all required file tasks within a limited number of instructions. The programmer could not, for example, lock the data file, show a record on the screen, accept keyboard input from the user that changes the record, and then update the record in the file. The process could potentially take minutes (or hours) to complete because the of the user interaction. Some programmers have attempted to get around this problem by using a status field in a record to indicate that the record is being changed by a user. If another user tries to modify the same record, that program would first read the record and then see that the status field is set to 'busy'. The problem with this method is that removing the lock requires the program to write to the record. If the program never unlocks the file, then the record remains locked. If the system crashes, the workstation loses power, or the user aborts the program, then the status field of the record would remain set to 'busy'. The system administrator would then have to detect this situation and clear the status field for every busy record. DB/C record locking gives the programmer that advantages of record locking without the administration problems. If a program is terminated for any reason and has not unlocked its record locks then the record locks are removed automatically. The DB/C record locking facility can be used on a file by file basis. Record locking is enabled for a particular file when the file is opened. There are three sets of record locking attributes that can be set for a file when it is opened. 1. MULTIPLE or SINGLE MULTIPLE is the default. The MULTIPLE option allows several records to be locked simultaneously. SINGLE means that only a single record may be locked by a given user at one time. If another record is locked the first record is then unlocked. SINGLE does not restrict multiple programs from each having different record locks on the file at the same time. 2. LOCKMANUAL or LOCKAUTO LOCKMANUAL is the default. If manual locking is in effect for a file then records must be explicitly locked by the program by using a locking READ verb. Each READ verb in DB/C has an corresponding locking verb. After reading a record with one of the locking READ verbs the record will be locked. The explicit READ locking verbs are READLK, READGPLK, READKGLK, READKPLK, and READKSLK. LOCKAUTO means that any read will cause the record that is read to be locked automatically even if the read is not an explicit locking read. 3. WAIT or NOWAIT WAIT is the default. If a locking read of an already locked record is attempted then the read will suspend DB/C until the record can be locked by the current program. If NOWAIT is specified then a read of an already locked record will complete immediately without reading the record and the LESS flag will be set to signal that the record could not be locked. An example of an open would be as follows: DATAFILE FILE OPEN DATAFILE, "datafile", SINGLE, LOCKAUTO, NOWAIT There are several ways to unlock records that have been locked through the record locking facility of DB/C. Note, however, that a program can only unlock records that it has locked. It cannot unlock a record that another program has locked. 1. The UNLOCK verb will unlock all records in a file that a program has locked. 2. Closing a file will unlock all records in a file that the program has locked. 3. If the SINGLE option was specified on the file's open statement then any record that was locked prior to the new record lock will be unlocked. 4. If the LOCKAUTO option was specified then WRITE or UPDATE of the locked record will unlock that record. FILEPI should not be used on files that are used with record locking. There is a deadlock possibility is this case. The following scenario is an example of how the deadlock could occur: 1. Program 1 issues a record lock on record 4 2. Program 2 issues a FILEPI which includes the data file 3. Program 2 issues a record lock on record 4 and waits for Program 1 to release its record lock. 4. Program 1 attempts to read record 4 through an index file The above example would now be in a deadlock situation. Program 2 is waiting for Program 1 to unlock record 4 from file A. Program 1 is waiting for the FILEPI for Program 2 to expire because reading through an index automatically sets up a FILEPI for the read statement. The FILEPI that Program 2 set will not expire because Program 2 is waiting for Program 1 to unlock record 4. Program 1 will not be able to unlock record 4 because it is waiting for Program 2's FILEPI to expire. When allowing multiple records to be locked by one program case must be taken to avoid deadlock situations. One of the many possible situations where this could occur is demonstrated in the example below. 1. Program 1 issues a record lock on record 4 2. Program 2 issues a record lock on record 5 3. Program 1 issues a record lock on record 5 4. Program 2 issues a record lock on record 4 Now program 1 will be waiting for record 5 and program 2 will wait for record 4. Neither situation will occur because both programs are stuck in a wait state. A final warning - even though you can mix reading the same records in two different programs where one program uses record locking and the other program doesn't, don't do it. It may not work in future releases of DB/C or in certain new operating systems. Memory Requirements under UNIX Several customers have asked for a way to determine how much memory DB/C requires when running on UNIX. Unfortunately the UNIX 'ps' command does not give the user an accurate report of memory usage for a single process. In fact the report from the 'ps' command is very misleading if used to calculate memory usage requirements. The following procedure will give you a rough estimate of actual usage for your DB/C users. 1. Type the following command at the UNIX prompt: size -f dbc The output of the UNIX 'size' utility will look something like: 294840(.text)+43684(.data)+19116(.bss)+17736(.comment)=375376 The numbers will be different for your version of DB/C. 2. CALCULATING TOTAL (.text) MEMORY SHARED BETWEEN ALL DB/C PROCESSES The (.text) value, 294,840 bytes, will be used by the first DB/C process loaded on the UNIX system. Subsequent processes that are started from other terminals will share this information so additional storage will not need to be allocated. 3. CALCULATING BYTES USED PER PROCESS The 294,840 bytes will be allocated only once no matter how many DB/C processes are started. Each process will also use a certain amount of memory. This extra memory is calculated as follows: the (.data) allocation 43684 (*) + the (.bss) allocation + 19116 (*) + shared memory + 8192 (approximately) + video memory + 16384 (approximately) + DBC_MEMALLOC + 524288 (default) ====== 616,664 bytes per DB/C process Therefore, the total amount of memory used by DB/C on a UNIX system would be as follows: 294,840 + (616,664 * number-of-DB/C-users) or (.text size) + (bytes-per-process * number-of-users) ^ from Step 2 ^ from Step 3 (*) NOTE: DB/C uses the fork() system call to create a secondary process to handle KEYIN. This will duplicate the (.data) and (.bss) segments. This memory will be allocated to the DB/C process. However, most UNIX systems use a what is called a Demand Paging scheme that only allocates physical memory when it is used. The extra process does not use this memory, so there is no impact on actual memory usage. 4. The DBC_MEMALLOC variable explained The DBC_MEMALLOC amount is due to the default setting of the environment variable DBC_MEMALLOC. The default value is 512 which stands for 512 K-Bytes. This is the maximum amount of memory that DB/C can use for DB/C internal tables and your programs and LOADMODs. Reducing this amount will save memory but may cause your program to run out of memory. DB/C Class Schedule The next DB/C class is tentatively scheduled for September 1993. It is held in the Oak Brook, Illinois office of Subject, Wills & Company. For more information, contact Judi Tamkevic at (708) 572-0240.