thr_rwlock.c 4.42 KB
Newer Older
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
1 2 3 4 5 6 7 8
/* Copyright (C) 2000 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
bk@work.mysql.com's avatar
bk@work.mysql.com committed
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
monty@hundin.mysql.fi's avatar
monty@hundin.mysql.fi committed
10 11 12 13 14 15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
16 17 18 19 20

/* Synchronization - readers / writer thread locks */

#include "mysys_priv.h"
#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
21
#include <errno.h>
bk@work.mysql.com's avatar
bk@work.mysql.com committed
22 23

/*
24 25 26 27
  Source base from Sun Microsystems SPILT, simplified for MySQL use
  -- Joshua Chamas
  Some cleanup and additional code by Monty
*/
bk@work.mysql.com's avatar
bk@work.mysql.com committed
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

/*
*  Multithreaded Demo Source
*
*  Copyright (C) 1995 by Sun Microsystems, Inc.
*  All rights reserved.
*
*  This file is a product of SunSoft, Inc. and is provided for
*  unrestricted use provided that this legend is included on all
*  media and as a part of the software program in whole or part.
*  Users may copy, modify or distribute this file at will.
*
*  THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
*  THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
*  PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
*  This file is provided with no support and without any obligation on the
*  part of SunSoft, Inc. to assist in its use, correction, modification or
*  enhancement.
*
*  SUNSOFT AND SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT
*  TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS
*  FILE OR ANY PART THEREOF.
*
*  IN NO EVENT WILL SUNSOFT OR SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY
*  LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
*  DAMAGES, EVEN IF THEY HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
*  DAMAGES.
*
*  SunSoft, Inc.
*  2550 Garcia Avenue
*  Mountain View, California  94043
*/

62
int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
bk@work.mysql.com's avatar
bk@work.mysql.com committed
63 64 65
{
  pthread_condattr_t	cond_attr;

66
  pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
67 68 69 70 71 72 73 74
  pthread_condattr_init( &cond_attr );
  pthread_cond_init( &rwp->readers, &cond_attr );
  pthread_cond_init( &rwp->writers, &cond_attr );
  pthread_condattr_destroy(&cond_attr);

  rwp->state	= 0;
  rwp->waiters	= 0;

75
  return(0);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
76 77
}

78 79 80

int my_rwlock_destroy(rw_lock_t *rwp)
{
bk@work.mysql.com's avatar
bk@work.mysql.com committed
81 82 83
  pthread_mutex_destroy( &rwp->lock );
  pthread_cond_destroy( &rwp->readers );
  pthread_cond_destroy( &rwp->writers );
84
  return(0);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
85 86
}

87 88 89

int my_rw_rdlock(rw_lock_t *rwp)
{
bk@work.mysql.com's avatar
bk@work.mysql.com committed
90 91
  pthread_mutex_lock(&rwp->lock);

92
  /* active or queued writers */
93
  while (( rwp->state < 0 ) || rwp->waiters)
bk@work.mysql.com's avatar
bk@work.mysql.com committed
94 95 96 97
    pthread_cond_wait( &rwp->readers, &rwp->lock);

  rwp->state++;
  pthread_mutex_unlock(&rwp->lock);
98 99
  return(0);
}
bk@work.mysql.com's avatar
bk@work.mysql.com committed
100

101 102 103 104 105 106 107 108 109 110 111 112 113
int my_rw_tryrdlock(rw_lock_t *rwp)
{
  int res;
  pthread_mutex_lock(&rwp->lock);
  if ((rwp->state < 0 ) || rwp->waiters)
    res= EBUSY;					/* Can't get lock */
  else
  {
    res=0;
    rwp->state++;
  }
  pthread_mutex_unlock(&rwp->lock);
  return(res);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
114 115
}

116

117 118
int my_rw_wrlock(rw_lock_t *rwp)
{
bk@work.mysql.com's avatar
bk@work.mysql.com committed
119
  pthread_mutex_lock(&rwp->lock);
120
  rwp->waiters++;				/* another writer queued */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
121

122 123
  while (rwp->state)
    pthread_cond_wait(&rwp->writers, &rwp->lock);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
124
  rwp->state	= -1;
125 126
  rwp->waiters--;
  pthread_mutex_unlock(&rwp->lock);
127
  return(0);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
128 129
}

130

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
int my_rw_trywrlock(rw_lock_t *rwp)
{
  int res;
  pthread_mutex_lock(&rwp->lock);
  if (rwp->state)
    res= EBUSY;					/* Can't get lock */    
  else
  {
    res=0;
    rwp->state	= -1;
  }
  pthread_mutex_unlock(&rwp->lock);
  return(res);
}


147 148
int my_rw_unlock(rw_lock_t *rwp)
{
bk@work.mysql.com's avatar
bk@work.mysql.com committed
149 150 151 152
  DBUG_PRINT("rw_unlock",
	     ("state: %d waiters: %d", rwp->state, rwp->waiters));
  pthread_mutex_lock(&rwp->lock);

153 154 155
  if (rwp->state == -1)		/* writer releasing */
  {
    rwp->state= 0;		/* mark as available */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
156

157
    if ( rwp->waiters )		/* writers queued */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
158 159 160
      pthread_cond_signal( &rwp->writers );
    else
      pthread_cond_broadcast( &rwp->readers );
161 162 163
  }
  else
  {
164
    if ( --rwp->state == 0 )	/* no more readers */
bk@work.mysql.com's avatar
bk@work.mysql.com committed
165 166 167 168
      pthread_cond_signal( &rwp->writers );
  }

  pthread_mutex_unlock( &rwp->lock );
169
  return(0);
bk@work.mysql.com's avatar
bk@work.mysql.com committed
170 171 172
}

#endif