[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#373555: Can't use pthread_cleanup_push with non-GCC compiler



Package: libc6-dev
Version: 2.3.6-15

When trying to compile a small pthread code with the Portland compiler
the pthread.h gives me code that uses gcc builtins.

System is a x86_64 machine with nptl based pthread.

Code:
#include <pthread.h>
int
main ()
{
    pthread_t th=pthread_self();
    pthread_join(th, 0);
    pthread_attr_init(0);
    pthread_cleanup_push(0, 0);
    pthread_create(0,0,0,0);
    pthread_cleanup_pop(0);
    return 0;
}

When compiled with PGI i get
$ pgcc -o ptest ptest.c -lpthread
ptest.c:
ptest.o: In function `main':
ptest.c:(.text+0x46): undefined reference to `__builtin_expect'

This seems to be caused by the following sequence of #if defined in
pthread.h

...
#if defined __GNUC__ && defined __EXCEPTIONS
# ifdef __cplusplus
...
# define pthread_cleanup_push(routine, arg) \
  do { \
    __pthread_cleanup_class __clframe (routine, arg)
...
# else
# define pthread_cleanup_push(routine, arg) \
   do { \
    struct __pthread_cleanup_frame __clframe \
      __attribute__ ((__cleanup__ (__pthread_cleanup_routine))) \
      = { .__cancel_routine = (routine), .__cancel_arg = (arg), \
          .__do_it = 1 };
...
# endif
#else
# define pthread_cleanup_push(routine, arg) \
  do { \
    __pthread_unwind_buf_t __cancel_buf; \
    void (*__cancel_routine) (void *) = (routine); \
    void *__cancel_arg = (arg); \
    int not_first_call = __sigsetjmp ((struct __jmp_buf_tag *) \
                                      __cancel_buf.__cancel_jmp_buf, 0);
\
    if (__builtin_expect (not_first_call, 0)) \
...
#endif

I.e. it uses __builtin_expect when __GCC__ is not defined.

All of this seems to be a bit too GCC centric.




Reply to: