Ignore:
File:
1 edited

Legend:

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

    r9414abc r84b7384  
    5858}
    5959
     60static 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
    6071static void print_deadlock(fibril_owner_info_t *oi)
    6172{
     
    7889                oi = oi->owned_by->waits_for;
    7990        }
    80 }
    81 
    82 
    83 static 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 
     91
     92        abort();
     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                 check_for_deadlock(&fm->oi);
     115
     116                if (check_for_deadlock(&fm->oi))
     117                        print_deadlock(&fm->oi);
    116118                f->waits_for = &fm->oi;
     119
    117120                fibril_switch(FIBRIL_TO_MANAGER);
    118121        } else {
     
    180183void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
    181184{
    182         fibril_t *f = (fibril_t *) fibril_get_id();
    183        
    184185        futex_down(&async_futex);
    185186        if (frw->writers) {
     187                fibril_t *f = (fibril_t *) fibril_get_id();
    186188                awaiter_t wdata;
    187189
     
    192194                f->flags &= ~FIBRIL_WRITER;
    193195                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                 /* Consider the first reader the owner. */
    199                 if (frw->readers++ == 0)
    200                         frw->oi.owned_by = f;
     198                frw->readers++;
    201199                futex_up(&async_futex);
    202200        }
     
    205203void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
    206204{
    207         fibril_t *f = (fibril_t *) fibril_get_id();
    208        
    209205        futex_down(&async_futex);
    210206        if (frw->writers || frw->readers) {
     207                fibril_t *f = (fibril_t *) fibril_get_id();
    211208                awaiter_t wdata;
    212209
     
    217214                f->flags |= FIBRIL_WRITER;
    218215                list_append(&wdata.wu_event.link, &frw->waiters);
    219                 check_for_deadlock(&frw->oi);
    220                 f->waits_for = &frw->oi;
    221216                fibril_switch(FIBRIL_TO_MANAGER);
    222217        } else {
    223                 frw->oi.owned_by = f;
    224218                frw->writers++;
    225219                futex_up(&async_futex);
     
    232226        assert(frw->readers || (frw->writers == 1));
    233227        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                         }
     228                if (--frw->readers)
    249229                        goto out;
    250                 }
    251230        } else {
    252231                frw->writers--;
     
    254233       
    255234        assert(!frw->readers && !frw->writers);
    256        
    257         frw->oi.owned_by = NULL;
    258235       
    259236        while (!list_empty(&frw->waiters)) {
     
    264241                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    265242                f = (fibril_t *) wdp->fid;
    266                
    267                 f->waits_for = NULL;
    268243               
    269244                if (f->flags & FIBRIL_WRITER) {
     
    275250                        fibril_add_ready(wdp->fid);
    276251                        frw->writers++;
    277                         frw->oi.owned_by = f;
    278252                        optimize_execution_power();
    279253                        break;
     
    283257                        list_remove(&wdp->wu_event.link);
    284258                        fibril_add_ready(wdp->fid);
    285                         if (frw->readers++ == 0) {
    286                                 /* Consider the first reader the owner. */
    287                                 frw->oi.owned_by = f;
    288                         }
     259                        frw->readers++;
    289260                        optimize_execution_power();
    290261                }
Note: See TracChangeset for help on using the changeset viewer.