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

📄 mutex.c

📁 debug source code under unix platform.
💻 C
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * Threads interface.  Provides thread-safe facilities for locking * data structures used by the mpatrol library.  An extremely informative * book on POSIX threads and multithreaded programming in general is * Programming with POSIX Threads, First Edition by David R. Butenhof * (Addison-Wesley, 1997, ISBN 0-201-63392-2). */#include "mutex.h"#include <stddef.h>#if TARGET == TARGET_UNIX#include <pthread.h>#if SYSTEM == SYSTEM_TRU64#include <tis.h>#endif /* SYSTEM */#elif TARGET == TARGET_AMIGA#include <proto/exec.h>#include <exec/semaphores.h>#elif TARGET == TARGET_WINDOWS#include <windows.h>#include <winbase.h>#elif TARGET == TARGET_NETWARE#include <nwsemaph.h>#include <nwthread.h>#endif /* TARGET */#if MP_IDENT_SUPPORT#ident "$Id: mutex.c,v 1.18 2002/01/08 20:13:59 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *mutex_id = "$Id: mutex.c,v 1.18 2002/01/08 20:13:59 graeme Exp $";#endif /* MP_IDENT_SUPPORT *//* A mutex provides a way to lock a data structure in an atomic way. */#if TARGET == TARGET_UNIXtypedef pthread_mutex_t mutex;        /* POSIX threads mutex */#elif TARGET == TARGET_AMIGAtypedef struct SignalSemaphore mutex; /* Amiga semaphore */#elif TARGET == TARGET_WINDOWStypedef HANDLE mutex;                 /* Windows handle */#elif TARGET == TARGET_NETWAREtypedef LONG mutex;                   /* Netware handle */#else /* TARGET */typedef int mutex;                    /* No threads support */#endif /* TARGET *//* A recursive mutex allows a thread to relock a mutex that is currently * locked by that thread. */typedef struct recmutex{    mutex guard;         /* guard mutex */    mutex real;          /* actual mutex */    unsigned long owner; /* owning thread */    unsigned long count; /* recursion count */    char init;           /* initialisation flag */}recmutex;#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* We will have to initialise the array of mutex locks at run-time.  This * means that we must find a way of initialising the mutexes before the * mpatrol library is initialised. */static recmutex locks[MT_MAX];#if TARGET == TARGET_UNIX && SYSTEM != SYSTEM_LYNXOS/* We can make use of the POSIX threads function pthread_once() in * order to prevent the mutexes being initialised more than once at * the same time. */static pthread_once_t lockflag = PTHREAD_ONCE_INIT;#endif /* TARGET && SYSTEM *//* Initialise the mpatrol library mutexes.  We're up a brown smelly creek if * any of these functions dynamically allocate memory. */MP_GLOBALvoid__mp_initmutexes(void){    unsigned long i;    for (i = 0; i < MT_MAX; i++)        if (!locks[i].init)        {            locks[i].init = 1;#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_TRU64            tis_mutex_init(&locks[i].guard);            tis_mutex_init(&locks[i].real);#else /* SYSTEM */            pthread_mutex_init(&locks[i].guard, NULL);            pthread_mutex_init(&locks[i].real, NULL);#endif /* SYSTEM */#elif TARGET == TARGET_AMIGA            InitSemaphore(&locks[i].guard);            InitSemaphore(&locks[i].real);#elif TARGET == TARGET_WINDOWS            locks[i].guard = CreateMutex(NULL, 0, NULL);            locks[i].real = CreateMutex(NULL, 0, NULL);#elif TARGET == TARGET_NETWARE            locks[i].guard = OpenLocalSemaphore(1);            locks[i].real = OpenLocalSemaphore(1);#else /* TARGET */            locks[i].guard = 0;            locks[i].real = 0;#endif /* TARGET */            locks[i].owner = 0;            locks[i].count = 0;        }}/* Remove the mpatrol library mutexes.  We're up another one of those creeks * if the mutexes are still locked or are likely to be used in the future. */MP_GLOBALvoid__mp_finimutexes(void){    unsigned long i;    for (i = 0; i < MT_MAX; i++)        if (locks[i].init)        {            locks[i].init = 0;#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_TRU64            tis_mutex_destroy(&locks[i].guard);            tis_mutex_destroy(&locks[i].real);#else /* SYSTEM */            pthread_mutex_destroy(&locks[i].guard);            pthread_mutex_destroy(&locks[i].real);#endif /* SYSTEM */#elif TARGET == TARGET_WINDOWS            CloseHandle(locks[i].guard);            CloseHandle(locks[i].real);#elif TARGET == TARGET_NETWARE            CloseLocalSemaphore(locks[i].guard);            CloseLocalSemaphore(locks[i].real);#else /* TARGET */            locks[i].guard = 0;            locks[i].real = 0;#endif /* TARGET */            locks[i].owner = 0;            locks[i].count = 0;        }}/* Lock an mpatrol library mutex. */staticvoidlockmutex(mutex *m){#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_TRU64    tis_mutex_lock(m);#else /* SYSTEM */    pthread_mutex_lock(m);#endif /* SYSTEM */#elif TARGET == TARGET_AMIGA    ObtainSemaphore(m);#elif TARGET == TARGET_WINDOWS    WaitForSingleObject(*m, INFINITE);#elif TARGET == TARGET_NETWARE    WaitOnLocalSemaphore(*m);#endif /* TARGET */}/* Unlock an mpatrol library mutex. */staticvoidunlockmutex(mutex *m){#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_TRU64    tis_mutex_unlock(m);#else /* SYSTEM */    pthread_mutex_unlock(m);#endif /* SYSTEM */#elif TARGET == TARGET_AMIGA    ReleaseSemaphore(m);#elif TARGET == TARGET_WINDOWS    ReleaseMutex(*m);#elif TARGET == TARGET_NETWARE    SignalLocalSemaphore(*m);#endif /* TARGET */}/* Lock an mpatrol library recursive mutex. */MP_GLOBALvoid__mp_lockmutex(mutextype m){    recmutex *l;    unsigned long i;    l = &locks[m];    i = __mp_threadid();#if TARGET == TARGET_UNIX && SYSTEM != SYSTEM_LYNXOS#if SYSTEM == SYSTEM_TRU64    tis_once(&lockflag, __mp_initmutexes);#else /* SYSTEM */    pthread_once(&lockflag, __mp_initmutexes);#endif /* SYSTEM */#else /* TARGET && SYSTEM */    if (!l->init)        __mp_initmutexes();#endif /* TARGET && SYSTEM */    lockmutex(&l->guard);    if ((l->owner == i) && (l->count > 0))        l->count++;    else    {        unlockmutex(&l->guard);        lockmutex(&l->real);        lockmutex(&l->guard);        l->owner = i;        l->count = 1;    }    unlockmutex(&l->guard);}/* Unlock an mpatrol library recursive mutex. */MP_GLOBALvoid__mp_unlockmutex(mutextype m){    recmutex *l;    unsigned long i;    l = &locks[m];    i = __mp_threadid();    if (l->init)    {        lockmutex(&l->guard);        if ((l->owner == i) && (l->count > 0))        {            l->count--;            if (l->count == 0)            {                unlockmutex(&l->real);                l->owner = 0;            }        }        unlockmutex(&l->guard);    }}/* Return the identifier of the currently running thread. */MP_GLOBALunsigned long__mp_threadid(void){#if TARGET == TARGET_UNIX#if SYSTEM == SYSTEM_TRU64    return (unsigned long) tis_self();#else /* SYSTEM */    return (unsigned long) pthread_self();#endif /* SYSTEM */#elif TARGET == TARGET_AMIGA    return (unsigned long) FindTask(NULL);#elif TARGET == TARGET_WINDOWS    return (unsigned long) GetCurrentThreadId();#elif TARGET == TARGET_NETWARE    return (unsigned long) GetThreadId();#else /* TARGET */    return 0;#endif /* TARGET */}#ifdef __cplusplus}#endif /* __cplusplus */

⌨️ 快捷键说明

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