[Gc] Signals / EINTR loop

Manuel.Serrano at sophia.inria.fr Manuel.Serrano at sophia.inria.fr
Wed Aug 6 23:48:40 PDT 2008


Hello Nicolas,

> Sometimes, in a call to recv(), the function returns with -1 and errno 
> is EINTR. This is normal since the GC might have tried to pause the 
> thread when collecting. We are then simply looping in order to restart 
> the recv() again.
> 
> The problem is that after that, each next call to recv() immediatly 
> returns with -1 + EINTR again, so we are entering an infinite loop that 
> takes full CPU (shared between User and System).
> 
> Is it a known problem ? Is there any way to check what's happening there 
> ? Reading in the mailing list archives, I found 
> GC_start_blocking/GC_end_blocking that would be helpful but they do not 
> seems to be available anymore as part of the LibGC 7.1
> 
> PS : other threads are blocked in pthread_cond_wait, in case this might 
> be related to the problem.
> 
> PPS : we had a timeout set on the socket using setsockopt(SO_RCVTIMEO) 
> but removing it doesn't seems to fix the problem.
I have had a similar problem with Bigloo. We are using the Linux sendfile
OS call and this should not be interrupted by the GC. Here is a short
description of the way we have fixed the problem.

First, during configuration, we check if GC_start_blocking/GC_stop_blocking
or GC_do_blocking is available. Then, around any call that *must not* be
interrupted we use a sequence such as:

-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
#if( BGL_GC_HAVE_BLOCKING )
	 GC_start_blocking();

	 n = sendfile( fileno( (FILE *)outp.port.stream ),
		       fileno( (FILE*)inp.port.stream ),
		       (offset > 0 ? (off_t *)(&offset) : 0),
		       sz );
	 
	 GC_stop_blocking();
#else
#  if( BGL_GC_HAVE_DO_BLOCKING )
	 {
	    struct sendfile_info_t si;
	    si.out = fileno( (FILE *)outp.port.stream );
	    si.in = fileno( (FILE *)inp.port.stream );
	    si.offset = (offset > 0 ? (off_t *)(&offset) : 0);
	    si.sz = sz;
	 
	    GC_do_blocking( &gc_sendfile, &si );

	    n = si.res;
	 }
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----

-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
static void
gc_sendfile( struct sendfile_info_t *si ) {
   si->res = sendfile( si->out, si->in, si->offset, si->sz );
}
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----

I hope this mail will help.

-- 
Manuel


More information about the Gc mailing list