Home | History | Annotate | Download | only in ffsb-6.0-rc2
      1 /*
      2  *   Copyright (c) International Business Machines Corp., 2001-2004
      3  *
      4  *   This program is free software;  you can redistribute it and/or modify
      5  *   it under the terms of the GNU General Public License as published by
      6  *   the Free Software Foundation; either version 2 of the License, or
      7  *   (at your option) any later version.
      8  *
      9  *   This program is distributed in the hope that it will be useful,
     10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  *   the GNU General Public License for more details.
     13  *
     14  *   You should have received a copy of the GNU General Public License
     15  *   along with this program;  if not, write to the Free Software
     16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  */
     18 #include <pthread.h>
     19 #include <stdlib.h>
     20 #include <stdio.h>
     21 
     22 /* #define RWDEBUG 1 */
     23 #include "config.h"
     24 #include "rwlock.h"
     25 
     26 void init_rwlock(struct rwlock *rw)
     27 {
     28 	rw->n_readers = 0;
     29 	pthread_mutex_init(&rw->plock, NULL);
     30 	pthread_cond_init(&rw->pcond, NULL);
     31 #ifdef RWDEBUG
     32 	rw->n_write_waiting = 0;
     33 	rw->n_read_waiting = 0;
     34 	rw->writer_tid = -1;
     35 #endif
     36 }
     37 
     38 void rw_lock_read(struct rwlock *rw)
     39 {
     40 	pthread_mutex_lock(&rw->plock);
     41 #ifdef RWDEBUG
     42 	rw->n_read_waiting++;
     43 #endif
     44 	while (rw->n_readers < 0)
     45 		pthread_cond_wait(&rw->pcond, &rw->plock);
     46 	rw->n_readers++;
     47 #ifdef RWDEBUG
     48 	rw->n_read_waiting--;
     49 #endif
     50 	pthread_mutex_unlock(&rw->plock);
     51 }
     52 
     53 void rw_lock_write(struct rwlock *rw)
     54 {
     55 	pthread_mutex_lock(&rw->plock);
     56 #ifdef RWDEBUG
     57 	rw->n_write_waiting++;
     58 #endif
     59 	while (rw->n_readers != 0)
     60 		pthread_cond_wait(&rw->pcond, &rw->plock);
     61 	rw->n_readers = -1;
     62 #ifdef RWDEBUG
     63 	rw->n_write_waiting--;
     64 	rw->writer_tid = (int)pthread_self();
     65 #endif
     66 	pthread_mutex_unlock(&rw->plock);
     67 
     68 }
     69 
     70 void rw_unlock_read(struct rwlock *rw)
     71 {
     72 	pthread_mutex_lock(&rw->plock);
     73 	rw->n_readers -= 1;
     74 	pthread_cond_signal(&rw->pcond);
     75 	pthread_mutex_unlock(&rw->plock);
     76 }
     77 
     78 void rw_unlock_write(struct rwlock *rw)
     79 {
     80 	pthread_mutex_lock(&rw->plock);
     81 	rw->n_readers = 0;
     82 	pthread_cond_broadcast(&rw->pcond);
     83 	pthread_mutex_unlock(&rw->plock);
     84 }
     85 
     86 int rw_trylock_read(struct rwlock *rw)
     87 {
     88 	int ret = 1;
     89 	pthread_mutex_lock(&rw->plock);
     90 	if (rw->n_readers >= 0) {
     91 		rw->n_readers++;
     92 		ret = 0;
     93 	}
     94 	pthread_mutex_unlock(&rw->plock);
     95 	return ret;
     96 }
     97 
     98 int rw_trylock_write(struct rwlock *rw)
     99 {
    100 	int ret = 1;
    101 	pthread_mutex_lock(&rw->plock);
    102 	if (rw->n_readers == 0) {
    103 		ret = 0;
    104 		rw->n_readers = -1;
    105 	}
    106 	pthread_mutex_unlock(&rw->plock);
    107 	return ret;
    108 }
    109