This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: is sysdep-cancel.h needed for any linux arch?


On Sat, Jan 04, 2003 at 12:19:06AM +0100, Franz Sirl wrote:
> On Thursday 02 January 2003 16:22, Jakub Jelinek wrote:
> > Yes, sysdep-cancel.h needs to be added for all arches.
> > Even if you succeeded to make the thing compile, it wouldn't work properly
> > (ie. cancellation points would not actually be cancellation points).
> > But it requires understanding of lots of architecture details, so
> > it would be best added by the respective architecture maintainers.
> > Will try to finish alpha, would prefer to leave the rest of arches
> > to others.
> 
> What exactly has PSEUDO in sysdep-cancel.h to do? I couldn't find a 
> specification and judging from the other arches is difficult, cause I don't 
> know their ABI.
> 
> - what has to happen between CENABLE and CDISABLE?
> - does PSEUDO fall thru to anything?
> - is it OK to compile in sysdep.c on PPC (maybe sysdep.c should be compiled 
> into libpthread on all arches to match libc?) to get the __syscall_error 
> routine into libpthread?

Here is a rough C version of what you need to do:

#ifdef IS_IN_libpthread
#define __local_multiple_threads __pthread_multiple_threads
#define __local_enable_asynccancel __pthread_enable_asynccancel
#define __local_disable_asynccancel __pthread_disable_asynccancel
#else
#define __local_multiple_threads __libc_multiple_threads
#define __local_enable_asynccancel __libc_enable_asynccancel
#define __local_disable_asynccancel __libc_disable_asynccancel
#endif
int __local_multiple_threads __attribute__((visibility ("hidden")));
int __local_enable_asynccancel (void) __attribute__((visibility ("hidden")));
void __local_disable_asynccancel (int) __attribute__((visibility ("hidden")));

/* Say for 3 arg syscall: */
long name (long arg1, long arg2, long arg3)
{
  int mask;
  long ret;
  if (__builtin_expect (__local_multiple_threads == 0, 1))
    return INLINE_SYSCALL (syscall_name, 3, arg1, arg2, arg3);
  mask = __local_enable_asynccancel ();
  ret = INLINE_SYSCALL (syscall_name, 3, arg1, arg2, arg3);
  __local_disable_asynccancel (mask);
  return ret;
}

plus define SINGLE_THREAD_P macro for C code.
If you have thread pointer register and access through it is faster
than loading of GOT pointer, you may replace __local_multiple_threads
with THREAD_SELF->p_header.multiple_threads.

You can count on PSEUDO macro being followed by ret followed by PSEUDO_END
(that's what the syscalls.list generated syscalls look like - for other
uses you'd need to manually include <sysdep-cancel.h> instead of
<sysdep.h> and deal with it.

Of course you want this as efficient as possible, especially in the
__local_multiple_threads == 0 case.
Note that enable/disable_asynccancel are calls which according to
ABI rules usually clobber the syscall arguments etc., so things must
be saved/restored around unless you have register windows.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]