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

📄 mpidu_process_locks.h

📁 mpi并行计算的c++代码 可用vc或gcc编译通过 可以用来搭建并行计算试验环境
💻 H
字号:
/* -*- Mode: C; c-basic-offset:5 ; -*- *//* * *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#ifndef MPIDU_PROCESS_LOCKS_H#define MPIDU_PROCESS_LOCKS_H#include "mpiimpl.h"#include "mpid_locksconf.h"#include <stdio.h>/* FIXME: First use the configure ifdefs to decide on an approach for    locks.  Then put all lock code in one place, or at least guarded by   the same "USE_xxx" ifdef.  It is nearly impossible with the current code   to determine, for example, what is the definition of MPIDU_Process_lock_t.   (Specifically, for the Intel compiler on an x86, it appears to be   missing a volatile, needed when using the _InterlockedExchange inline    function*/#ifdef HAVE_GCC_AND_PENTIUM_ASM#define HAVE_COMPARE_AND_SWAPstatic inline char__attribute__ ((unused))     compare_and_swap (volatile long int *p, long int oldval, long int newval){  char ret;  long int readval;  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"                : "=q" (ret), "=m" (*p), "=a" (readval)            : "r" (newval), "m" (*p), "a" (oldval) : "memory");  return ret;}#endif#ifdef HAVE_GCC_AND_X86_64_ASM#define HAVE_COMPARE_AND_SWAPstatic inline char__attribute__ ((unused))     compare_and_swap (volatile long int *p, long int oldval, long int newval){  char ret;  long int readval;  __asm__ __volatile__ ("lock; cmpxchgq %3, %1; sete %0"                : "=q" (ret), "=m" (*p), "=a" (readval)            : "r" (newval), "m" (*p), "a" (oldval) : "memory");  return ret;}#endif#ifdef HAVE_GCC_AND_IA64_ASM#define HAVE__INTERLOCKEDEXCHANGE 1/* Make sure that the type here is compatible with the use and with  * MPIDU_Process_lock_t */static inline unsigned long _InterlockedExchange(volatile long *ptr, unsigned long x){   unsigned long result;   __asm__ __volatile ("xchg4 %0=[%1],%2" : "=r" (result) : "r" (ptr), "r" (x) : "memory");   return result;}#endif#ifdef HAVE_ICC_AND_IA64#define HAVE__INTERLOCKEDEXCHANGE 1#include <ia64intrin.h>#define _InterlockedExchange(ptr,x) _InterlockedExchange(ptr,x)#endifextern int g_nLockSpinCount;/* Define MPIDU_Yield() */#ifdef HAVE_YIELD#define MPIDU_Yield() yield()#elif defined(HAVE_WIN32_SLEEP)#define MPIDU_Yield() Sleep(0)#elif defined (HAVE_SCHED_YIELD)#ifdef HAVE_SCHED_H#include <sched.h>#endif#define MPIDU_Yield() sched_yield()#elif defined (HAVE_SELECT)#define MPIDU_Yield() { struct timeval t; t.tv_sec = 0; t.tv_usec = 0; select(0,0,0,0,&t); }#elif defined (HAVE_USLEEP)#define MPIDU_Yield() usleep(0)#elif defined (HAVE_SLEEP)#define MPIDU_Yield() sleep(0)#else#error *** No yield function specified ***#endif#ifdef USE_SLEEP_YIELD/* Define MPIDU_Sleep_yield() */extern int MPIDI_Sleep_yield_count;extern int MPIDI_Sleep_yield_counts[10];static inline void MPIDU_Sleep_yield(){#ifdef HAVE_WIN32_SLEEP    Sleep(MPIDI_Sleep_yield_counts[MPIDI_Sleep_yield_count]);#elif defined(HAVE_USLEEP)    usleep(MPIDI_Sleep_yield_counts[MPIDI_Sleep_yield_count]);#elif defined(HAVE_SELECT)    struct timeval t;    t.tv_sec = 0;    t.tv_usec = MPIDI_Sleep_yield_counts[MPIDI_Sleep_yield_count];    select(0,0,0,0,&t);#elif defined(HAVE_SLEEP)    sleep(MPIDI_Sleep_yield_counts[MPIDI_Sleep_yield_count]);#else#error *** No function available to implement sleep_yield ***#endif    if (MPIDI_Sleep_yield_count < 9)	MPIDI_Sleep_yield_count++;}#endif/*#ifdef HAVE_WIN32_SLEEP#define MPIDU_Sleep_yield() Sleep(200)#elif defined(HAVE_USLEEP)#define MPIDU_Sleep_yield() usleep(200000)#elif defined(HAVE_SELECT)#define MPIDU_Sleep_yield() { struct timeval t; t.tv_sec = 0; t.tv_usec = 200000; select(0,0,0,0,&t); }#elif defined(HAVE_SLEEP)#define MPIDU_Sleep_yield() sleep(1)#else#error *** No function available to implement sleep_yield ***#endif*/#if defined(HAVE_SPARC_INLINE_PROCESS_LOCKS)typedef int MPIDU_Process_lock_t;#else#ifdef HAVE_MUTEX_INIT/*   Only known system is Solaris */#include <sys/systeminfo.h>#include <sys/processor.h>#include <sys/procset.h>#include <synch.h>#include <string.h>typedef mutex_t                 MPIDU_Process_lock_t;#define MPIDU_Process_lock_init(lock)   mutex_init(lock,USYNC_PROCESS,(void *)NULL)#define MPIDU_Process_lock(lock)        mutex_lock(lock)#define MPIDU_Process_unlock(lock)      mutex_unlock(lock)#define MPIDU_Process_lock_free(lock)   mutex_destroy(lock)#undef FUNCNAME#define FUNCNAME MPIDU_Process_lock_busy_wait#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_lock_busy_wait( MPIDU_Process_lock_t *lock ){    int i;    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);    mutex_lock(lock);    mutex_unlock(lock);    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);}#else#ifdef USE_BUSY_LOCKS#ifdef HAVE_MUTEX_INITtypedef mutex_t MPIDU_Process_lock_t;#elsetypedef volatile long MPIDU_Process_lock_t;#endif#else#ifdef HAVE_NT_LOCKStypedef HANDLE MPIDU_Process_lock_t;#elif defined(HAVE_PTHREAD_H)#include <pthread.h>typedef pthread_mutex_t MPIDU_Process_lock_t;  #else#error *** No locking mechanism for shared memory.specified ***#endif#endif#include <errno.h>#ifdef HAVE_WINDOWS_H#include <winsock2.h>#include <windows.h>#endif#ifdef USE_BUSY_LOCKS/* FIXME: only the lock/unlock/wait routines should be considered for    static inline functions */#undef FUNCNAME#define FUNCNAME MPIDU_Process_lock_init#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_lock_init( MPIDU_Process_lock_t *lock ){#ifdef HAVE_MUTEX_INIT    int err;#endif    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_LOCK_INIT);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_LOCK_INIT);#ifdef HAVE_MUTEX_INIT    memset(lock, 0, sizeof(MPIDU_Process_lock_t));    err = mutex_init(lock, USYNC_PROCESS, 0);    if (err)	MPIU_Error_printf("mutex_init error: %d\n", err);#else    *(lock) = 0;#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK_INIT);}#undef FUNCNAME#define FUNCNAME MPIDU_Process_lock#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_lock( MPIDU_Process_lock_t *lock ){#ifdef HAVE_MUTEX_INIT    int err;    err = mutex_lock(lock);    if (err)	MPIU_Error_printf("mutex_lock error: %d\n", err);#else    int i;    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_LOCK);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_LOCK);    for (;;)    {        for (i=0; i<g_nLockSpinCount; i++)        {            if (*lock == 0)            {#ifdef HAVE_INTERLOCKEDEXCHANGE                if (InterlockedExchange((LPLONG)lock, 1) == 0)                {                    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK);                    return;                }#elif defined(HAVE__INTERLOCKEDEXCHANGE)		/* The Intel compiler complains if the lock is cast to		 * volatile void * (the type of lock is probably		 * volatile long *).  The void * works for the Intel 		 * compiler. */                if (_InterlockedExchange((void *)lock, 1) == 0)                {                    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK);                    return;                }#elif defined(HAVE_COMPARE_AND_SWAP)                if (compare_and_swap(lock, 0, 1) == 1)                {                    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK);                    return;                }#else#error *** No atomic memory operation specified to implement busy locks ***#endif            }        }        MPIDU_Yield();    }    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK);#endif}#undef FUNCNAME#define FUNCNAME MPIDU_Process_unlock#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_unlock( MPIDU_Process_lock_t *lock ){#ifdef HAVE_MUTEX_INIT    int err;#endif    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_UNLOCK);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_UNLOCK);#ifdef HAVE_MUTEX_INIT    err = mutex_lock(lock);    if (err)	MPIU_Error_printf("mutex_unlock error: %d\n", err);#else    *(lock) = 0;#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_UNLOCK);}#undef FUNCNAME#define FUNCNAME MPIDU_Process_lock_busy_wait#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_lock_busy_wait( MPIDU_Process_lock_t *lock ){    int i;#ifdef HAVE_MUTEX_INIT    int err;#endif    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);#ifdef HAVE_MUTEX_INIT    err = mutex_lock(lock);    if (err)	MPIU_Error_printf("mutex_lock error: %d\n", err);    err = mutex_unlock(lock);    if (err)	MPIU_Error_printf("mutex_unlock error: %d\n", err);#else    for (;;)    {        for (i=0; i<g_nLockSpinCount; i++)            if (!*lock)            {		MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);                return;            }        MPIDU_Yield();    }#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK_BUSY_WAIT);}#undef FUNCNAME#define FUNCNAME MPIDU_Process_lock_free#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)static inline void MPIDU_Process_lock_free( MPIDU_Process_lock_t *lock ){#ifdef HAVE_MUTEX_INIT    int err;#endif    MPIDI_STATE_DECL(MPID_STATE_MPIDU_PROCESS_LOCK_FREE);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_PROCESS_LOCK_FREE);#ifdef HAVE_MUTEX_INIT    err = mutex_destroy(lock);    if (err)	MPIU_Error_printf("mutex_destroy error: %d\n", err);#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_PROCESS_LOCK_FREE);}#elsevoid MPIDU_Process_lock_init( MPIDU_Process_lock_t *lock );void MPIDU_Process_lock( MPIDU_Process_lock_t *lock );void MPIDU_Process_unlock( MPIDU_Process_lock_t *lock );void MPIDU_Process_lock_free( MPIDU_Process_lock_t *lock );void MPIDU_Process_lock_busy_wait( MPIDU_Process_lock_t *lock );#endif /* #ifdef USE_BUSY_LOCKS */#endif /* #ifdef HAVE_MUTEX_INIT */#endif /* defined(HAVE_SPARC_INLINE_PROCESS_LOCKS) */#undef FUNCNAME#define FUNCNAME MPIDU_Compare_swap#undef FCNAME#define FCNAME MPIDI_QUOTE(FUNCNAME)/*@   MPIDU_Compare_swap -    Parameters:+  void **dest.  void *new_val.  void *compare_val.  MPIDU_Process_lock_t *lock-  void **original_val   Notes:@*/static inline int MPIDU_Compare_swap( void **dest, void *new_val, void *compare_val,                                    MPIDU_Process_lock_t *lock, void **original_val ){    /* dest = pointer to value to be checked (address size)       new_val = value to set dest to if *dest == compare_val       original_val = value of dest prior to this operation */    MPIDI_STATE_DECL(MPID_STATE_MPIDU_COMPARE_SWAP);    MPIDI_FUNC_ENTER(MPID_STATE_MPIDU_COMPARE_SWAP);#ifdef HAVE_NT_LOCKS    MPIU_UNREFERENCED_ARG(lock);    /**original_val = InterlockedCompareExchange(dest, new_val, compare_val);*/    /**original_val = (void*)InterlockedCompareExchange((LONG*)dest, (LONG)new_val, (LONG)compare_val);*/    *original_val = (void*)InterlockedCompareExchangePointer(dest, new_val, compare_val);#elif defined(HAVE_COMPARE_AND_SWAP)    MPIU_UNREFERENCED_ARG(lock);    if (compare_and_swap((volatile long *)dest, (long)compare_val, (long)new_val))        *original_val = new_val;#elif defined(HAVE_SPARC_INLINE_PROCESS_LOCKS) || defined(HAVE_PTHREAD_H) || defined(HAVE_MUTEX_INIT)    MPIDU_Process_lock( lock );    *original_val = *dest;        if ( *dest == compare_val )        *dest = new_val;    MPIDU_Process_unlock( lock );#else#error *** No locking functions specified ***#endif    MPIDI_FUNC_EXIT(MPID_STATE_MPIDU_COMPARE_SWAP);    return 0;}#endif

⌨️ 快捷键说明

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