The pthreads library introduces significant overhead for single-threaded
applications, so it's nice to be able to use the regular libc versions
of various routines when possible. Having libGL explicitly link to
libpthreads makes this impossible.

Yes, libGL uses several pthreads functions, but it doesn't create
threads itself, so the pthreads function usages are simply there to
permit applications to use threads if they want. Glibc contains many
pthread functions as 'weak' symbols, expressly for this situation.
Single threaded applications bind to the non-thread-safe 'weak' versions
of the pthread functions in glibc while pthread-using multi-threaded
applications bind to the 'strong' versions in the real pthreads library.

The problem that Mesa's GL library faces is that there are several
pthread functions that it uses which are not included in glibc. So, it
currently links to libpthread and makes all GL applications use the
thread-safe version of many glibc functions (stdio and malloc being two
horrible consequences).

I've gone ahead and created a thread stub library that implements the
missing functions and allows single-threaded GL applications to skip
-lpthread.

If this seems useful (I don't know how many "real" GL applications are
multi-threaded), we could use this on any elf system supporting weak
symbols, adding more symbols as necessary for non-Glibc systems.

Here's the code:

int pthread_key_create (pthread_key_t *key, void (*destr_function) (void *)) 
__attribute__ ((weak));

static struct {
    void *pointer;
    void (*destr_function) (void *);
    int busy;
} pthread_specific[PTHREAD_KEYS_MAX];

int pthread_key_create (pthread_key_t *key, void (*destr_function) (void *))
{
    int i;

    printf ("pthread_key_create\n");
    for (i = 0; i < PTHREAD_KEYS_MAX; i++)
        if (!pthread_specific[i].busy)
        {
            pthread_specific[i].pointer = NULL;
            pthread_specific[i].destr_function = destr_function;
            pthread_specific[i].busy = 1;
            *key = i;
            return 0;
        }
    return EAGAIN;
}

int  pthread_once(pthread_once_t  *once_control,  void  (*init_routine) (void)) 
__attribute ((weak));

int  pthread_once(pthread_once_t  *once_control,  void  (*init_routine) (void))
{
    if (!*once_control) {
        *once_control = 1;
        (*init_routine) ();
    }
    return 0;
}

int pthread_setspecific (pthread_key_t key, const void *pointer) __attribute__ 
((weak));

int pthread_setspecific (pthread_key_t key, const void *pointer)
{
    if (key >= PTHREAD_KEYS_MAX || !pthread_specific[key].busy)
        return EINVAL;

    pthread_specific[key].pointer = (void *) pointer;
    return 0;
}

void * pthread_getspecific (pthread_key_t key) __attribute ((weak));

void * pthread_getspecific (pthread_key_t key)
{
    if (key >= PTHREAD_KEYS_MAX || !pthread_specific[key].busy)
        return NULL;

    return pthread_specific[key].pointer;
}


-- 
[EMAIL PROTECTED]

Attachment: signature.asc
Description: This is a digitally signed message part

-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services
for just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Mesa3d-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to