[Android] [PATCH] Add pthread_once function from AOSP

Edward Wang edward.c.wang at compdigitec.com
Thu Jun 28 12:37:53 CEST 2012


On 12-06-28 04:55 AM, Rafaël Carré <funman at videolan.org> wrote:
> Le 28/06/2012 00:09, Edward Wang a écrit :
>> See:
>> http://www.compdigitec.com/labs/2012/06/25/fclose-freezes-when-run-inside-pthread-on-android-2-1/
>> http://code.google.com/p/android/issues/detail?id=5116
>>
>> Summary:
>> Android 2.1/2.2's pthread implementation has a bug where fclose() hangs inside pthread. This commit imports a working version of pthread_once that makes VLC for Android work on Android 2.1 and 2.2.
>> ---
>>   Updated version, please discard previous version.
>>
>>   vlc-android/jni/Android.mk     |    3 +-
>>   vlc-android/jni/pthread-once.c |   91 ++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 93 insertions(+), 1 deletions(-)
>>   create mode 100644 vlc-android/jni/pthread-once.c
>>
>> diff --git a/vlc-android/jni/Android.mk b/vlc-android/jni/Android.mk
>> index 7c05cb5..b2647d4 100644
>> --- a/vlc-android/jni/Android.mk
>> +++ b/vlc-android/jni/Android.mk
>> @@ -3,7 +3,7 @@ include $(CLEAR_VARS)
>>
>>   LOCAL_MODULE    := libvlcjni
>>
>> -LOCAL_SRC_FILES := libvlcjni.c aout.c thumbnailer.c pthread-condattr.c pthread-rwlocks.c eventfd.c sem.c
>> +LOCAL_SRC_FILES := libvlcjni.c aout.c thumbnailer.c pthread-condattr.c pthread-rwlocks.c pthread-once.c eventfd.c sem.c
>>
>>   LOCAL_C_INCLUDES := $(VLC_SRC_DIR)/include
>>
>> @@ -11,6 +11,7 @@ ARCH=$(ANDROID_ABI)
>>
>>   CPP_STATIC=$(ANDROID_NDK)/sources/cxx-stl/gnu-libstdc++/libs/$(ARCH)/libgnustl_static.a
>>
>> +LOCAL_ARM_MODE := arm
> not related?
It is related, please see below:
>>   LOCAL_CFLAGS := -std=gnu99
>>   ifeq ($(ARCH), "armeabi")
>>   	LOCAL_CFLAGS += -DHAVE_ARMEABI
>> diff --git a/vlc-android/jni/pthread-once.c b/vlc-android/jni/pthread-once.c
>> new file mode 100644
>> index 0000000..0fae403
>> --- /dev/null
>> +++ b/vlc-android/jni/pthread-once.c
>> @@ -0,0 +1,91 @@
>> +/*
>> + * Copyright (C) 2008 The Android Open Source Project
>> + * All rights reserved.
>> + *
>> + * Redistribution and use in source and binary forms, with or without
>> + * modification, are permitted provided that the following conditions
>> + * are met:
>> + *  * Redistributions of source code must retain the above copyright
>> + *    notice, this list of conditions and the following disclaimer.
>> + *  * Redistributions in binary form must reproduce the above copyright
>> + *    notice, this list of conditions and the following disclaimer in
>> + *    the documentation and/or other materials provided with the
>> + *    distribution.
>> + *
>> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
>> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
>> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
>> + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
>> + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
>> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
>> + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
>> + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
>> + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>> + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>> + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>> + * SUCH DAMAGE.
>> + */
>> +#include<errno.h>
>> +#include<pthread.h>
>> +#include<unistd.h>
>> +
>> +#include<machine/cpu-features.h>
>> +
>> +/* Adapted from bionic_atomic_inline.h */
>> +void ANDROID_MEMBAR_FULL() {
>> +    if(sysconf(_SC_NPROCESSORS_CONF)>  1) { /* SMP */
> no need to detect SMP at runtime, just use the same code everywhere and
> asm ("" : : : "memory") as fallback
OK
>
>> +#ifdef __arm__
>> +    #if __ARM_ARCH__>= 7
>> +            do { __asm__ __volatile__ ("dmb" ::: "memory"); } while (0);
>> +    #elif __ARM_ARCH__ == 6
>> +            /*
>> +            * For ARMv6 we need to issue a specific MCR instead of the DMB, since
>> +            * that wasn't added until v7.
>> +            */
>> +            do { __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" :: "r" (0) : "memory"); } while (0);
> Is the system control coprocessor present on all ARMv6 ?
It is present in ARMv6 base in _ARM_ mode, that's why I had 
LOCAL_MODE_ARM set above to ensure it runs on all ARMv6 devices.
>> +    #elif __ARM_ARCH__<  6
>> +            /*
>> +             * For anything older, SMP isn't relevant.
>> +             */
>> +    #endif
>> +#elif defined(__i386__) || defined(__x86_64__)
>> +        /*
>> +         * For recent x86, we can use the SSE2 mfence instruction.
>> +         */
>> +        do { __asm__ __volatile__ ("mfence" ::: "memory"); } while (0);
> This should use __SSE2__ define
OK
>
>> +#else
>> +        /*
>> +         * Implementation not defined for this platform.  Hopefully we're building
>> +         * in uniprocessor mode.
>> +         *
>> +         * For example: MIPS, PowerPC, etc
>> +         */
>> +#endif
>> +    } else {
>> +        do { __asm__ __volatile__ ("" ::: "memory"); } while (0);
>> +    }
>> +}
>> +
>> +/* NOTE: this implementation doesn't support a init function that throws a C++ exception
>> + *       or calls fork()
>> + */
>> +int pthread_once( pthread_once_t*  once_control,  void (*init_routine)(void) )
>> +{
>> +    if( once_control == NULL || init_routine == NULL )
>> +        return EINVAL;
>> +    static pthread_mutex_t   once_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
>> +    volatile pthread_once_t* ocptr = once_control;
>> +
>> +    pthread_once_t tmp = *ocptr;
>> +    ANDROID_MEMBAR_FULL();
>> +    if (tmp == PTHREAD_ONCE_INIT) {
>> +        pthread_mutex_lock(&once_lock );
>> +        if (*ocptr == PTHREAD_ONCE_INIT) {
>> +            (*init_routine)();
>> +            ANDROID_MEMBAR_FULL();
>> +            *ocptr = ~PTHREAD_ONCE_INIT;
>> +        }
>> +        pthread_mutex_unlock(&once_lock );
>> +    }
>> +    return 0;
>> +}
>>
>>
Regards,
         Edward Wang


More information about the Android mailing list