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

📄 mutex.c

📁 多线程库
💻 C
字号:
//// class mutex//// Mutes is a semaphore, that can be used by two threads to mutually// exclude the other.  To ensure uniqe access to memory.#include <thread_mutex.h>#include <thread_lists.h>#include "wait_queue.h"#include "shared.h"extern "C" {#	include <errno.h>#       include <unistd.h>};char *mutex::m_project = 0;mutex::mutex(attributes::scope p_scope){  init( p_scope );}mutex::mutex(){  init( attributes::process_private );}mutex::~mutex(){  if ( _m ) {    delete m_waiting;    if ( m_scope == attributes::process_private )      delete _m;    else       shared_mem::share.dealloc( _m );    _m = 0;  }}void mutex::init(attributes::scope p_scope){  m_id = -1;  if ( p_scope == attributes::process_private ) {    _m            = new storage;    _m->m_magic   = 0;  } else {   m_id           = shared_mem::share.create_proj( m_project );   _m             = (storage *)shared_mem::share.alloc( sizeof(storage),m_id );   assert( _m != (storage *)-1 );  }  if ( _m->m_magic != 0x212612 ) {    _m->m_kind    = fast;    _m->m_count   = 0;    _m->m_owner   = -1;    _m->m_magic   = 0x212612;  }  m_waiting       = new wait_queue( m_id );  m_scope         = p_scope;}attributes::scope mutex::scope(){  return m_scope;}void mutex::release(){  _m->m_owner = 0;  _m->m_count = 0;}int mutex::acquire(){  _m->m_owner = getpid();  _m->m_count++;  return 0;}//// kind//// set the mutex kind.int mutex::kind(mutex_kind _kind){  if (_kind != mutex::recursive && _kind != mutex::fast)    return EINVAL;  _m->m_kind = _kind;  return 0;}//// kind//// get the mutex kind.int mutex::kind(){  return _m->m_kind;}//// trylock//// try and lock the mutex.//// return//   EBUSY  - the mutex is locked by another.//   EINVAL - the mutex is of an unknown kind.//   0      - successful.int mutex::trylock(){  int rval = EBUSY;  _m->m_spinlock.acquire();  switch(_m->m_kind) {  case mutex::fast:    if ( _m->m_count == 0 )      rval = acquire();    break;  case mutex::recursive:    if (_m->m_count == 0 || _m->m_owner == getpid())      rval = acquire();    break;  case mutex::errorcheck:    if ( _m->m_count == 0 )      rval = acquire();    else      if ( _m->m_owner == getpid() )	rval = EDEADLK;    break;  default:    rval = EINVAL;    break;  }  _m->m_spinlock.release();  return rval;}//// lock//// Try and lock the mutex.  If unsuccessful, suspend the calling// process, until the mutex is available.int mutex::lock(){  int rval = EBUSY;  while(rval == EBUSY) {    if ((rval = trylock()) == EBUSY)      m_waiting->suspend_me();  }  return rval;}//// unlock//// unlock the mutex, and restart any threads, that are waiting// on it.int mutex::unlock(){  int rval = 0;  _m->m_spinlock.acquire();  switch(_m->m_kind) {  case mutex::fast:    if ( _m->m_owner == getpid() )      release();    else      rval = EBUSY;    break;  case mutex::recursive:    if ( _m->m_owner == getpid() ) {      if (--_m->m_count <= 1)	release();    } else      rval = EBUSY;    break;  case mutex::errorcheck:    if ( _m->m_count == 0 || _m->m_owner != getpid() )      rval = EPERM;    else      release();    break;  default:    rval = EINVAL;  }  _m->m_spinlock.release();  if ( rval == 0 )    m_waiting->wake_up();  return rval;}//// project_part//// change the project partvoidmutex::project_part(const char *p_part){  if ( m_project == 0 )    m_project = new char[80];  m_project[0] = 0;  if ( p_part )    strcpy( m_project,p_part );}

⌨️ 快捷键说明

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