Date: Mon, 08 Jan 2001 00:54:22 +0200 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: "Alain Magloire" Message-Id: <5567-Mon08Jan2001005421+0200-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.6 CC: djgpp-workers AT delorie DOT com In-reply-to: <200101072031.PAA28996@qnx.com> (alain@qnx.com) Subject: Re: valloc and memalign draftu References: <200101072031 DOT PAA28996 AT qnx DOT com> Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > Date: Sun, 7 Jan 2001 15:31:46 -0500 (EST) > From: "Alain Magloire" > > > > > I did not follow the thread but malloc and friends cannot be made > > > async-safe. What you're describing is undefined behaviour or a programming > > > error i.e. calling a none async-safe routine in a signal handler. > > > > malloc isn't documented in DJGPP as non-safe in this context. In DJGPP, > > ?? > Then out of curiosity what context are you refering too. I was referring to the context of a signal handler. We don't say in the library docs that a signal handler cannot call malloc. > > signal handlers are called in the normal user context (unlike on Unix), > > By this do you mean, on many other OS implementations, the signal handler > is run on a separate stack. There are good reasons for doing it this way. Of course, there are good reasons to do that. Except that in DJGPP, these reasons don't exist. > > so the handler and the code it runs is generally allowed to do anything > > that normal C code is allowed to do. > > I'm not sure I follow or understand what make DJGPP so particular. What makes DJGPP special is the way signal-handling machinery is implemented. The DPMI spec doesn't allow to do almost anything from a hardware interrupt handler. So, for example, a SIGINT handler cannot run directly from the keyboard interrupt handler, and SIGALRM cannot be run by the timer tick handler. To overcome this, the interrupt handler invalidates the data selector (by setting its size to 4KB), and then returns. Since all data is allocated above the first 4KB page, the first time the program tries to touch its data or stack, it triggers a CPU exception (a GPF), because it tries to access data outside the segment limit. The execution thread then jumps to the GPF exception handler, installed by the library startup code. This handler notices that the GPF was a fake one, restores the normal data segment limit (safely stashed away in a special variable), and then calls the signal handler after restoring the normal execution environment (segment registers, stack, etc.) that GCC-generated code expects to find. So, by the time the user-defined signal handler's code runs, the program is in a safe state, with all the segment registers set up as they are for normal vanilla C code. It therefore can in principle do anything a vanilla C code can. > If in DJGPP, you guys found a way, to make it possible for malloc() > calls to be reentrant .... great. I don't know if malloc is reentrant. But if it isn't, that should be documented, since I don't think the users should guess. One thing to keep in mind is that signals are sometimes used to implement sophisticated features, such as threading (there are a couple of such packages which work with DJGPP), where threads are run from within a SIGALRM handler. And threads can call malloc.