Fork us on GitHub Follow us on Facebook Follow us on Twitter

Ignore:
File:
1 edited

Legend:

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

    r63f8966 r84b7384  
    4242#include <errno.h>
    4343#include <assert.h>
     44#include <stacktrace.h>
     45#include <stdlib.h>
    4446
    4547static void optimize_execution_power(void)
     
    5658}
    5759
     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
     71static void print_deadlock(fibril_owner_info_t *oi)
     72{
     73        fibril_t *f = (fibril_t *) fibril_get_id();
     74
     75        printf("Deadlock detected.\n");
     76        stacktrace_print();
     77
     78        printf("Fibril %p waits for primitive %p.\n", f, oi);
     79
     80        while (oi && oi->owned_by) {
     81                printf("Primitive %p is owned by fibril %p.\n",
     82                    oi, oi->owned_by);
     83                if (oi->owned_by == f)
     84                        break;
     85                stacktrace_print_fp_pc(context_get_fp(&oi->owned_by->ctx),
     86                    oi->owned_by->ctx.pc);
     87                printf("Fibril %p waits for primitive %p.\n",
     88                     oi->owned_by, oi->owned_by->waits_for);
     89                oi = oi->owned_by->waits_for;
     90        }
     91
     92        abort();
     93}
     94
    5895void fibril_mutex_initialize(fibril_mutex_t *fm)
    5996{
     97        fm->oi.owned_by = NULL;
    6098        fm->counter = 1;
    6199        list_initialize(&fm->waiters);
     
    64102void fibril_mutex_lock(fibril_mutex_t *fm)
    65103{
     104        fibril_t *f = (fibril_t *) fibril_get_id();
     105
    66106        futex_down(&async_futex);
    67107        if (fm->counter-- <= 0) {
     
    73113                link_initialize(&wdata.wu_event.link);
    74114                list_append(&wdata.wu_event.link, &fm->waiters);
     115
     116                if (check_for_deadlock(&fm->oi))
     117                        print_deadlock(&fm->oi);
     118                f->waits_for = &fm->oi;
     119
    75120                fibril_switch(FIBRIL_TO_MANAGER);
    76121        } else {
     122                fm->oi.owned_by = f;
    77123                futex_up(&async_futex);
    78124        }
     
    86132        if (fm->counter > 0) {
    87133                fm->counter--;
     134                fm->oi.owned_by = (fibril_t *) fibril_get_id();
    88135                locked = true;
    89136        }
     
    99146                link_t *tmp;
    100147                awaiter_t *wdp;
     148                fibril_t *f;
    101149       
    102150                assert(!list_empty(&fm->waiters));
     
    105153                wdp->active = true;
    106154                wdp->wu_event.inlist = false;
     155
     156                f = (fibril_t *) wdp->fid;
     157                fm->oi.owned_by = f;
     158                f->waits_for = NULL;
     159
    107160                list_remove(&wdp->wu_event.link);
    108161                fibril_add_ready(wdp->fid);
    109162                optimize_execution_power();
     163        } else {
     164                fm->oi.owned_by = NULL;
    110165        }
    111166}
     
    120175void fibril_rwlock_initialize(fibril_rwlock_t *frw)
    121176{
     177        frw->oi.owned_by = NULL;
    122178        frw->writers = 0;
    123179        frw->readers = 0;
Note: See TracChangeset for help on using the changeset viewer.