From news.daimi.aau.dk!news.uni-c.dk!sunic!trane.uninett.no!nac.no!ifi.uio.no!sics.se!eua.ericsson.se!cnn.exu.ericsson.se!convex!cs.utexas.edu!howland.reston.ans.net!swrinde!pipex!uunet!allegra!alice!dmr Thu Feb 2 14:28:42 1995 Newsgroups: alt.folklore.computers Path: news.daimi.aau.dk!news.uni-c.dk!sunic!trane.uninett.no!nac.no!ifi.uio.no!sics.se!eua.ericsson.se!cnn.exu.ericsson.se!convex!cs.utexas.edu!howland.reston.ans.net!swrinde!pipex!uunet!allegra!alice!dmr From: dmr@research.att.com (Dennis Ritchie <7549-15328> 0112710) Subject: Re: Hackerdom and the Real World Message-ID: Organization: AT&T Bell Labs, Murray Hill, NJ Date: Mon, 30 Jan 1995 04:22:28 GMT Lines: 78 Here is the relevant code surrounding the infamous comment. It's around line 325 of /usr/sys/ken/slp.c in v6 Unix. The comment beginning "If the process paused..." is correct. However, the specification and behavior of savu and retu/aretu in v6 were not well designed, and turned out to be unimplementable with slightly different arrangements of the stack frame from that used on the PDP-11. Savu() saved the stack context of its caller in a place. Retu() and aretu() restored this stack context. (The difference between the routines had to do with whether one was or was not actually changing to another process's stack). Thus--to restate the comment below--once either retu() or aretu() has been executed, the code is actually borrowing the stack frame of the function that called savu(); and the return from the routine that executes retu/aretu is actually a return to the caller of savu(). Besides being confusing, this can't always be made to work. The problem is that the actual machine code executed as the return sequence (say from swtch() in the quoted sample) might not be appropriate--it might restore the wrong registers, for example. The comment reflects a certain struggle to explain, and wasn't intended to be flip. It was more like, `this won't be on the exam.' Later, when Steve Johnson and I moved things to another machine and another compiler, we changed the primitives, to a mechanism (save/resume) more like standard C's setjmp/longjmp. Dennis Code follows: swtch() { ... [find a process to run next ] /* * Switch to stack of the new process and set up * his segmentation registers. */ retu(rp->p_addr); sureg(); /* * If the new process paused because it was * swapped out, set the stack level to the last call * to savu(u_ssav). This means that the return * which is executed immediately after the call to aretu * actually returns from the last routine which did * the savu. * * You are not expected to understand this. */ if(rp->p_flag&SSWAP) { rp->p_flag =& ~SSWAP; aretu(u.u_ssav); } /* * The value returned here has many subtle implications. * See the newproc comments. */ return(1); } /* * Create a new process-- the internal version of * sys fork. * It returns 1 in the new process. * How this happens is rather hard to understand. * The essential fact is that the new process is created * in such a way that appears to have started executing * in the same call to newproc as the parent; * but in fact the code that runs is that of swtch. * The subtle implication of the returned value of swtch * (see above) is that this is the value that newproc's * caller in the new process sees. */ newproc() { ....