xref: /titanic_44/usr/src/lib/sun_fc/common/Lockable.cc (revision f3aaec0a97c3584095582719a0149d5e94c06ea2)
1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
22fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte 
26fcf3ce44SJohn Forte 
27fcf3ce44SJohn Forte #include "Lockable.h"
28fcf3ce44SJohn Forte #include <iostream>
29fcf3ce44SJohn Forte #include <cstdio>
30fcf3ce44SJohn Forte #include <cerrno>
31fcf3ce44SJohn Forte #include <unistd.h>
32*f3aaec0aSRichard Lowe #include <cstring>
33fcf3ce44SJohn Forte 
34fcf3ce44SJohn Forte using namespace std;
35fcf3ce44SJohn Forte 
36fcf3ce44SJohn Forte #define	    DEADLOCK_WARNING 10
37fcf3ce44SJohn Forte #define	    LOCK_SLEEP 1
38fcf3ce44SJohn Forte 
39fcf3ce44SJohn Forte /**
40fcf3ce44SJohn Forte  * @memo	    Create a lockable instance and initialize internal locks
41fcf3ce44SJohn Forte  */
Lockable()42fcf3ce44SJohn Forte Lockable::Lockable() {
43fcf3ce44SJohn Forte 	if (pthread_mutex_init(&mutex, NULL)) {
44fcf3ce44SJohn Forte 	}
45fcf3ce44SJohn Forte }
46fcf3ce44SJohn Forte 
47fcf3ce44SJohn Forte /**
48fcf3ce44SJohn Forte  * @memo	    Free up a lockable instance
49fcf3ce44SJohn Forte  */
~Lockable()50fcf3ce44SJohn Forte Lockable::~Lockable() {
51fcf3ce44SJohn Forte 	if (pthread_mutex_destroy(&mutex)) {
52fcf3ce44SJohn Forte 	}
53fcf3ce44SJohn Forte }
54fcf3ce44SJohn Forte 
55fcf3ce44SJohn Forte /**
56fcf3ce44SJohn Forte  * @memo	    Unlock the instance
57fcf3ce44SJohn Forte  * @precondition    This thread must have locked the instance
58fcf3ce44SJohn Forte  * @postcondition   The instance will be unlocked
59fcf3ce44SJohn Forte  */
unlock()60fcf3ce44SJohn Forte void Lockable::unlock() {
61fcf3ce44SJohn Forte 	unlock(&mutex);
62fcf3ce44SJohn Forte }
63fcf3ce44SJohn Forte 
64fcf3ce44SJohn Forte /**
65fcf3ce44SJohn Forte  * @memo	    Unlock a given mutex lock
66fcf3ce44SJohn Forte  * @precondition    The lock must be held by this thread
67fcf3ce44SJohn Forte  * @postcondition   The lock will be released
68fcf3ce44SJohn Forte  * @param	    myMutex The lock to unlock
69fcf3ce44SJohn Forte  */
unlock(pthread_mutex_t * myMutex)70fcf3ce44SJohn Forte void Lockable::unlock(pthread_mutex_t *myMutex) {
71fcf3ce44SJohn Forte 	pthread_mutex_unlock(myMutex);
72fcf3ce44SJohn Forte }
73fcf3ce44SJohn Forte 
74fcf3ce44SJohn Forte /**
75fcf3ce44SJohn Forte  * @memo	    Lock the instance
76fcf3ce44SJohn Forte  * @postcondition   The lock will be held by this thread.
77fcf3ce44SJohn Forte  */
lock()78fcf3ce44SJohn Forte void Lockable::lock() {
79fcf3ce44SJohn Forte 	lock(&mutex);
80fcf3ce44SJohn Forte }
81fcf3ce44SJohn Forte 
82fcf3ce44SJohn Forte /**
83fcf3ce44SJohn Forte  * @memo	    Lock the given mutex lock
84fcf3ce44SJohn Forte  * @postcondition   The lock will be held by this thread
85fcf3ce44SJohn Forte  * @param	    myMutex The mutex lock to take
86fcf3ce44SJohn Forte  */
lock(pthread_mutex_t * myMutex)87fcf3ce44SJohn Forte void Lockable::lock(pthread_mutex_t *myMutex) {
88fcf3ce44SJohn Forte 	int status;
89fcf3ce44SJohn Forte 	int loop = 0;
90fcf3ce44SJohn Forte 	do {
91fcf3ce44SJohn Forte 	    loop++;
92fcf3ce44SJohn Forte 	    status = pthread_mutex_trylock(myMutex);
93fcf3ce44SJohn Forte 	    if (status) {
94fcf3ce44SJohn Forte 		switch (pthread_mutex_trylock(myMutex)) {
95fcf3ce44SJohn Forte 		case EFAULT:
96fcf3ce44SJohn Forte 		    cerr << "Lock failed: Fault" << endl;
97fcf3ce44SJohn Forte 		    break;
98fcf3ce44SJohn Forte 		case EINVAL:
99fcf3ce44SJohn Forte 		    cerr << "Lock failed: Invalid" << endl;
100fcf3ce44SJohn Forte 		    break;
101fcf3ce44SJohn Forte 		case EBUSY:
102fcf3ce44SJohn Forte 		    if (loop > DEADLOCK_WARNING) {
103fcf3ce44SJohn Forte 			cerr << "Lock failed: Deadlock" << endl;
104fcf3ce44SJohn Forte 		    }
105fcf3ce44SJohn Forte 		    break;
106fcf3ce44SJohn Forte 		case EOWNERDEAD:
107fcf3ce44SJohn Forte 		    cerr << "Lock failed: Owner died" << endl;
108fcf3ce44SJohn Forte 		    break;
109fcf3ce44SJohn Forte 		case ELOCKUNMAPPED:
110fcf3ce44SJohn Forte 		    cerr << "Lock failed: Unmapped" << endl;
111fcf3ce44SJohn Forte 		    break;
112fcf3ce44SJohn Forte 		case ENOTRECOVERABLE:
113fcf3ce44SJohn Forte 		    cerr << "Lock failed: not recoverable" << endl;
114fcf3ce44SJohn Forte 		default:
115fcf3ce44SJohn Forte 		    if (loop > DEADLOCK_WARNING) {
116fcf3ce44SJohn Forte 			cerr << "Lock failed: " <<strerror(status) << endl;
117fcf3ce44SJohn Forte 			break;
118fcf3ce44SJohn Forte 		    }
119fcf3ce44SJohn Forte 		}
120fcf3ce44SJohn Forte 	    } else {
121fcf3ce44SJohn Forte 		break; // Lock taken succesfully
122fcf3ce44SJohn Forte 	    }
123fcf3ce44SJohn Forte 	    sleep(LOCK_SLEEP);
124fcf3ce44SJohn Forte 	} while (status);
125fcf3ce44SJohn Forte }
126