stratton@hpcupt1.HP.COM (Jim Stratton) (09/24/89)
I have two processes doing simultaneous output to the same terminal using the write system call. Assume A does a write of 10 bytes while B does a write of 30 bytes. Can I be assured that A's and B's output will not be inter- mixed? I understand that for pipes, they won't be mixed. How about terminals? -- Jim Stratton hplabs.hp.com!hpcupt1!stratton
spolsky-joel@CS.YALE.EDU (Joel Spolsky) (10/02/89)
In article <-286379999@hpcupt1.HP.COM> stratton@hpcupt1.HP.COM (Jim Stratton) writes: >I have two processes doing simultaneous output to the same terminal using the >write system call. Assume A does a write of 10 bytes while B does a write >of 30 bytes. Can I be assured that A's and B's output will not be inter- >mixed? I understand that for pipes, they won't be mixed. How about terminals? >-- >Jim Stratton hplabs.hp.com!hpcupt1!stratton I think this is safe. A while ago I wrote a little program that runs on a Unix host, and puts the time, date, and warns you if you get mail in the status line of TVI950's or VT100's. This program runs quitely in the background, and every once in a while sends the necessary string to the terminal. Under extensive testing, it never interfered with whatever foreground process was running, even when it had to write a whole 80 character string to the status line every second. The write() commands were preserved atomically. Now, this is on Sun-OS 4.0, it might not work on your system, and I don't know how to "prove" that it always works, but it has for me. +----------------+----------------------------------------------------------+ | Joel Spolsky | bitnet: spolsky@yalecs.bitnet uucp: ...!yale!spolsky | | | internet: spolsky@cs.yale.edu voicenet: 203-436-1538 | +----------------+----------------------------------------------------------+ #include <disclaimer.h>
mark@promark.UUCP (Mark J. DeFilippis) (10/03/89)
In article <1118@cs.yale.edu>, spolsky-joel@CS.YALE.EDU (Joel Spolsky) writes: > I think this is safe. A while ago I wrote a little program that runs > on a Unix host, and puts the time, date, and warns you if you get mail > in the status line of TVI950's or VT100's. > write() commands were preserved atomically. > How about we take this further. The answer to this question is an undocumented feature of write() under Unix. Several Authors note that write() is atomic under Unix and that it is undocumented. One is Marc J. Rochkind in his book _Advanced Unix Programming_, Prentice-Hall. Writes are Atomic, no matter what you are writing to, even terminals. However, if you have two processes writing to the same device simultaneously, you cannot guarantee which one will preceed the other, (assuming no formal communication between the two processes course). -- Adelphi University, Garden City, NY 11530 (516) 663-1170 Department of Mathematics and Computer Science markd@adelphi.UUCP or mark@promark.UUCP UUCP: ...philabs!sbcs!bnlux0!adelphi!markd
chris@mimsy.UUCP (Chris Torek) (10/04/89)
In article <186@promark.UUCP> mark@promark.UUCP (Mark J. DeFilippis) writes: >How about we take this further. The answer to this question is an >undocumented feature of write() under Unix. Several Authors note >that write() is atomic under Unix and that it is undocumented. >One is Marc J. Rochkind in his book _Advanced Unix Programming_, >Prentice-Hall. Writes are Atomic, no matter what you are writing to, >even terminals. Of course, it might be undocumented because it is false. On Berkeley systems (4BSD, at least), writes to character devices are not locked at the syscall level, and hence could be reentered if the driver (cdevsw[].d_write) function sleeps. Tty writes all go through `ttwrite()', which has two ways of sleeping: if the tty output queue is over the `high water' mark, or if the machine runs out of clist blocks. The sleep queues are priority-FIFO, so if two processes sleep for the same reason, the first one wins when a wakeup() happens (since they are sleeping at the same priority). But if one sleeps on lbolt while another is sleeping on outq/high-water-mark (if this condition is even possible), they might wake up in the `wrong' order and intermix output. Anyway, I am not going to try to figure out whether it never happens, just remark that it is at least theoretically possible. `If it ain't documented, don't trust it'. (Of course even if it is documented, you might do well not to trust it anyway.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
clyde@hitech.ht.oz (Clyde Smith-Stubbs) (10/06/89)
From article <186@promark.UUCP>, by mark@promark.UUCP (Mark J. DeFilippis): > In article <1118@cs.yale.edu>, spolsky-joel@CS.YALE.EDU (Joel Spolsky) writes: >> I think this is safe. A while ago I wrote a little program that runs > > How about we take this further. The answer to this question is an > undocumented feature of write() under Unix. Several Authors note > that write() is atomic under Unix and that it is undocumented. Rubbish! Writes to terminals under Unix are not, and have never been, in any way atomic. In many cases they will be atomic, but there is nothing in the structure of the system to guarantee this. It is easy to demonstrate a situation where they are not atomic. Try the following program: (If run on e.g. the memory mapped display of a 386 PC then the writes will be atomic - but on a serial terminal, or anything that uses buffering and interrupts, they will not be). char x[25][61]; main() { char c; int i, j; if(fork()) c = 'A'; else c = '.'; for(i = 0 ; i != 25 ; i++) { for (j = 0 ; j != 60 ; j++) x[i][j] = c; x[i][j] = '\n'; } for(;;) write(1, x, sizeof(x)); } For the explanation, here is the mail I sent to Jim Stratton after his original posting: From clyde Tue Sep 26 14:32:58 1989 To: stratton@hpcupt1.HP.COM Subject: Re: Are terminal writes atomic? stratton@hpcupt1.HP.COM (Jim Stratton): > I have two processes doing simultaneous output to the same terminal using the > write system call. Assume A does a write of 10 bytes while B does a write > of 30 bytes. Can I be assured that A's and B's output will not be inter- > mixed? I understand that for pipes, they won't be mixed. How about terminals? No, you can't assume that. It depends on how much output is going to the terminal. If the terminal output queue reaches the high water mark the current process will be suspended. When the queue drops to the low water mark all processes waiting on that terminal will be woken. Which one gets to write some more output first is indeterminate. ------------------------ Clyde Smith-Stubbs HI-TECH Software, P.O. Box 103, ALDERLEY, QLD, 4051, AUSTRALIA. ACSnet: clyde@hitech.ht.oz INTERNET: clyde@hitech.ht.oz.au PHONE: +61 7 300 5011 UUCP: uunet!hitech.ht.oz.au!clyde FAX: +61 7 300 5246 -- Clyde Smith-Stubbs HI-TECH Software, P.O. Box 103, ALDERLEY, QLD, 4051, AUSTRALIA. INTERNET: clyde@hitech.ht.oz.au PHONE: +61 7 300 5011 UUCP: uunet!hitech.ht.oz.au!clyde FAX: +61 7 300 5246
mark@promark.UUCP (Mark J. DeFilippis) (10/08/89)
In article <19972@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <186@promark.UUCP> mark@promark.UUCP (Mark J. DeFilippis) writes: > >How about we take this further. The answer to this question is an > >undocumented feature of write() under Unix. Several Authors note this > > Of course, it might be undocumented because it is false. > > On Berkeley systems (4BSD, at least), writes to character devices are Indeed I should have qualified my statement, however almost everyone is familiar with Rochkind's _Advanced Unix Programming_ book, and they are aware it is a SYSTEM V book, not a 4BSD Unix book. Under System V, it is a known undocumented item. By undocumented, I mean it was left out of the documentation and under ALL true Unix System V systems, atomic writes at the system call level are guaranteed. Yes, 4BSD is different and causes much grief with which I am familiar with. That is why I am glad that most porting I do is from 4.XBSD to System V, and not the other way around! I assume you don't get out from under 4.XBSD that often huh? -- Adelphi University, Garden City, NY 11530 (516) 663-1170 Department of Mathematics and Computer Science markd@adelphi.UUCP or mark@promark.UUCP UUCP: ...philabs!sbcs!bnlux0!adelphi!markd
cpcahil@virtech.UUCP (Conor P. Cahill) (10/08/89)
In article <191@promark.UUCP>, mark@promark.UUCP (Mark J. DeFilippis) writes: > In article <19972@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > > In article <186@promark.UUCP> mark@promark.UUCP (Mark J. DeFilippis) writes: > > >How about we take this further. The answer to this question is an > > >undocumented feature of write() under Unix. Several Authors note this > > > > Of course, it might be undocumented because it is false. > > > > On Berkeley systems (4BSD, at least), writes to character devices are > > Indeed I should have qualified my statement, however almost everyone is > familiar with Rochkind's _Advanced Unix Programming_ book, and they are > aware it is a SYSTEM V book, not a 4BSD Unix book. > Under System V, it is a known undocumented item. By undocumented, I mean > it was left out of the documentation and under ALL true Unix System V systems, > atomic writes at the system call level are guaranteed. NO THIS IS NOT TRUE. Writes are not atomic. To prove the point I threw the following example program together: #define BUFSIZE 2048 main() { char buffer[BUFSIZE+1]; int i; if( fork() == 0 ) { for(i=0; i < BUFSIZE; i++) buffer[i] = '0'; buffer[i++] = '\n'; write(1,buffer,i); exit(0); } for(i=0; i < BUFSIZE; i++) buffer[i] = '1'; buffer[i++] = '\n'; write(1,buffer,i); exit(0); } On my "true" system V (AT&T System V/386 Release 3.2) this resulted in mixed output. I don't care what someones book says, the real thing says that it is not atomic. Try this on your system and see what you get. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
wgb@tntdev.tnt.COM (William G. Bunton) (10/08/89)
On 7 Oct 89 19:17:44 GMT, mark@promark.UUCP (Mark J. DeFilippis) said: Mark> Summary: I should have qualifed this... Mark> In article <19972@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > In article <186@promark.UUCP> mark@promark.UUCP (Mark J. DeFilippis) writes: > >How about we take this further. The answer to this question is an > >undocumented feature of write() under Unix. Several Authors note this > > Of course, it might be undocumented because it is false. > > On Berkeley systems (4BSD, at least), writes to character devices are Mark> Indeed I should have qualified my statement, however almost Mark> everyone is familiar with Rochkind's _Advanced Unix Programming_ Mark> book, and they are aware it is a SYSTEM V book, not a 4BSD Unix Mark> book. Under System V, it is a known undocumented item. By Mark> undocumented, I mean it was left out of the documentation and Mark> under ALL true Unix System V systems, atomic writes at the Mark> system call level are guaranteed. Yes, 4BSD is different and Mark> causes much grief with which I am familiar with. That is why I Mark> am glad that most porting I do is from 4.XBSD to System V, and Mark> not the other way around! I assume you don't get out from under Mark> 4.XBSD that often huh? But Mark, it isn't true under System V, either. Bach says (Design of the UNIX Operating System) section 10.3.2, page 33: "Output data could also be garbled at a terminal because a writing process may sleep in the middle of a *write* system call while waiting for previous output data to drain from the system. The kernel could schedule other processes that *write* the terminal before the original process is rescheduled. Because of this case, the kernel does *not* guarantee that the contents of the data buffer to be output by a *write* system call appear contiguously on the terminal." Note the emphasis is his, not mine. I think this is why atomic terminal writes are not documented for System V: because they are not guaranteed atomic. Bill -- William G. Bunton wgb@tntdev.tnt.com Tools & Techniques, Inc. Austin, TX {cs.utexas.edu,uunet}!tntdev!wgb
mark@promark.UUCP (Mark J. DeFilippis) (10/09/89)
In article <411@hitech.ht.oz>, clyde@hitech.ht.oz (Clyde Smith-Stubbs) writes: > From article <186@promark.UUCP>, by mark@promark.UUCP (Mark J. DeFilippis): > > In article <1118@cs.yale.edu>, spolsky-joel@CS.YALE.EDU (Joel Spolsky) writes: > >> I think this is safe. A while ago I wrote a little program that runs > > > > How about we take this further. The answer to this question is an > > undocumented feature of write() under Unix. Several Authors note > > that write() is atomic under Unix and that it is undocumented. > > Rubbish! Writes to terminals under Unix are not, and have never been, > in any way atomic. In many cases they will be atomic, but there > is nothing in the structure of the system to guarantee this. It is easy > [program followed] Sorry, Under my Unix system V, and my Xenix system as well as SCO UNIX system V, your program yeilds atomic writes. However, this is a coeincidence. Someone else provided a program 3 articles after yours which woke me up. Plus my boss said to me, "Mark, where is your mind? Remember that application you wrote 3 months ago and the semaphores you had to use to control simulatneous access by multiple writes?" I went back to the Rochkind book I mentioned, which I should have done in the first place, to see where my neural net got it's cross circuit. He states: "It is presumably a goal of the /usr/group standards effort to document important properties like the atomicity of creat, open, and write, But their proposed standard does not do so. If this omission is deliberate - that is, a conforming implimentation does _not_ have to ensure that these systems calls are atomic, then the standard is seriously defective." This is a footnote in the book when discussing "The Unix manual fails to state that writes to files opened with O_APPEND are atomic." However vendors are only bound by the manual for their implimentation. "Whats worse, even a system that doesn't force open and write to be atomic will still act that way 99 percent of the time, making the bug maddeningly elusive." A totally different story. Sorry about the confusion, and thanks to those whose minds were on guard for setting me straight. I should have known this stuff anyway, since I have had to impliment semaphores for exactly this reason in the past. Sometimes the mind wanders, thats one of the reasons why we have auto accidents... Again, my apologies -- Adelphi University, Garden City, NY 11530 (516) 663-1170 Department of Mathematics and Computer Science markd@adelphi.UUCP or mark@promark.UUCP UUCP: ...philabs!sbcs!bnlux0!adelphi!markd
guy@auspex.auspex.com (Guy Harris) (10/10/89)
>Indeed I should have qualified my statement, however almost everyone is >familiar with Rochkind's _Advanced Unix Programming_ book, and they are >aware it is a SYSTEM V book, not a 4BSD Unix book. >Under System V, it is a known undocumented item. By undocumented, I mean >it was left out of the documentation and under ALL true Unix System V systems, >atomic writes at the system call level are guaranteed. And you believe that, in fact, *terminal* writes are atomic on S5? I don't - and I've checked the S5R3 code. While S5 *does*, in fact, lock the inode on "read"s and "write"s in some cases - as does 4.3BSD, in fact - neither of them do so if the file is a character special file, which terminals are. Chris Torek's scenario appears to apply to S5 as well.