# HG changeset patch # User Gorka Guardiola # Date 1328895988 0 # Node ID 50a0f958bd0ce7086474983c2b2bf0b8d5993e07 # Parent 9100bac012ae7ac201bacbaaf801f713ddedc017 pmc: fix sleep error leak. R=nixiedev, nemo, quanstro, john CC=nix-dev http://codereview.appspot.com/5646065 Committer: John Floren diff -r 9100bac012ae -r 50a0f958bd0c sys/src/nix/k10/dat.h --- a/sys/src/nix/k10/dat.h Fri Feb 10 17:42:19 2012 +0000 +++ b/sys/src/nix/k10/dat.h Fri Feb 10 17:46:28 2012 +0000 @@ -202,6 +202,7 @@ * hw perf counters */ struct PmcCtl { + Ref; u32int coreno; int enab; int user; diff -r 9100bac012ae -r 50a0f958bd0c sys/src/nix/k10/pmcio.c --- a/sys/src/nix/k10/pmcio.c Fri Feb 10 17:42:19 2012 +0000 +++ b/sys/src/nix/k10/pmcio.c Fri Feb 10 17:46:28 2012 +0000 @@ -239,18 +239,45 @@ * it now just in case it is idle or not being updated * NB: this function releases the ilock */ + + +static PmcWait* +newpmcw(void) +{ + PmcWait *w; + + w = malloc(sizeof (PmcWait)); + w->ref = 1; + return w; +} + +static void +pmcwclose(PmcWait *w) +{ + if(decref(w)) + return; + + free(w); +} + static void waitnotstale(Mach *mp, PmcCtr *p) { PmcWait *w; - w = malloc(sizeof (PmcWait)); + w = newpmcw(); w->next = p->wq; p->wq = w; + incref(w); iunlock(&mp->pmclock); apicipi(mp->apicno); + if(waserror()){ + pmcwclose(w); + nexterror(); + } sleep(&w->r, notstale, p); - free(w); + poperror(); + pmcwclose(w); } u64int @@ -400,6 +427,7 @@ for(w = p->wq; w != nil; w = w->next){ p->wq = w->next; wakeup(&w->r); + pmcwclose(w); } } iunlock(&m->pmclock);