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

Changeset e503d3a9 in mainline


Ignore:
Timestamp:
2010-10-25T21:33:03Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
e7f6389
Parents:
b14b71e (diff), 84b7384 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/deadlock-detection.

Location:
uspace/lib/c
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/abs32le/include/fibril.h

    rb14b71e re503d3a9  
    4444                (ctx)->pc = (uintptr_t) (_pc); \
    4545                (ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
     46                (ctx)->fp = 0; \
    4647                (ctx)->tls = ((uintptr_t) (ptls)) + sizeof(tcb_t); \
    4748        } while (0)
     
    5354typedef struct {
    5455        uintptr_t sp;
     56        uintptr_t fp;
    5557        uintptr_t pc;
    5658        uintptr_t tls;
    5759} context_t;
     60
     61static inline uintptr_t context_get_fp(context_t *ctx)
     62{
     63        /* On real hardware, this function returns the frame pointer. */
     64        return ctx->fp;
     65}
    5866
    5967#endif
  • uspace/lib/c/arch/amd64/include/fibril.h

    rb14b71e re503d3a9  
    5656 */
    5757typedef struct {
    58     uint64_t sp;
    59     uint64_t pc;
    60    
    61     uint64_t rbx;
    62     uint64_t rbp;
     58        uint64_t sp;
     59        uint64_t pc;
    6360
    64     uint64_t r12;
    65     uint64_t r13;
    66     uint64_t r14;
    67     uint64_t r15;
     61        uint64_t rbx;
     62        uint64_t rbp;
    6863
    69     uint64_t tls;
     64        uint64_t r12;
     65        uint64_t r13;
     66        uint64_t r14;
     67        uint64_t r15;
     68
     69        uint64_t tls;
    7070} context_t;
     71
     72static inline uintptr_t context_get_fp(context_t *ctx)
     73{
     74        return ctx->rbp;
     75}
    7176
    7277#endif
  • uspace/lib/c/arch/arm32/include/fibril.h

    rb14b71e re503d3a9  
    8686} context_t;
    8787
     88static inline uintptr_t context_get_fp(context_t *ctx)
     89{
     90        return ctx->fp;
     91}
     92
    8893
    8994#endif
  • uspace/lib/c/arch/ia32/include/fibril.h

    rb14b71e re503d3a9  
    6767} context_t;
    6868
     69static inline uintptr_t context_get_fp(context_t *ctx)
     70{
     71        return ctx->ebp;
     72}
     73
    6974#endif
    7075
  • uspace/lib/c/arch/ia64/include/fibril.h

    rb14b71e re503d3a9  
    130130} context_t;
    131131
     132static inline uintptr_t context_get_fp(context_t *ctx)
     133{
     134        return 0;       /* FIXME */
     135}
     136
    132137#endif
    133138
  • uspace/lib/c/arch/mips32/include/fibril.h

    rb14b71e re503d3a9  
    8585} context_t;
    8686
     87static inline uintptr_t context_get_fp(context_t *ctx)
     88{
     89        return ctx->sp;
     90}
     91
    8792#endif
    8893
  • uspace/lib/c/arch/ppc32/include/fibril.h

    rb14b71e re503d3a9  
    7878} __attribute__ ((packed)) context_t;
    7979
     80static inline uintptr_t context_get_fp(context_t *ctx)
     81{
     82        return ctx->sp;
     83}
     84
    8085#endif
    8186
  • uspace/lib/c/arch/sparc64/include/fibril.h

    rb14b71e re503d3a9  
    7777} context_t;
    7878
     79static inline uintptr_t context_get_fp(context_t *ctx)
     80{
     81        return ctx->sp + STACK_BIAS;
     82}
     83
    7984#endif
    8085
  • uspace/lib/c/generic/fibril.c

    rb14b71e re503d3a9  
    275275        fibril->func = func;
    276276        fibril->arg = arg;
     277
     278        fibril->waits_for = NULL;
    277279       
    278280        context_save(&fibril->ctx);
  • uspace/lib/c/generic/fibril_synch.c

    rb14b71e re503d3a9  
    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;
  • uspace/lib/c/include/fibril.h

    rb14b71e re503d3a9  
    4848#define FIBRIL_WRITER      2
    4949
     50struct fibril;
     51
     52typedef struct {
     53        struct fibril *owned_by;
     54} fibril_owner_info_t;
     55
    5056typedef enum {
    5157        FIBRIL_PREEMPT,
     
    6874        int retval;
    6975        int flags;
     76
     77        fibril_owner_info_t *waits_for;
    7078} fibril_t;
    7179
  • uspace/lib/c/include/fibril_synch.h

    rb14b71e re503d3a9  
    4343
    4444typedef struct {
     45        fibril_owner_info_t oi;         /* Keep this the first thing. */
    4546        int counter;
    4647        link_t waiters;
     
    4950#define FIBRIL_MUTEX_INITIALIZER(name) \
    5051        { \
     52                .oi = { \
     53                        .owned_by = NULL \
     54                }, \
    5155                .counter = 1, \
    5256                .waiters = { \
     
    6064
    6165typedef struct {
     66        fibril_owner_info_t oi; /* Keep this the first thing. */
    6267        unsigned writers;
    6368        unsigned readers;
     
    6772#define FIBRIL_RWLOCK_INITIALIZER(name) \
    6873        { \
     74                .oi = { \
     75                        .owned_by = NULL \
     76                }, \
    6977                .readers = 0, \
    7078                .writers = 0, \
Note: See TracChangeset for help on using the changeset viewer.