📄 mutex.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 + -