Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.glorb.com!peer02.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news.iecc.com!.POSTED!nerds-end From: Kaz Kylheku Newsgroups: comp.compilers Subject: Re: Question about inter-thread stack references Date: Sun, 18 Jan 2015 17:12:30 +0000 (UTC) Organization: Aioe.org NNTP Server Lines: 80 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <15-01-030@comp.compilers> References: <15-01-015@comp.compilers> NNTP-Posting-Host: news.iecc.com X-Trace: miucha.iecc.com 1421608187 18983 2001:470:1f07:1126:0:676f:7373:6970 (18 Jan 2015 19:09:47 GMT) X-Complaints-To: abuse@iecc.com NNTP-Posting-Date: Sun, 18 Jan 2015 19:09:47 +0000 (UTC) Keywords: architecture, parallel Posted-Date: 18 Jan 2015 14:09:47 EST X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com X-Received-Bytes: 4574 X-Received-Body-CRC: 1502322162 Xref: csiph.com comp.compilers:1487 On 2015-01-16, Ivan Godard wrote: > If a process has two or more threads running in it, what are the rules > regarding one thread referencing memory in a different thread's stack? In what system? In all the systems I'm familiar with, threads run in one address space, and accessing all valid objects is fair game regardless of their storage class or thread affiliation. If we are talking in C terms, then if in some thread, the following block is executing: { some_type_t x; ... } then while that block continues to execute, the object x is valid. Anything in the address space which has a pointer to the object can use that object. When the block terminates, then the pointer becomes indeterminate. Secondly, if this x is accessed by multiple threads, then the usual concurrency considerations apply. Unless x is some atomically accessed type, you need some kind of mutex, and so forth. Consider that this sort of stack access is absolutely essential in various kinds of core multithreading API's. For instance, send a message to another thread and wait for a reply: message_type_t request, reply; request_fill(&request, ...); if (send_message(other_thread, &request, &reply) == SEND_OKAY) { /* process reply */ } How this fictitious API works is that the request and reply objects (local to the thread, on its stack) are registered into some global message-queuing data structure. The thread which calls send_message is then blocked. Because it is blocked, those objects remain valid: the suspension prevents it from terminating the statement block. While the sender is blocked, the other thread can access the request, and fill in the reply. Then when the sender is unblocked, everything is cool: it finds the repy. The suspend and resume discipline also ensures proper synchronization. The send_message thread does not access the reply prior to the reply being produced, and the receiver of course won't access the request before that is enqueued and the sender thread is being put to sleep. > In the usual way that paging hardware works both stacks can be made > visible to both threads, but interstack visibility could also be > prevented (assuming that stacks occupied whole pages). How paging hardware works is that preventing inter-stack visibility using paging would be so expensive, that it would be making a mockery of the concept of threading. The processor would have to swap page tables and flush translation caches when switching thread contexts. Some special support for protecting stacks could make it possible. For instance stacks could be segments, and segments could have some security word in their descriptor which is cheaply checked against the current security descriptor of the current thread. > I vaguely (so vague that I can't find citations) remember that on some, > possibly legacy, hardware it was physically impossible to do > inter-thread stack accesses; stacks were strictly per-thread and > private. I also vaguely recall that some languages (or thread packages) > banned the practice even if it were physically possible. Could be, but that's a pretty dumb approach which is why those systems ended up as legacy. Well, it's not a dumb approach, but it's just not threading, really. One way to emulate that scenario is simply to use multiple processes (e.g. with fork() on Unix), and use explicit memory sharing (mmap, SysV) to have a global area which is common, and mapped to exactly the same address in every process, too. Then you have private stacks.