⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethread.h

📁 OTP是开放电信平台的简称
💻 H
📖 第 1 页 / 共 2 页
字号:
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ *//* * Description: Thread library for use in the ERTS and other OTP *              applications. * Author: Rickard Green */#ifndef ETHREAD_H__#define ETHREAD_H__#ifndef ETHR_HAVE_ETHREAD_DEFINES#  include "ethread_header_config.h"#endif#include <stdlib.h>#include <errno.h>typedef struct {    long tv_sec;    long tv_nsec;} ethr_timeval;#if defined(DEBUG)#  undef ETHR_XCHK#  define  ETHR_XCHK 1#else#  ifndef ETHR_XCHK#    define ETHR_XCHK 0#  endif#endif#undef ETHR_INLINE#if defined(__GNUC__)#  define ETHR_INLINE __inline__#elif defined(__WIN32__)#  define ETHR_INLINE __forceinline#endif#if defined(DEBUG) || !defined(ETHR_INLINE) || ETHR_XCHK#  undef ETHR_TRY_INLINE_FUNCS#endif#define ETHR_RWMUTEX_INITIALIZED 	0x99999999#define ETHR_MUTEX_INITIALIZED		0x77777777#define ETHR_COND_INITIALIZED		0x55555555#if defined(ETHR_PTHREADS)/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * The pthread implementation                                                *\*                                                                           */#if defined(__linux__) && !defined(_GNU_SOURCE)#error "_GNU_SOURCE not defined. Please, compile all files with -D_GNU_SOURCE."#endif#if defined(ETHR_HAVE_MIT_PTHREAD_H)#include <pthread/mit/pthread.h>#elif defined(ETHR_HAVE_PTHREAD_H)#include <pthread.h>#endif#define ETHR_HAVE_ETHR_MUTEX_TRYLOCK 1/* Types */typedef pthread_t ethr_tid;typedef struct ethr_mutex_ ethr_mutex;struct ethr_mutex_ {    pthread_mutex_t pt_mtx;    int is_rec_mtx;    ethr_mutex *prev;    ethr_mutex *next;#if ETHR_XCHK    int initialized;#endif};typedef struct ethr_cond_ ethr_cond;struct ethr_cond_ {    pthread_cond_t pt_cnd;#if ETHR_XCHK    int initialized;#endif};#ifdef ETHR_EXTENDED_LIBtypedef struct ethr_rwmutex_ ethr_rwmutex;struct ethr_rwmutex_ {    pthread_rwlock_t pt_rwlock;#if ETHR_XCHK    int initialized;#endif};#endif/* Static initializers */#if ETHR_XCHK#define ETHR_MUTEX_XCHK_INITER	, ETHR_MUTEX_INITIALIZED#define ETHR_COND_XCHK_INITER	, ETHR_COND_INITIALIZED#else#define ETHR_MUTEX_XCHK_INITER#define ETHR_COND_XCHK_INITER#endif#define ETHR_MUTEX_INITER {PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL ETHR_MUTEX_XCHK_INITER}#define ETHR_COND_INITER {PTHREAD_COND_INITIALIZER ETHR_COND_XCHK_INITER}#if defined(ETHR_HAVE_PTHREAD_MUTEXATTR_SETTYPE) \    || defined(ETHR_HAVE_PTHREAD_MUTEXATTR_SETKIND_NP)#  define ETHR_HAVE_ETHR_REC_MUTEX_INIT 1#  ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP#    define ETHR_REC_MUTEX_INITER \            {PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, 1, NULL, NULL ETHR_MUTEX_XCHK_INITER}#  endif#else#  undef ETHR_HAVE_ETHR_REC_MUTEX_INIT#endif#ifndef ETHR_HAVE_PTHREAD_ATFORK#  define ETHR_NO_FORKSAFETY 1#endiftypedef pthread_key_t ethr_tsd_key;#define ETHR_HAVE_ETHR_SIG_FUNCS 1#ifdef ETHR_EXTENDED_LIB#if (!defined(__builtin_expect) \     || !defined(__GNUC__) \     || (__GNUC__ < 3 && __GNUC_MINOR__ < 96))#define __builtin_expect(X, Y) (X)#endif/* For CPU-optimised atomics, spinlocks, and rwlocks. */#if defined(__GNUC__)#if defined(__i386__)#include "i386/ethread.h"#elif defined(__x86_64__)#include "x86_64/ethread.h"#elif (defined(__powerpc__) || defined(__ppc__)) && !defined(__powerpc64__)#include "ppc32/ethread.h"#elif defined(__sparc__)#include "sparc32/ethread.h"#endif#endif /* __GNUC__ */#if defined(PURIFY) || defined(VALGRIND) || defined(ETHR_DISABLE_NATIVE_OPS)#undef ETHR_HAVE_NATIVE_ATOMICS#undef ETHR_HAVE_NATIVE_LOCKS#endif#ifdef ETHR_HAVE_NATIVE_ATOMICS/* * Map ethread native atomics to ethread API atomics. */typedef ethr_native_atomic_t ethr_atomic_t;static ETHR_INLINE intethr_atomic_init(ethr_atomic_t *var, long i){    ethr_native_atomic_init(var, i);    return 0;}static ETHR_INLINE intethr_atomic_set(ethr_atomic_t *var, long i){    ethr_native_atomic_set(var, i);    return 0;}static ETHR_INLINE intethr_atomic_read(ethr_atomic_t *var, long *i){    *i = ethr_native_atomic_read(var);    return 0;}static ETHR_INLINE intethr_atomic_add(ethr_atomic_t *var, long incr){    ethr_native_atomic_add(var, incr);    return 0;}       static ETHR_INLINE intethr_atomic_addtest(ethr_atomic_t *var, long i, long *testp){    *testp = ethr_native_atomic_add_return(var, i);    return 0;}static ETHR_INLINE intethr_atomic_inc(ethr_atomic_t *var){    ethr_native_atomic_inc(var);    return 0;}static ETHR_INLINE intethr_atomic_dec(ethr_atomic_t *var){    ethr_native_atomic_dec(var);    return 0;}static ETHR_INLINE intethr_atomic_inctest(ethr_atomic_t *var, long *testp){    *testp = ethr_native_atomic_inc_return(var);    return 0;}static ETHR_INLINE intethr_atomic_dectest(ethr_atomic_t *var, long *testp){    *testp = ethr_native_atomic_dec_return(var);    return 0;}static ETHR_INLINE intethr_atomic_and_old(ethr_atomic_t *var, long mask, long *old){    *old = ethr_native_atomic_and_retold(var, mask);    return 0;}static ETHR_INLINE intethr_atomic_or_old(ethr_atomic_t *var, long mask, long *old){    *old = ethr_native_atomic_or_retold(var, mask);    return 0;}static ETHR_INLINE intethr_atomic_xchg(ethr_atomic_t *var, long new, long *old){    *old = ethr_native_atomic_xchg(var, new);    return 0;}   #define ETHR_HAVE_OPTIMIZED_ATOMIC_OPS 1#endif /* ETHR_HAVE_NATIVE_ATOMICS */#ifdef ETHR_HAVE_NATIVE_LOCKS/* * Map ethread native spinlocks to ethread API spinlocks. */typedef ethr_native_spinlock_t ethr_spinlock_t;static ETHR_INLINE intethr_spinlock_init(ethr_spinlock_t *lock){    ethr_native_spinlock_init(lock);    return 0;}static ETHR_INLINE intethr_spinlock_destroy(ethr_spinlock_t *lock){    return 0;}static ETHR_INLINE intethr_spin_unlock(ethr_spinlock_t *lock){    ethr_native_spin_unlock(lock);    return 0;}static ETHR_INLINE intethr_spin_lock(ethr_spinlock_t *lock){    ethr_native_spin_lock(lock);    return 0;}/* * Map ethread native rwlocks to ethread API rwlocks. */typedef ethr_native_rwlock_t ethr_rwlock_t;static ETHR_INLINE intethr_rwlock_init(ethr_rwlock_t *lock){    ethr_native_rwlock_init(lock);    return 0;}static ETHR_INLINE intethr_rwlock_destroy(ethr_rwlock_t *lock){    return 0;}static ETHR_INLINE intethr_read_unlock(ethr_rwlock_t *lock){    ethr_native_read_unlock(lock);    return 0;}static ETHR_INLINE intethr_read_lock(ethr_rwlock_t *lock){    ethr_native_read_lock(lock);    return 0;}static ETHR_INLINE intethr_write_unlock(ethr_rwlock_t *lock){    ethr_native_write_unlock(lock);    return 0;}static ETHR_INLINE intethr_write_lock(ethr_rwlock_t *lock){    ethr_native_write_lock(lock);    return 0;}#define ETHR_HAVE_OPTIMIZED_LOCKS 1#endif /* ETHR_HAVE_NATIVE_LOCKS */#endif /* #ifdef ETHR_EXTENDED_LIB */#ifndef ETHR_HAVE_OPTIMIZED_ATOMIC_OPS#define ETHR_ATOMIC_ADDR_BITS 4#define ETHR_ATOMIC_ADDR_SHIFT 3#ifdef ETHR_HAVE_PTHREAD_SPIN_LOCKextern pthread_spinlock_t ethr_atomic_spinlock[1 << ETHR_ATOMIC_ADDR_BITS];#define ETHR_ATOMIC_PTR2LCK__(PTR) \(&ethr_atomic_spinlock[((((unsigned long) (PTR)) >> ETHR_ATOMIC_ADDR_SHIFT) \			& ((1 << ETHR_ATOMIC_ADDR_BITS) - 1))])#define ETHR_ATOMIC_OP_FALLBACK_IMPL__(AP, EXPS)			\do {									\    pthread_spinlock_t *slp__ = ETHR_ATOMIC_PTR2LCK__((AP));		\    int res__ = pthread_spin_lock(slp__);				\    if (res__ != 0)							\	return res__;							\    { EXPS; }								\    return pthread_spin_unlock(slp__);					\} while (0)#elseextern pthread_mutex_t ethr_atomic_mutex[1 << ETHR_ATOMIC_ADDR_BITS];#define ETHR_ATOMIC_PTR2LCK__(PTR) \(&ethr_atomic_mutex[((((unsigned long) (PTR)) >> ETHR_ATOMIC_ADDR_SHIFT) \		     & ((1 << ETHR_ATOMIC_ADDR_BITS) - 1))])#define ETHR_ATOMIC_OP_FALLBACK_IMPL__(AP, EXPS)			\do {									\    pthread_mutex_t *mtxp__ = ETHR_ATOMIC_PTR2LCK__((AP));		\    int res__ = pthread_mutex_lock(mtxp__);				\    if (res__ != 0)							\	return res__;							\    { EXPS; }								\    return pthread_mutex_unlock(mtxp__);				\} while (0)#endiftypedef long ethr_atomic_t;#endif#ifndef ETHR_HAVE_OPTIMIZED_LOCKS#ifdef ETHR_HAVE_PTHREAD_SPIN_LOCKtypedef struct {    pthread_spinlock_t spnlck;} ethr_spinlock_t;typedef struct {    pthread_spinlock_t spnlck;    unsigned counter;} ethr_rwlock_t;#define ETHR_RWLOCK_WRITERS (((unsigned) 1) << 31)#elsetypedef struct {    pthread_mutex_t mtx;} ethr_spinlock_t;typedef struct {    pthread_rwlock_t rwlck;} ethr_rwlock_t;#endif#endif#ifdef ETHR_TRY_INLINE_FUNCSstatic ETHR_INLINE intethr_mutex_trylock(ethr_mutex *mtx){    return pthread_mutex_trylock(&mtx->pt_mtx);}static ETHR_INLINE intethr_mutex_lock(ethr_mutex *mtx){    return pthread_mutex_lock(&mtx->pt_mtx);}static ETHR_INLINE intethr_mutex_unlock(ethr_mutex *mtx){    return pthread_mutex_unlock(&mtx->pt_mtx);}#ifdef ETHR_EXTENDED_LIBstatic ETHR_INLINE intethr_rwmutex_tryrlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_tryrdlock(&rwmtx->pt_rwlock);}static ETHR_INLINE intethr_rwmutex_rlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_rdlock(&rwmtx->pt_rwlock);}static ETHR_INLINE intethr_rwmutex_runlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_unlock(&rwmtx->pt_rwlock);}static ETHR_INLINE intethr_rwmutex_tryrwlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_trywrlock(&rwmtx->pt_rwlock);}static ETHR_INLINE intethr_rwmutex_rwlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_wrlock(&rwmtx->pt_rwlock);}static ETHR_INLINE intethr_rwmutex_rwunlock(ethr_rwmutex *rwmtx){    return pthread_rwlock_unlock(&rwmtx->pt_rwlock);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -