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

📄 mutex.c

📁 这是leon3处理器的交叉编译链
💻 C
字号:
/* Copyright (C) 1992-2000 the Florida State University   Distributed by the Florida State University under the terms of the   GNU Library General Public License.This file is part of Pthreads.Pthreads is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General PublicLicense as published by the Free Software Foundation (version 2).Pthreads is distributed "AS IS" in the hope that it will beuseful, but WITHOUT ANY WARRANTY; without even the impliedwarranty 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 PublicLicense along with Pthreads; see the file COPYING.  If not, writeto the Free Software Foundation, 675 Mass Ave, Cambridge,MA 02139, USA.Report problems and direct all questions to:  pthreads-bugs@ada.cs.fsu.edu  @(#)mutex.c	3.14 11/8/00*//*  * Functions for the support of mutual exclusion - mutexes and their  * attributes.   */#define _LIBCLOCK_NOT_WEAK#include "internals.h"#include "mutex.h"#ifdef TDI_SUPPORT#include "tdi-aux.h"#endif#include <fsu_pthread/debug.h>#include <asm-leon/elfmacro.h>#include <asm-leon/liblocks.h>/*------------------------------------------------------------*//* * pthread_mutex_lock - Checks are made to see if the mutex is  * currently in use or not.  If the mutex is not in use, then its  * locked. Otherwise the currently executing thread is put in the  * wait queue and a new thread is selected. (Fast mutex_lock without * error checks can be found in pthread_sched.S.) */int __pthread_mutex_lock(mutex)     pthread_mutex_t *mutex;{  register pthread_t p = mac_pthread_self();    PTRACEIN;    if (mutex == NO_MUTEX)    return(EINVAL);  switch (mutex->flags) {  case 1<<PTHREAD_MUTEX_TIMED_NP:    if (mutex->owner == p)      return(EDEADLK);    break;  case 1<<PTHREAD_MUTEX_RECURSIVE_NP:    if (mutex->owner == p) {      mutex->count++;      return 0;    }    break;  default:    return(EINVAL);  }  #ifdef _POSIX_THREADS_PRIO_PROTECT  if (mutex->protocol == PTHREAD_PRIO_PROTECT && p->attr.param.sched_priority > mutex->prioceiling)    return(EINVAL);#endif /* _POSIX_THREADS_PRIO_PROTECT */  SET_KERNEL_FLAG;  SIM_SYSCALL(mutex->lock);  mac_mutex_lock(mutex, p);  CLEAR_KERNEL_FLAG;  return(0);}strong_alias (__pthread_mutex_lock, pthread_mutex_lock)strong_alias (__pthread_mutex_lock, __st_pthread_mutex_lock)/*------------------------------------------------------------*//* * pthread_mutex_trylock - Just try to lock the mutex. If  * lock succeeds return. Otherwise return right away without  * getting the lock. (Fast mutex_trylock without * error checks can be found in pthread_sched.S.) */int __pthread_mutex_trylock(mutex)     pthread_mutex_t *mutex;{pthread_t p = mac_pthread_self();  PTRACEIN;  if (mutex == NO_MUTEX)    return(EINVAL);  switch (mutex->flags) {  case 1<<PTHREAD_MUTEX_TIMED_NP:    if (mutex->owner == p)      return(EDEADLK);    break;  case 1<<PTHREAD_MUTEX_RECURSIVE_NP:    if (mutex->owner == p) {      mutex->count++;      return 0;    }    break;  default:    return(EINVAL);  }  #ifdef _POSIX_THREADS_PRIO_PROTECT  if (mutex->protocol == PTHREAD_PRIO_PROTECT &&      p->attr.param.sched_priority > mutex->prioceiling)    return(EINVAL);#endif /* _POSIX_THREADS_PRIO_PROTECT */  SET_KERNEL_FLAG;  if (mutex->lock) {    CLEAR_KERNEL_FLAG;    return(EBUSY);  }   mutex->lock = TRUE;  mutex->owner = p;  mutex->count = 0;#ifdef NOERR_CHECK   mac_change_lock_prio(mutex, p); #else #ifdef _POSIX_THREADS_PRIO_PROTECT  if (mutex->protocol == PTHREAD_PRIO_PROTECT)    mac_change_lock_prio(mutex, p);#endif                  #endif   CLEAR_KERNEL_FLAG;  return(0);}strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)strong_alias (__pthread_mutex_trylock, __st_pthread_mutex_trylock)/*------------------------------------------------------------*//* * pthread_mutex_unlock - Called by the owner of mutex to release * the mutex. (Fast mutex_unlock without * error checks can be found in pthread_sched.S.) */int __pthread_mutex_unlock(mutex)     pthread_mutex_t *mutex;{pthread_t p = mac_pthread_self();  PTRACEIN;  if (mutex == NO_MUTEX)    return(EINVAL);  if (mutex->owner != mac_pthread_self())    return(EPERM );  switch (mutex->flags) {  case 1<<PTHREAD_MUTEX_TIMED_NP:    break;  case 1<<PTHREAD_MUTEX_RECURSIVE_NP:    if (mutex->count > 0) {      mutex->count--;      return 0;    }    break;  default:    return(EINVAL);  }  SET_KERNEL_FLAG;  SIM_SYSCALL(mutex->queue.head != mutex->queue.tail);  mac_mutex_unlock(mutex, p,  /* NULL */);  CLEAR_KERNEL_FLAG;  return(0);}strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)strong_alias (__pthread_mutex_unlock, __st_pthread_mutex_unlock)/*------------------------------------------------------------*//* * pthread_mutex_init - Initialize the mutex and at the same time  * ensure that it's usaable.  Set the attribute values from attr  * specified. No check is made to see if the attributes are right  * as yet. */int __pthread_mutex_init(mutex, attr)     pthread_mutex_t *mutex;     pthread_mutexattr_t *attr;{  PTRACEIN;  if (mutex == NO_MUTEX)    return(EINVAL);#ifdef _POSIX_THREADS_PRIO_PROTECT#ifndef NOERR_CHECK  if (attr && ((!attr->flags) ||	       (!((attr->protocol == PTHREAD_PRIO_NONE) ||		  (attr->protocol == PTHREAD_PRIO_INHERIT) ||		  (attr->protocol == PTHREAD_PRIO_PROTECT))) ||	       (attr->prioceiling < 0))) {    PDEBUG(PDBG_ASSERT,"EINVAL: flags: %d protocol: %d ceil: %d\n", attr->flags, attr->protocol, attr->prioceiling);    return(EINVAL);  }#endif#endif  if (!attr)    attr = &pthread_mutexattr_default;  mutex->owner = NO_PTHREAD;  mutex->flags = attr->flags;  pthread_queue_init(&mutex->queue);#ifdef _POSIX_THREADS_PRIO_PROTECT  mutex->prioceiling = attr->prioceiling;  mutex->protocol = attr->protocol;#endif  mutex->lock = FALSE;  return(0);}  strong_alias (__pthread_mutex_init, pthread_mutex_init)strong_alias (__pthread_mutex_init, __st_pthread_mutex_init)/*------------------------------------------------------------*//* * pthread_mutex_destroy - Destroys the mutex. */int __pthread_mutex_destroy(mutex)      pthread_mutex_t *mutex;{  PTRACEIN;  if (mutex == NO_MUTEX)    return(EINVAL);  /*   * free mutex only if not locked and not associated with any cond var   */#ifdef NOERR_CHECK  if (pthread_test_and_set(&mutex->lock))    return(EBUSY);#else /* !NOERR_CHECK */  SET_KERNEL_FLAG;  if (mutex->lock) {    CLEAR_KERNEL_FLAG;    return(EBUSY);  }  CLEAR_KERNEL_FLAG;#endif /* !NOERR_CHECK */  mutex->flags = 0;  return(0);}strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)strong_alias (__pthread_mutex_destroy, __st_pthread_mutex_destroy)/*------------------------------------------------------------*//* * pthread_mutex_setprioceiling - locks the mutex, changes the * mutex's priority ceiling and releases the mutex. */int pthread_mutex_setprioceiling(mutex, prioceiling, old_prioceiling)pthread_mutex_t *mutex;int prioceiling;int *old_prioceiling;{  PTRACEIN;  if (mutex == NO_MUTEX || !mutex->flags || !old_prioceiling)    return(EINVAL);#ifdef _POSIX_THREADS_PRIO_PROTECT  if (prioceiling >= MIN_PRIORITY && prioceiling <= MAX_PRIORITY) {    if (!pthread_mutex_trylock(mutex)) {      if (old_prioceiling) {	*old_prioceiling = mutex->prioceiling;      }      mutex->prioceiling = prioceiling;      pthread_mutex_unlock(mutex);      return(ENOSYS);    }    else      return(EPERM);  }  else    return(EINVAL);#else  return(ENOTSUP);#endif}/*------------------------------------------------------------*//* * pthread_mutex_getprioceiling - Returns the current priority * ceiling of the mutex in "prioceiling". */int pthread_mutex_getprioceiling(mutex, prioceiling)pthread_mutex_t *mutex;int *prioceiling;{  PTRACEIN;  if (mutex == NO_MUTEX || !mutex->flags || !prioceiling)    return(EINVAL);  #ifdef _POSIX_THREADS_PRIO_PROTECT  if (mutex->prioceiling >= MIN_PRIORITY &&      mutex->prioceiling <= MAX_PRIORITY) {    *prioceiling = mutex->prioceiling;    return(0);  }  else    return(EINVAL);#else  return(ENOTSUP);#endif}/*------------------------------------------------------------*//* * pthread_mutexattr_init - Initializes the mutex attribute object * with default values. */int __pthread_mutexattr_init(attr)pthread_mutexattr_t *attr;{  PTRACEIN;  if (!attr)    return(EINVAL);  attr->flags = TRUE;#ifdef _POSIX_THREADS_PRIO_PROTECT  attr->prioceiling = DEFAULT_PRIORITY;  attr->protocol = PTHREAD_PRIO_NONE;#endif  return(0);}strong_alias (__pthread_mutexattr_init, pthread_mutexattr_init)strong_alias (__pthread_mutexattr_init, __st_pthread_mutexattr_init)/*------------------------------------------------------------*//* * pthread_mutexattr_destroy - Destroys the mutex attribute object. */int __pthread_mutexattr_destroy(attr)pthread_mutexattr_t *attr;{  PTRACEIN;  if (!attr || !attr->flags)    return(EINVAL);  attr->flags = FALSE;#ifdef _POSIX_THREADS_PRIO_PROTECT  attr->prioceiling = DEFAULT_PRIORITY;  attr->protocol = PTHREAD_PRIO_NONE;#endif    return(0);}strong_alias (__pthread_mutexattr_destroy, pthread_mutexattr_destroy)strong_alias (__pthread_mutexattr_destroy, __st_pthread_mutexattr_destroy)/*------------------------------------------------------------*//* * pthread_mutexattr_setprotocol - Sets the protocol (value can be * PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT or PTHREAD_PRIO_PROTECT) * for the mutex attr. */int pthread_mutexattr_setprotocol(attr,protocol)pthread_mutexattr_t *attr;pthread_protocol_t protocol;{  PTRACEIN;    if (!attr || !attr->flags)    return(EINVAL);#ifndef _POSIX_THREADS_PRIO_PROTECT  return(ENOSYS);#else  if (protocol < PTHREAD_PRIO_NONE || protocol > PTHREAD_PRIO_PROTECT)    return(EINVAL);  if (protocol == PTHREAD_PRIO_INHERIT)    return(ENOTSUP);  attr->protocol = protocol;  return(0);#endif}/*------------------------------------------------------------*//* * pthread_mutexattr_getprotocol - Gets the current protcol. */int pthread_mutexattr_getprotocol(attr, protocol)pthread_mutexattr_t *attr;int *protocol;{  PTRACEIN;  if (!attr || !attr->flags || !protocol)    return(EINVAL);#ifdef _POSIX_THREADS_PRIO_PROTECT  *protocol = attr->protocol;  return(0);#else  return(ENOSYS);#endif}/*------------------------------------------------------------*//* * pthread_mutexattr_setprioceiling - Sets the priority ceiling * for the mutex attribute object. */int pthread_mutexattr_setprioceiling(attr, prioceiling)pthread_mutexattr_t *attr;int prioceiling;{  PTRACEIN;  if (!attr || !attr->flags)    return(EINVAL);#ifndef _POSIX_THREADS_PRIO_PROTECT  return(ENOSYS);#else  if (prioceiling > MAX_PRIORITY || prioceiling < MIN_PRIORITY)    return(EINVAL);  attr->prioceiling = prioceiling;  return(0);#endif}/*------------------------------------------------------------*//* * pthread_mutexattr_getprioceiling - returns the current priority * ceiling of the mutex attribute object. */int pthread_mutexattr_getprioceiling(attr, prioceiling)pthread_mutexattr_t *attr;int *prioceiling;{  PTRACEIN;  if (!attr || !attr->flags || !prioceiling)    return(EINVAL);#ifdef _POSIX_THREADS_PRIO_PROTECT  *prioceiling = attr->prioceiling;  return(0);#else  return(ENOSYS);#endif}/*------------------------------------------------------------*//* * pthread_mutexattr_getpshared - Not Implemented. Returns ENOSYS. */ int pthread_mutexattr_getpshared(attr, pshared)pthread_mutexattr_t *attr;int *pshared;{  PTRACEIN;  return(ENOSYS);} /*------------------------------------------------------------*//* * pthread_mutexattr_setpshared - Not Implemented. Returns ENOSYS. */ int pthread_mutexattr_setpshared(attr, pshared)pthread_mutexattr_t *attr;int pshared;{  PTRACEIN;  return(ENOSYS);}int __pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind){  PTRACEIN;  switch (kind) {  case PTHREAD_MUTEX_TIMED_NP:    PDEBUG(PDBG_MUTEX,"PTHREAD_MUTEX_TIMED_NP");    break;  case PTHREAD_MUTEX_RECURSIVE_NP:    PDEBUG(PDBG_MUTEX,"PTHREAD_MUTEX_RECURSIVE_NP");    break;  default:      return EINVAL;  }    attr->flags = 1 << kind;  return 0;}weak_alias   (__pthread_mutexattr_settype, pthread_mutexattr_settype)strong_alias ( __pthread_mutexattr_settype, __pthread_mutexattr_setkind_np)weak_alias   (__pthread_mutexattr_setkind_np, pthread_mutexattr_setkind_np)strong_alias ( __pthread_mutexattr_settype, __st_pthread_mutexattr_setkind_np)void pthread_leonbare_lockinit() {  __lbst_pthread_mutex_init = __pthread_mutex_init;  __lbst_pthread_mutex_destroy = __pthread_mutex_destroy;  __lbst_pthread_mutex_trylock = __pthread_mutex_trylock;  __lbst_pthread_mutex_lock = __pthread_mutex_lock;  __lbst_pthread_mutex_unlock = __pthread_mutex_unlock;  __lbst_pthread_mutexattr_init = __pthread_mutexattr_init;  __lbst_pthread_mutexattr_destroy = __pthread_mutexattr_destroy;  __lbst_pthread_mutexattr_settype = __pthread_mutexattr_settype;}

⌨️ 快捷键说明

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