00001 /*[ 00002 * Copyright (c) 2007 Integration Engineering Laboratory 00003 University of California, Davis 00004 * 00005 * Permission to use, copy, and distribute this software and its 00006 * documentation for any purpose with or without fee is hereby granted, 00007 * provided that the above copyright notice appear in all copies and 00008 * that both that copyright notice and this permission notice appear 00009 * in supporting documentation. 00010 * 00011 * Permission to modify the software is granted, but not the right to 00012 * distribute the complete modified source code. Modifications are to 00013 * be distributed as patches to the released version. Permission to 00014 * distribute binaries produced by compiling modified sources is granted, 00015 * provided you 00016 * 1. distribute the corresponding source modifications from the 00017 * released version in the form of a patch file along with the binaries, 00018 * 2. add special version identification to distinguish your version 00019 * in addition to the base release version number, 00020 * 3. provide your name and address as the primary contact for the 00021 * support of your modified version, and 00022 * 4. retain our contact information in regard to use of the base 00023 * software. 00024 * Permission to distribute the released version of the source code along 00025 * with corresponding source modifications in the form of a patch file is 00026 * granted with same provisions 2 through 4 for binary distributions. 00027 * 00028 * This software is provided "as is" without express or implied warranty 00029 * to the extent permitted by applicable law. 00030 ]*/ 00031 00032 #include <stdio.h> 00033 #include <stdlib.h> 00034 #include "include/macros.h" 00035 #include "include/mc_error.h" 00036 #include "include/mc_rwlock.h" 00037 00038 int mc_rwlock_init(mc_rwlock_p rwlock) 00039 { 00040 /* Init values */ 00041 rwlock->num_readers = 0; 00042 rwlock->write_flag = 0; 00043 rwlock->write_request = 0; 00044 00045 /* Alloc sync */ 00046 rwlock->lock = (MUTEX_T*)malloc(sizeof(MUTEX_T)); 00047 CHECK_NULL(rwlock->lock, return MC_ERR_MEMORY;); 00048 rwlock->cond = (COND_T*)malloc(sizeof(COND_T)); 00049 CHECK_NULL(rwlock->cond, return MC_ERR_MEMORY;); 00050 00051 /* Init sync */ 00052 MUTEX_INIT(rwlock->lock); 00053 COND_INIT(rwlock->cond); 00054 00055 return 0; 00056 } 00057 00058 int mc_rwlock_destroy(mc_rwlock_p rwlock) 00059 { 00060 /* Destroy mutex/conds */ 00061 MUTEX_DESTROY(rwlock->lock); 00062 COND_DESTROY(rwlock->cond); 00063 00064 /* De-alloc */ 00065 free(rwlock->lock); 00066 free(rwlock->cond); 00067 00068 return 0; 00069 } 00070 00071 int mc_rwlock_rdlock(mc_rwlock_p rwlock) 00072 { 00073 MUTEX_LOCK(rwlock->lock); 00074 while ( 00075 (rwlock->write_flag != 0) || 00076 (rwlock->write_request != 0) 00077 ) 00078 { 00079 COND_WAIT(rwlock->cond, rwlock->lock); 00080 } 00081 rwlock->num_readers++; 00082 MUTEX_UNLOCK(rwlock->lock); 00083 return 0; 00084 } 00085 00086 int mc_rwlock_rdunlock(mc_rwlock_p rwlock) 00087 { 00088 MUTEX_LOCK(rwlock->lock); 00089 if (rwlock->num_readers > 0) { 00090 rwlock->num_readers--; 00091 } 00092 if (rwlock->num_readers == 0) { 00093 COND_SIGNAL( rwlock->cond ); 00094 } 00095 MUTEX_UNLOCK(rwlock->lock); 00096 return 0; 00097 } 00098 00099 int mc_rwlock_wrlock(mc_rwlock_p rwlock) 00100 { 00101 MUTEX_LOCK(rwlock->lock); 00102 rwlock->write_request++; 00103 00104 while ( 00105 (rwlock->num_readers != 0) || 00106 (rwlock->write_flag != 0) 00107 ) 00108 { 00109 COND_WAIT(rwlock->cond, rwlock->lock); 00110 } 00111 00112 rwlock->write_request--; 00113 rwlock->write_flag++; 00114 MUTEX_UNLOCK(rwlock->lock); 00115 return 0; 00116 } 00117 00118 int mc_rwlock_wrunlock(mc_rwlock_p rwlock) 00119 { 00120 MUTEX_LOCK(rwlock->lock); 00121 rwlock->write_flag = 0; 00122 COND_SIGNAL(rwlock->cond); 00123 MUTEX_UNLOCK(rwlock->lock); 00124 return 0; 00125 }