Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril_synch.c

    r84b7384 r9414abc  
    5858}
    5959
    60 static bool check_for_deadlock(fibril_owner_info_t *oi)
    61 {
    62         while (oi && oi->owned_by) {
    63                 if (oi->owned_by == (fibril_t *) fibril_get_id())
    64                         return true;
    65                 oi = oi->owned_by->waits_for;
    66         }
    67 
    68         return false;
    69 }
    70 
    7160static void print_deadlock(fibril_owner_info_t *oi)
    7261{
     
    8978                oi = oi->owned_by->waits_for;
    9079        }
    91 
    92         abort();
    93 }
     80}
     81
     82
     83static void check_for_deadlock(fibril_owner_info_t *oi)
     84{
     85        while (oi && oi->owned_by) {
     86                if (oi->owned_by == (fibril_t *) fibril_get_id()) {
     87                        print_deadlock(oi);
     88                        abort();
     89                }
     90                oi = oi->owned_by->waits_for;
     91        }
     92}
     93
    9494
    9595void fibril_mutex_initialize(fibril_mutex_t *fm)
     
    113113                link_initialize(&wdata.wu_event.link);
    114114                list_append(&wdata.wu_event.link, &fm->waiters);
    115 
    116                 if (check_for_deadlock(&fm->oi))
    117                         print_deadlock(&fm->oi);
     115                check_for_deadlock(&fm->oi);
    118116                f->waits_for = &fm->oi;
    119 
    120117                fibril_switch(FIBRIL_TO_MANAGER);
    121118        } else {
     
    183180void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
    184181{
     182        fibril_t *f = (fibril_t *) fibril_get_id();
     183       
    185184        futex_down(&async_futex);
    186185        if (frw->writers) {
    187                 fibril_t *f = (fibril_t *) fibril_get_id();
    188186                awaiter_t wdata;
    189187
     
    194192                f->flags &= ~FIBRIL_WRITER;
    195193                list_append(&wdata.wu_event.link, &frw->waiters);
     194                check_for_deadlock(&frw->oi);
     195                f->waits_for = &frw->oi;
    196196                fibril_switch(FIBRIL_TO_MANAGER);
    197197        } else {
    198                 frw->readers++;
     198                /* Consider the first reader the owner. */
     199                if (frw->readers++ == 0)
     200                        frw->oi.owned_by = f;
    199201                futex_up(&async_futex);
    200202        }
     
    203205void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
    204206{
     207        fibril_t *f = (fibril_t *) fibril_get_id();
     208       
    205209        futex_down(&async_futex);
    206210        if (frw->writers || frw->readers) {
    207                 fibril_t *f = (fibril_t *) fibril_get_id();
    208211                awaiter_t wdata;
    209212
     
    214217                f->flags |= FIBRIL_WRITER;
    215218                list_append(&wdata.wu_event.link, &frw->waiters);
     219                check_for_deadlock(&frw->oi);
     220                f->waits_for = &frw->oi;
    216221                fibril_switch(FIBRIL_TO_MANAGER);
    217222        } else {
     223                frw->oi.owned_by = f;
    218224                frw->writers++;
    219225                futex_up(&async_futex);
     
    226232        assert(frw->readers || (frw->writers == 1));
    227233        if (frw->readers) {
    228                 if (--frw->readers)
     234                if (--frw->readers) {
     235                        if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) {
     236                                /*
     237                                 * If this reader firbril was considered the
     238                                 * owner of this rwlock, clear the ownership
     239                                 * information even if there are still more
     240                                 * readers.
     241                                 *
     242                                 * This is the limitation of the detection
     243                                 * mechanism rooted in the fact that tracking
     244                                 * all readers would require dynamically
     245                                 * allocated memory for keeping linkage info.
     246                                 */
     247                                frw->oi.owned_by = NULL;
     248                        }
    229249                        goto out;
     250                }
    230251        } else {
    231252                frw->writers--;
     
    233254       
    234255        assert(!frw->readers && !frw->writers);
     256       
     257        frw->oi.owned_by = NULL;
    235258       
    236259        while (!list_empty(&frw->waiters)) {
     
    241264                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    242265                f = (fibril_t *) wdp->fid;
     266               
     267                f->waits_for = NULL;
    243268               
    244269                if (f->flags & FIBRIL_WRITER) {
     
    250275                        fibril_add_ready(wdp->fid);
    251276                        frw->writers++;
     277                        frw->oi.owned_by = f;
    252278                        optimize_execution_power();
    253279                        break;
     
    257283                        list_remove(&wdp->wu_event.link);
    258284                        fibril_add_ready(wdp->fid);
    259                         frw->readers++;
     285                        if (frw->readers++ == 0) {
     286                                /* Consider the first reader the owner. */
     287                                frw->oi.owned_by = f;
     288                        }
    260289                        optimize_execution_power();
    261290                }
Note: See TracChangeset for help on using the changeset viewer.