* Lock for write access, wait until locked (or error).
* Multiple nested write locking is permitted.
*/
-int devlock::writelock(int areason, bool acan_steal)
+int devlock::writelock(int areason, bool acan_take)
{
devlock *rwl = this;
int stat;
lmgr_post_lock();
}
rwl->reason = areason;
- rwl->can_steal = acan_steal;
+ rwl->can_take = acan_take;
pthread_mutex_unlock(&rwl->mutex);
return stat;
}
return (stat == 0 ? stat2 : stat);
}
+int devlock::take_lock(take_lock_t *hold, int areason)
+{
+ int stat;
+
+ if (valid != DEVLOCK_VALID) {
+ return EINVAL;
+ }
+ if ((stat = pthread_mutex_lock(&mutex)) != 0) {
+ return stat;
+ }
+ hold->reason = reason;
+ hold->prev_reason = prev_reason;
+ hold->writer_id = writer_id;
+ reason = areason;
+ writer_id = pthread_self();
+ stat = pthread_mutex_unlock(&mutex);
+ return stat;
+}
+
+int devlock::return_lock(take_lock_t *hold)
+{
+ int stat, stat2;
+
+ if (valid != DEVLOCK_VALID) {
+ return EINVAL;
+ }
+ if ((stat = pthread_mutex_lock(&mutex)) != 0) {
+ return stat;
+ }
+ reason = hold->reason;
+ prev_reason = hold->prev_reason;
+ writer_id = hold->writer_id;
+ writer_id = pthread_self();
+ stat2 = pthread_mutex_unlock(&mutex);
+ if (w_active || w_wait) {
+ stat = pthread_cond_broadcast(&write);
+ }
+ return (stat == 0 ? stat2 : stat);
+
+}
+
#ifdef TEST_RWLOCK
#define THREADS 300
#ifndef __DEVLOCK_H
#define __DEVLOCK_H 1
+struct take_lock_t {
+ pthread_t writer_id; /* id of writer */
+ int reason; /* save reason */
+ int prev_reason; /* previous reason */
+};
+
+
class devlock {
private:
pthread_mutex_t mutex;
int r_wait; /* readers waiting */
int w_wait; /* writers waiting */
int reason; /* reason for lock */
- bool can_steal; /* can the lock be stolen? */
+ int prev_reason; /* previous reason */
+ bool can_take; /* can the lock be taken? */
public:
- devlock(int reason, bool can_steal=false);
+ devlock(int reason, bool can_take=false);
~devlock();
int init(int priority);
int destroy();
+ int take_lock(take_lock_t *hold, int reason);
+ int return_lock(take_lock_t *hold);
+ void new_reason(int nreason) { prev_reason = reason; reason = nreason; };
+ void restore_reason() { reason = prev_reason; prev_reason = 0; };
- int writelock(int reason, bool can_steal=false);
+ int writelock(int reason, bool can_take=false);
int writetrylock();
int writeunlock();
void write_release();