Changeset 92d34f0b in mainline
- Timestamp:
- 2009-06-11T20:30:59Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9ae22ba
- Parents:
- ba2a055
- Location:
- uspace/lib/libc
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/fibril_sync.c
rba2a055 r92d34f0b 91 91 void fibril_rwlock_initialize(fibril_rwlock_t *frw) 92 92 { 93 fibril_mutex_initialize(&frw->fm); 93 frw->writers = 0; 94 frw->readers = 0; 95 list_initialize(&frw->waiters); 94 96 } 95 97 96 98 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 97 99 { 98 fibril_mutex_lock(&frw->fm); 100 futex_down(&async_futex); 101 if (frw->writers) { 102 fibril_t *f = (fibril_t *) fibril_get_id(); 103 f->flags &= ~FIBRIL_WRITER; 104 list_append(&f->link, &frw->waiters); 105 fibril_switch(FIBRIL_TO_MANAGER); 106 } else { 107 frw->readers++; 108 futex_up(&async_futex); 109 } 99 110 } 100 111 101 112 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 102 113 { 103 fibril_mutex_lock(&frw->fm); 114 futex_down(&async_futex); 115 if (frw->writers || frw->readers) { 116 fibril_t *f = (fibril_t *) fibril_get_id(); 117 f->flags |= FIBRIL_WRITER; 118 list_append(&f->link, &frw->waiters); 119 fibril_switch(FIBRIL_TO_MANAGER); 120 } else { 121 frw->writers++; 122 futex_up(&async_futex); 123 } 124 } 125 126 static void _fibril_rwlock_common_unlock(fibril_rwlock_t *frw) 127 { 128 futex_down(&async_futex); 129 assert(frw->readers || (frw->writers == 1)); 130 if (frw->readers) { 131 if (--frw->readers) 132 goto out; 133 } else { 134 frw->writers--; 135 } 136 137 assert(!frw->readers && !frw->writers); 138 139 while (!list_empty(&frw->waiters)) { 140 link_t *tmp = frw->waiters.next; 141 fibril_t *f = list_get_instance(tmp, fibril_t, link); 142 143 if (f->flags & FIBRIL_WRITER) { 144 if (frw->readers) 145 break; 146 list_remove(&f->link); 147 fibril_add_ready((fid_t) f); 148 frw->writers++; 149 break; 150 } else { 151 list_remove(&f->link); 152 fibril_add_ready((fid_t) f); 153 frw->readers++; 154 } 155 } 156 out: 157 futex_up(&async_futex); 104 158 } 105 159 106 160 void fibril_rwlock_read_unlock(fibril_rwlock_t *frw) 107 161 { 108 fibril_mutex_unlock(&frw->fm);162 _fibril_rwlock_common_unlock(frw); 109 163 } 110 164 111 165 void fibril_rwlock_write_unlock(fibril_rwlock_t *frw) 112 166 { 113 fibril_mutex_unlock(&frw->fm);167 _fibril_rwlock_common_unlock(frw); 114 168 } 115 169 -
uspace/lib/libc/include/fibril.h
rba2a055 r92d34f0b 47 47 #endif /* context_set */ 48 48 49 #define FIBRIL_SERIALIZED 1 49 #define FIBRIL_SERIALIZED 1 50 #define FIBRIL_WRITER 2 50 51 51 52 typedef enum { -
uspace/lib/libc/include/fibril_sync.h
rba2a055 r92d34f0b 56 56 57 57 typedef struct { 58 fibril_mutex_t fm; 58 unsigned writers; 59 unsigned readers; 60 link_t waiters; 59 61 } fibril_rwlock_t; 60 62 61 63 #define FIBRIL_RWLOCK_INITIALIZE(name) \ 62 64 fibril_rwlock_t name = { \ 63 .fm = { \ 64 .counter = 1, \ 65 .waiters = { \ 66 .prev = &name.fm.waiters, \ 67 .next = &name.fm.waiters, \ 68 } \ 65 .readers = 0, \ 66 .writers = 0, \ 67 .waiters = { \ 68 .prev = &name.waiters, \ 69 .next = &name.waiters, \ 69 70 } \ 70 71 }
Note:
See TracChangeset
for help on using the changeset viewer.