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 set_sem_owner(data->readCountSem, B_SYSTEM_TEAM); 66 set_sem_owner(data->writeCountSem, B_SYSTEM_TEAM); 67 set_sem_owner(data->readerQueue, B_SYSTEM_TEAM); 68 set_sem_owner(data->reader, B_SYSTEM_TEAM); 69 set_sem_owner(data->writer, B_SYSTEM_TEAM); 70 71 return true; 72} 73 74void closeManagedData(bt_managed_data *data) 75{ 76 data->readCount = data->writeCount = 0; 77 78 delete_sem(data->writer); 79 delete_sem(data->reader); 80 delete_sem(data->readerQueue); 81 delete_sem(data->writeCountSem); 82 delete_sem(data->readCountSem); 83} 84 85void beginReading(bt_managed_data *data) 86{ 87 btLock(data->readerQueue, &data->readerQueueVar); 88 btLock(data->reader, &data->readerVar); 89 btLock(data->readCountSem, &data->readCountVar); 90 91 data->readCount++; 92 if (data->readCount == 1) 93 btLock(data->writer, &data->writerVar); 94 95 btUnlock(data->readCountSem, &data->readCountVar); 96 btUnlock(data->reader, &data->readerVar); 97 btUnlock(data->readerQueue, &data->readerQueueVar); 98} 99 100void endReading(bt_managed_data *data) 101{ 102 btLock(data->readCountSem, &data->readCountVar); 103 104 data->readCount--; 105 if (data->readCount == 0) 106 btUnlock(data->writer, &data->writerVar); 107 108 btUnlock(data->readCountSem, &data->readCountVar); 109} 110 111void beginWriting(bt_managed_data *data) 112{ 113 btLock(data->writeCountSem, &data->writeCountVar); 114 115 data->writeCount++; 116 if (data->writeCount == 1) 117 btLock(data->reader, &data->readerVar); 118 119 btUnlock(data->writeCountSem, &data->writeCountVar); 120 btLock(data->writer, &data->writerVar); 121} 122 123void endWriting(bt_managed_data *data) 124{ 125 btUnlock(data->writer, &data->writerVar); 126 btLock(data->writeCountSem, &data->writeCountVar); 127 128 data->writeCount--; 129 if (data->writeCount == 0) 130 btUnlock(data->reader, &data->readerVar); 131 132 btUnlock(data->writeCountSem, &data->writeCountVar); 133} 134