1// readerWriter.c 2 3#include "betalk.h" 4#include "readerWriter.h" 5 6 7void btLock(sem_id semaphore, int32 *atomic) 8{ 9 int32 previous = atomic_add(atomic, 1); 10 if (previous >= 1) 11 while (acquire_sem(semaphore) == B_INTERRUPTED); 12} 13 14void btUnlock(sem_id semaphore, int32 *atomic) 15{ 16 int32 previous = atomic_add(atomic, -1); 17 if (previous > 1) 18 release_sem(semaphore); 19} 20 21bool initManagedData(bt_managed_data *data) 22{ 23 data->readCount = 0; 24 data->writeCount = 0; 25 26 data->readCountVar = 0; 27 data->writeCountVar = 0; 28 data->readerQueueVar = 0; 29 data->readerVar = 0; 30 data->writerVar = 0; 31 32 if ((data->readCountSem = create_sem(1, "Read Counter")) < 0) 33 return false; 34 35 if ((data->writeCountSem = create_sem(1, "Write Counter")) < 0) 36 { 37 delete_sem(data->readCountSem); 38 return false; 39 } 40 41 if ((data->readerQueue = create_sem(1, "Read Queue")) < 0) 42 { 43 delete_sem(data->writeCountSem); 44 delete_sem(data->readCountSem); 45 return false; 46 } 47 48 if ((data->reader = create_sem(1, "Single Reader")) < 0) 49 { 50 delete_sem(data->readerQueue); 51 delete_sem(data->writeCountSem); 52 delete_sem(data->readCountSem); 53 return false; 54 } 55 56 if ((data->writer = create_sem(1, "Writer")) < 0) 57 { 58 delete_sem(data->reader); 59 delete_sem(data->readerQueue); 60 delete_sem(data->writeCountSem); 61 delete_sem(data->readCountSem); 62 return false; 63 } 64 65 return true; 66} 67 68void closeManagedData(bt_managed_data *data) 69{ 70 data->readCount = data->writeCount = 0; 71 72 delete_sem(data->writer); 73 delete_sem(data->reader); 74 delete_sem(data->readerQueue); 75 delete_sem(data->writeCountSem); 76 delete_sem(data->readCountSem); 77} 78 79void beginReading(bt_managed_data *data) 80{ 81 btLock(data->readerQueue, &data->readerQueueVar); 82 btLock(data->reader, &data->readerVar); 83 btLock(data->readCountSem, &data->readCountVar); 84 85 data->readCount++; 86 if (data->readCount == 1) 87 btLock(data->writer, &data->writerVar); 88 89 btUnlock(data->readCountSem, &data->readCountVar); 90 btUnlock(data->reader, &data->readerVar); 91 btUnlock(data->readerQueue, &data->readerQueueVar); 92} 93 94void endReading(bt_managed_data *data) 95{ 96 btLock(data->readCountSem, &data->readCountVar); 97 98 data->readCount--; 99 if (data->readCount == 0) 100 btUnlock(data->writer, &data->writerVar); 101 102 btUnlock(data->readCountSem, &data->readCountVar); 103} 104 105void beginWriting(bt_managed_data *data) 106{ 107 btLock(data->writeCountSem, &data->writeCountVar); 108 109 data->writeCount++; 110 if (data->writeCount == 1) 111 btLock(data->reader, &data->readerVar); 112 113 btUnlock(data->writeCountSem, &data->writeCountVar); 114 btLock(data->writer, &data->writerVar); 115} 116 117void endWriting(bt_managed_data *data) 118{ 119 btUnlock(data->writer, &data->writerVar); 120 btLock(data->writeCountSem, &data->writeCountVar); 121 122 data->writeCount--; 123 if (data->writeCount == 0) 124 btUnlock(data->reader, &data->readerVar); 125 126 btUnlock(data->writeCountSem, &data->writeCountVar); 127} 128