hasiuk@trwspp.UUCP (10/13/84)
We are about to write an application which has multiple processes all updating a database stored on a raw disk partition. Realizing that this requires locking, we would like to implement something along the lines of a system call which prevents switching processes during critical sections of code. A glance at the sources would seem to point to making the changes in swtch(), perhaps such that it doesn't do anything while a flag is set other than return to the interrupted process. Another call would clear the flag and immediately allow another process to run, once the sensitive code decides that it has used the cpu enough and it is safe to switch to another process. Has anyone out there ever tried something like this before? Are there potential problems with resource monitoring preventing such exclusive use of the cpu? Is it possible to continue to make system calls while running in this state, and not relinquish the cpu to another process? What I would really like is a suggestion for an elegant way to accomplish this. By the way, we are running 4.2 on a Sun with source code support. Please mail responses directly to me. Thanks in advance. Lee Hasiuk {decvax,ucbvax}!trwrb!trwspp!hasiuk
geoff@desint.UUCP (Geoff Kuenning) (10/13/84)
I think that a system call to prevent process switching is probably not the right way to go. You will run into a number of problems, the biggest of which is that you are violating a fundamental assumption of the design of the operating system (i.e., that it can switch processes when it wants to). It is impossible (at least for me) to predict where Unix would object, but I sure wouldn't be surprised if your first attempt failed miserably and mysteriously. What is wrong with the famous "locking" (or "lockf") system call, which locks access to a particular area of disk? I even think it's on 4.2bsd. If not, here's an outline of an implementation: struct locktab {you-figure-this-part-out} locktab[NLOCK]; locking () { <convert user's byte range into a device and absolute disk byte range(s)> while (1) { <search locktab to see if that range is locked> if (locked) sleep (&locktab_entry); else break; } <make new locktab entry to mark byte range as locked> } unlock () { <remove locktab entry> wakeup (&locktab_entry); } Since this is implemented in the kernel, it is clean and simple. It also has the advantage that it does not lock out the whole world when there are probably only a few processes that are likely to be a problem (do you really want to shut off uucp and the print spooler while you access those bytes?). And a runaway process won't grab the CPU so it can't be killed. Fleshing this code out is simple if you are a kernel guru. If you are not, you really don't have any business mucking with swtch() anyway. -- Geoff Kuenning First Systems Corporation ...!ihnp4!trwrb!desint!geoff
chris@umcp-cs.UUCP (Chris Torek) (10/17/84)
Note, however, that implementing arbitrary mandatory locking is not
a good idea as anyone can then write something like this:
#include <signal.h>
main() {
int fd, i;
for (i = 0; i < 31; i++)
(void) signal(i, SIG_IGN);
fd = open("/etc/passwd", 0);
lockf(fd, -1); /* lock it to EOF */
pause(); /* or, for(;;); is even more malicious */
}
If there are no system administrators already logged in you may
have to halt the machine from the console.
There are numerous ways around this, the easiest probably being to
use advisory locks rather than mandatory locks.
--
(This mind accidently left blank.)
In-Real-Life: Chris Torek, Univ of MD Comp Sci (301) 454-7690
UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@maryland