> From: Random832
> You could return the address of the last character read, and let the
> user code do the math.
Yes, but that's still 'design the system call to work with interrupted and
re-started system calls'.
> If the terminal is in raw/cbreak mode, the user code must handle a
> "partial" read anyway, so returning five bytes is fine.
As in, if a software interrupt happens after 5 characters are read in, just
terminate the read() call and have it return 5? Yeah, I suppose that would
work.
> If it's in canonical mode, the system call does not copy characters into
> the user buffer until they have pressed enter.
I didn't remember that; that TTY code makes my head hurt! I've had to read it
(to add 8-bit input and output), but I can't remember all the complicated
details unless I'm looking at it!
> Maybe there's some other case other than reading from a terminal that it
> makes sense for, but I couldn't think of any while writing this post.
As the Bawden paper points out, probably a better example is _output_ to a
slow device, such as a console. If the thing has already printed 5 characters,
you can't ask for them back! :-)
So one can neither i) roll the system call back to make it look like it hasn't
started yet (as one could do, with input, by stuffing the characters back into
the input buffer with kernel ungetc()), or ii) wait for it to complete (since
that will delay delivery of the software interrupt). One can only interrupt
the call (and show that it didn't complete, i.e. an error), or have
re-startability (i.e. argument modification).
Noel
> From: Paul Ruizendaal
> There's an odd comment in V6, in tty.c, just above ttread():
> ...
> That comment is strange, because it does not describe what the code
> does.
I can't actually find anyplace where the PC is backed up (except on a
segmentation fault, when extending the stack)?
So I suspect that the comment is a tombstone; it refers to what the code did
at one point, but no longer does.
> The comment isn't there in V5 or V7.
Which is consistent with it documenting a temporary state of affairs...
> I wonder if there is a link to the famous Gabriel paper
I suspect so. Perhaps they tried backing up the PC (in the case where a system
call is interrupted by a software interrupt in the user's process), and
decided it was too much work to do it 'right' in all instances, and punted.
The whole question of how to handle software interrupts while a process is
waiting on some event, while in the kernel, is non-trivial, especially in
systems which use the now-universal approach of i) writing in a higher-level
stack oriented language, and ii) 'suspending' with a sub-routine call chain on
the kernel stack.
Unix (at least, in V6 - I'm not familiar with the others) just trashes the
whole call stack (via the qsav thing), and uses the intflg mechanism to notify
the user that a system call was aborted. But on systems with e.g. locks, it
can get pretty complicated (try Googling Multics crawl-out). Many PhD theses
have looked at these issues...
> Actually, research Unix does save the complete state of a process and
> could back up the PC. The reason that it doesn't work is in the syscall
> API design, using registers to pass values etc. If all values were
> passed on the stack it would work.
Sorry, I don't follow this?
The problem with 'backing up the PC' is that you 'sort of' have to restore the
arguments to the state they were in at the time the system call was first
made. This is actually easier if the arguments are in registers.
I said 'sort of' because the hard issue is that there are system calls (like
terminal I/O) where the system call is potentially already partially executed
(e.g. a read asking for 10 characters from the user's console may have
already gotten 5, and stored them in the user's buffer), so you can't just
simply completely 'back out' the call (i.e. restore the arguments to what they
were, and expect the system call to execute 'correctly' if retried - in the
example, those 5 characters would be lost).
Instead, you have to modify the arguments so that the re-tried call takes up
where it left off - in the example above, tries to read 5 characters, starting
5 bytes into the buffer). The hard part is that the return value (of the
number of characters actually read) has to count the 5 already read! Without
the proper design of the system call interface, this can be hard - how does
the system distinguish between the _first_ attempt at a system call (in which
the 'already done' count is 0), and a _later_ attempt? If the user passes in
the 'already done' count, it's pretty straightforward - otherwise, not so
much!
Alan Bawden wrote a good paper about PCLSR'ing which explores some of these
issues.
Noel
There's an odd comment in V6, in tty.c, just above ttread():
/*
* Called from device's read routine after it has
* calculated the tty-structure given as argument.
* The pc is backed up for the duration of this call.
* In case of a caught interrupt, an RTI will re-execute.
*/
That comment is strange, because it does not describe what the code does. The comment isn't there in V5 or V7.
I wonder if there is a link to the famous Gabriel paper about "worse is better" (http://dreamsongs.com/RiseOfWorseIsBetter.html) In arguing its points, the paper includes this story:
---
Two famous people, one from MIT and another from Berkeley (but working on Unix) once met to discuss operating system issues. The person from MIT was knowledgeable about ITS (the MIT AI Lab operating system) and had been reading the Unix sources. He was interested in how Unix solved the PC loser-ing problem. The PC loser-ing problem occurs when a user program invokes a system routine to perform a lengthy operation that might have significant state, such as IO buffers. If an interrupt occurs during the operation, the state of the user program must be saved. Because the invocation of the system routine is usually a single instruction, the PC of the user program does not adequately capture the state of the process. The system routine must either back out or press forward. The right thing is to back out and restore the user program PC to the instruction that invoked the system routine so that resumption of the user program after the interrupt, for example, re-enters the system routine. It is called PC loser-ing because the PC is being coerced into loser mode, where loser is the affectionate name for user at MIT.
The MIT guy did not see any code that handled this case and asked the New Jersey guy how the problem was handled. The New Jersey guy said that the Unix folks were aware of the problem, but the solution was for the system routine to always finish, but sometimes an error code would be returned that signaled that the system routine had failed to complete its action. A correct user program, then, had to check the error code to determine whether to simply try the system routine again. The MIT guy did not like this solution because it was not the right thing.
The New Jersey guy said that the Unix solution was right because the design philosophy of Unix was simplicity and that the right thing was too complex. Besides, programmers could easily insert this extra test and loop. The MIT guy pointed out that the implementation was simple but the interface to the functionality was complex. The New Jersey guy said that the right tradeoff has been selected in Unix -- namely, implementation simplicity was more important than interface simplicity.
---
Actually, research Unix does save the complete state of a process and could back up the PC. The reason that it doesn't work is in the syscall API design, using registers to pass values etc. If all values were passed on the stack it would work. As to whether it is the right thing to be stuck in a read() call waiting for terminal input after a signal was received...
I always thought that this story was entirely fictional, but now I wonder. The Unix guru referred to could be Ken Thompson (note how he is first referred to as "from Berkeley but working on Unix" and then as "the New Jersey guy").
Who can tell me more about this? Any of the old hands?
Paul
> From: Lars Brinkhoff
> Nick Downing <downing.nick(a)gmail.com> writes:
>> By contrast the MIT guy probably was working with a much smaller/more
>> economical system that didn't maintain a kernel stack per process.
I'm not sure I'd call ITS 'smaller'... :-)
> PCLSRing is a feature of MIT' ITS operating system, and it does have a
> separate stack for the kernel.
I wasn't sure if there was a separate kernel stack for each process; I checked
the ITS source, and there is indeed a separate stack per process. There are
also three other stacks in the kernel that are used from time to time (look
for 'MOVE P,' for places where the SP is loaded).
Oddly enough, it doesn't seem to ever _save_ the SP - there are no 'MOVEM P,'
instructions that I could find!
Noel
On page 3 of the Research Unix reader (http://www.cs.dartmouth.edu/~doug/reader.pdf)
"Sandy (A. G.) Fraser devised the Spider local-area ring (v6) and the Datakit switch (v7) that have served in the lab for over a decade. Special services on Spider included a central network file store, nfs, and a communication package, ufs."
I do not recall ever seeing any SPIDER related code in the public V6 source tree. Was it ever released outside Bell Labs?
From a bit of Googling I understand that SPIDER was a ATDM ring network with a supervisor allocating virtual circuits. Apparently there was only ever one SPIDER loop with 11 hosts connected, although Fraser reportedly intended to create multiple connected loops as part of his research.
The papers that Fraser wrote are hard to find: lots of citations, but no copies, not even behind pay walls. The base report seems to be:
A. G. FRASER, " SPIDER-a data communication experiment", Tech Report 23 , Bell Lab, 1974.
Is that tech report available online somewhere?
Tanks!
Paul
> we just read the second tape, which read without error. ... at this
> point we have access to everything that was on that machine.
OK, we're starting to get through all the clearances needed to release the
non-MIT Unix systems on the machine. (The MIT one is going to take more
work - I have to curate out all the personal files.)
We have now completed the OK's for the 'Network Unix' (the one done at the
University of Illinois for use on the ARPANET, with NCP). A tarball is
available here:
http://ana-3.lcs.mit.edu/~jnc/tech/pdp11/tmp/nosc.tar
(It's called 'nosc.tar' because it came through NOSC, and then SRI,
on the way to MIT.)
In addition to all the UIllinois code, it also contains early versions of the
MH mail reader (from Rand) and the MMDF mailer (from UDel).
Enjoy!
Noel
With no offense intended, I can't help noting the irony of the
following paragraph appearing in a message in the company of
others that address Unix "bloat".
>'\cX' A mechanism that allows usage of the non-printable
> (ASCII and compatible) control codes 0 to 31: to cre-
> ate the printable representation of a control code the
> numeric value 64 is added, and the resulting ASCII
> character set code point is then printed, e.g., BEL is
> '7 + 64 = 71 = G'. Whereas historically circumflex
> notation has often been used for visualization pur-
> poses of control codes, e.g., '^G', the reverse
> solidus notation has been standardized: '\cG'. Some
> control codes also have standardized (ISO 10646, ISO
> C) alias representations, as shown above (e.g., '\a',
> '\n', '\t'): whenever such an alias exists S-nail will
> use it for display purposes. The control code NUL
> ('\c@') ends argument processing without producing
> further output.
Except for the ISO citations, this paragraph says the same
thing more succinctly.
'\cX' represents a nonprintable character Y in terms of the
printable character X whose binary code is obtained
by adding 0x40 (decimal 64) to that for Y. (In some
historical contexts, '^' plays the role of '\c'.)
Alternative standard representations for certain
nonprinting characters, e.g. '\a', '\n', '\t' above,
are preferred by S-nail. '\c@' (NUL) serves as a
string terminator regardless of following characters.
And this version, 1/3 the length of the original, tells all
one really needs to know.
'\cX' represents a nonprintable character Y in terms of the
printable character X whose binary code is obtained
by adding 0x40 (decimal 64) to that for Y. '\c@'
(NUL) serves as a string terminator regardless of
following characters.
Doug]
On 2017-02-09 20:55, corey(a)lod.com (Corey Lindsly) wrote:
>
>> In spite of that, I'm typing away to you all, I'm 3ms away from 8.8.8.8
>> (Google's dns server). Go wireless. It's pretty remarkable to be here
>> and have decent net connectivity.
>>
>> I do not yearn for the days of SLIP.
>> --
>> ---
>> Larry McVoy lm at mcvoy.comhttp://www.mcvoy.com/lm
> 3ms? Really? I'm impressed, and I'd like to see your traceroute. We peer
> directly with Google and I get 4-5ms. Do share.
Meh. From Uppsala in Sweden I seem to have about 2ms ping time to 8.8.8.8...
Psilocybe:update/bqt> ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_req=1 ttl=56 time=2.10 ms
64 bytes from 8.8.8.8: icmp_req=2 ttl=56 time=1.93 ms
64 bytes from 8.8.8.8: icmp_req=3 ttl=56 time=2.05 ms
64 bytes from 8.8.8.8: icmp_req=4 ttl=56 time=1.89 ms
64 bytes from 8.8.8.8: icmp_req=5 ttl=56 time=2.02 ms
64 bytes from 8.8.8.8: icmp_req=6 ttl=56 time=2.05 ms
64 bytes from 8.8.8.8: icmp_req=7 ttl=56 time=2.00 ms
64 bytes from 8.8.8.8: icmp_req=8 ttl=56 time=1.97 ms
64 bytes from 8.8.8.8: icmp_req=9 ttl=56 time=2.03 ms
64 bytes from 8.8.8.8: icmp_req=10 ttl=56 time=2.10 ms
^C
--- 8.8.8.8 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9011ms
rtt min/avg/max/mdev = 1.894/2.020/2.108/0.067 ms
Psilocybe:update/bqt> traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
1 r1.n.it.uu.se (130.238.19.254) 1.986 ms 2.324 ms 2.717 ms
2 l-uu-1-b1.uu.se (130.238.6.251) 0.288 ms 0.680 ms 0.646 ms
3 uu-r1.sunet.se (130.242.6.148) 0.686 ms 0.685 ms 0.673 ms
4 uppsala-upa-r1.sunet.se (130.242.4.138) 0.672 ms 0.661 ms 0.657 ms
5 stockholm-fre-r1.sunet.se (130.242.4.26) 3.503 ms 3.468 ms 3.483 ms
6 se-fre.nordu.net (109.105.102.9) 24.456 ms 24.532 ms 24.153 ms
7 se-kst2.nordu.net (109.105.97.27) 1.934 ms 1.902 ms 1.891 ms
8 as15169-te-tc1.sthix.net (192.121.80.47) 2.204 ms 2.189 ms
72.14.196.42 (72.14.196.42) 1.872 ms
9 216.239.40.29 (216.239.40.29) 1.862 ms 1.941 ms 216.239.40.27
(216.239.40.27) 1.995 ms
10 209.85.251.233 (209.85.251.233) 2.398 ms 209.85.245.61
(209.85.245.61) 2.778 ms 72.14.234.85 (72.14.234.85) 2.385 ms
11 google-public-dns-a.google.com (8.8.8.8) 2.372 ms 2.366 ms 2.337 ms
Johnny
--
Johnny Billquist || "I'm on a bus
|| on a psychedelic trip
email: bqt(a)softjar.se || Reading murder books
pdp is alive! || tryin' to stay hip" - B. Idol
> Lots of commands are now little shells
...
> Linux today is much more like the systems
> Unix displaced than it is like Unix
So depressingly true!
Doug