Ignore:
File:
1 edited

Legend:

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

    r9414abc r63f8966  
    4242#include <errno.h>
    4343#include <assert.h>
    44 #include <stacktrace.h>
    45 #include <stdlib.h>
    4644
    4745static void optimize_execution_power(void)
     
    5856}
    5957
    60 static void print_deadlock(fibril_owner_info_t *oi)
    61 {
    62         fibril_t *f = (fibril_t *) fibril_get_id();
    63 
    64         printf("Deadlock detected.\n");
    65         stacktrace_print();
    66 
    67         printf("Fibril %p waits for primitive %p.\n", f, oi);
    68 
    69         while (oi && oi->owned_by) {
    70                 printf("Primitive %p is owned by fibril %p.\n",
    71                     oi, oi->owned_by);
    72                 if (oi->owned_by == f)
    73                         break;
    74                 stacktrace_print_fp_pc(context_get_fp(&oi->owned_by->ctx),
    75                     oi->owned_by->ctx.pc);
    76                 printf("Fibril %p waits for primitive %p.\n",
    77                      oi->owned_by, oi->owned_by->waits_for);
    78                 oi = oi->owned_by->waits_for;
    79         }
    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 
    94 
    9558void fibril_mutex_initialize(fibril_mutex_t *fm)
    9659{
    97         fm->oi.owned_by = NULL;
    9860        fm->counter = 1;
    9961        list_initialize(&fm->waiters);
     
    10264void fibril_mutex_lock(fibril_mutex_t *fm)
    10365{
    104         fibril_t *f = (fibril_t *) fibril_get_id();
    105 
    10666        futex_down(&async_futex);
    10767        if (fm->counter-- <= 0) {
     
    11373                link_initialize(&wdata.wu_event.link);
    11474                list_append(&wdata.wu_event.link, &fm->waiters);
    115                 check_for_deadlock(&fm->oi);
    116                 f->waits_for = &fm->oi;
    11775                fibril_switch(FIBRIL_TO_MANAGER);
    11876        } else {
    119                 fm->oi.owned_by = f;
    12077                futex_up(&async_futex);
    12178        }
     
    12986        if (fm->counter > 0) {
    13087                fm->counter--;
    131                 fm->oi.owned_by = (fibril_t *) fibril_get_id();
    13288                locked = true;
    13389        }
     
    14399                link_t *tmp;
    144100                awaiter_t *wdp;
    145                 fibril_t *f;
    146101       
    147102                assert(!list_empty(&fm->waiters));
     
    150105                wdp->active = true;
    151106                wdp->wu_event.inlist = false;
    152 
    153                 f = (fibril_t *) wdp->fid;
    154                 fm->oi.owned_by = f;
    155                 f->waits_for = NULL;
    156 
    157107                list_remove(&wdp->wu_event.link);
    158108                fibril_add_ready(wdp->fid);
    159109                optimize_execution_power();
    160         } else {
    161                 fm->oi.owned_by = NULL;
    162110        }
    163111}
     
    172120void fibril_rwlock_initialize(fibril_rwlock_t *frw)
    173121{
    174         frw->oi.owned_by = NULL;
    175122        frw->writers = 0;
    176123        frw->readers = 0;
     
    180127void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
    181128{
    182         fibril_t *f = (fibril_t *) fibril_get_id();
    183        
    184129        futex_down(&async_futex);
    185130        if (frw->writers) {
     131                fibril_t *f = (fibril_t *) fibril_get_id();
    186132                awaiter_t wdata;
    187133
     
    192138                f->flags &= ~FIBRIL_WRITER;
    193139                list_append(&wdata.wu_event.link, &frw->waiters);
    194                 check_for_deadlock(&frw->oi);
    195                 f->waits_for = &frw->oi;
    196140                fibril_switch(FIBRIL_TO_MANAGER);
    197141        } else {
    198                 /* Consider the first reader the owner. */
    199                 if (frw->readers++ == 0)
    200                         frw->oi.owned_by = f;
     142                frw->readers++;
    201143                futex_up(&async_futex);
    202144        }
     
    205147void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
    206148{
    207         fibril_t *f = (fibril_t *) fibril_get_id();
    208        
    209149        futex_down(&async_futex);
    210150        if (frw->writers || frw->readers) {
     151                fibril_t *f = (fibril_t *) fibril_get_id();
    211152                awaiter_t wdata;
    212153
     
    217158                f->flags |= FIBRIL_WRITER;
    218159                list_append(&wdata.wu_event.link, &frw->waiters);
    219                 check_for_deadlock(&frw->oi);
    220                 f->waits_for = &frw->oi;
    221160                fibril_switch(FIBRIL_TO_MANAGER);
    222161        } else {
    223                 frw->oi.owned_by = f;
    224162                frw->writers++;
    225163                futex_up(&async_futex);
     
    232170        assert(frw->readers || (frw->writers == 1));
    233171        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                         }
     172                if (--frw->readers)
    249173                        goto out;
    250                 }
    251174        } else {
    252175                frw->writers--;
     
    254177       
    255178        assert(!frw->readers && !frw->writers);
    256        
    257         frw->oi.owned_by = NULL;
    258179       
    259180        while (!list_empty(&frw->waiters)) {
     
    264185                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    265186                f = (fibril_t *) wdp->fid;
    266                
    267                 f->waits_for = NULL;
    268187               
    269188                if (f->flags & FIBRIL_WRITER) {
     
    275194                        fibril_add_ready(wdp->fid);
    276195                        frw->writers++;
    277                         frw->oi.owned_by = f;
    278196                        optimize_execution_power();
    279197                        break;
     
    283201                        list_remove(&wdp->wu_event.link);
    284202                        fibril_add_ready(wdp->fid);
    285                         if (frw->readers++ == 0) {
    286                                 /* Consider the first reader the owner. */
    287                                 frw->oi.owned_by = f;
    288                         }
     203                        frw->readers++;
    289204                        optimize_execution_power();
    290205                }
Note: See TracChangeset for help on using the changeset viewer.