Maybe we want, maybe we don't. Here's a check to prevent a counter from going negative, which usually means an accounting mistake somewhere. On the shortcomiing side, it only catches double decrements, not missing decrements, so maybe it's not worthwhile. Anyway, it was like five minutes to make, figured I'd show it.
Index: lib/libkern/libkern.h =================================================================== RCS file: /cvs/src/sys/lib/libkern/libkern.h,v retrieving revision 1.29 diff -u -p -r1.29 libkern.h --- lib/libkern/libkern.h 26 Apr 2012 01:22:31 -0000 1.29 +++ lib/libkern/libkern.h 19 Mar 2013 15:10:41 -0000 @@ -116,14 +116,11 @@ abs(int j) #ifndef DIAGNOSTIC #define KASSERT(e) ((void)0) +#define DECREMENT(x) x-- #else -#ifdef __STDC__ #define KASSERT(e) ((e) ? (void)0 : \ __assert("diagnostic ", __FILE__, __LINE__, #e)) -#else -#define KASSERT(e) ((e) ? (void)0 : \ - __assert("diagnostic ", __FILE__, __LINE__, "e")) -#endif +#define DECREMENT(x) decrement_checked((x)--, __FILE__, __LINE__, #x) #endif #ifndef DEBUG @@ -141,6 +138,7 @@ abs(int j) /* Prototypes for non-quad routines. */ void __assert(const char *, const char *, int, const char *) __attribute__ ((__noreturn__)); +int64_t decrement_checked(int64_t, const char *, int, const char *); int bcmp(const void *, const void *, size_t); void bzero(void *, size_t); void explicit_bzero(void *, size_t); Index: kern/subr_prf.c =================================================================== RCS file: /cvs/src/sys/kern/subr_prf.c,v retrieving revision 1.76 diff -u -p -r1.76 subr_prf.c --- kern/subr_prf.c 3 Apr 2011 16:46:19 -0000 1.76 +++ kern/subr_prf.c 19 Mar 2013 15:13:27 -0000 @@ -161,6 +161,14 @@ __assert(const char *t, const char *f, i t, e, f, l); } +int64_t +decrement_checked(int64_t x, const char *f, int l, const char *e) +{ + if (x <= 0) + __assert("decrement ", f, l, e); + return x; +} + /* * tablefull: warn that a system table is full */ Index: kern/vfs_bio.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_bio.c,v retrieving revision 1.146 diff -u -p -r1.146 vfs_bio.c --- kern/vfs_bio.c 17 Feb 2013 17:39:29 -0000 1.146 +++ kern/vfs_bio.c 19 Mar 2013 15:12:12 -0000 @@ -129,7 +129,7 @@ bremfree(struct buf *bp) bcstats.numcleanpages -= atop(bp->b_bufsize); } else { bcstats.numdirtypages -= atop(bp->b_bufsize); - bcstats.delwribufs--; + DECREMENT(bcstats.delwribufs); } TAILQ_REMOVE(dp, bp, b_freelist); } @@ -155,7 +155,7 @@ buf_put(struct buf *bp) #endif LIST_REMOVE(bp, b_list); - bcstats.numbufs--; + DECREMENT(bcstats.numbufs); if (buf_dealloc_mem(bp) != 0) return; @@ -1221,9 +1221,9 @@ biodone(struct buf *bp) if (bcstats.numbufs && (!(ISSET(bp->b_flags, B_RAW) || ISSET(bp->b_flags, B_PHYS)))) { if (!ISSET(bp->b_flags, B_READ)) - bcstats.pendingwrites--; + DECREMENT(bcstats.pendingwrites); else - bcstats.pendingreads--; + DECREMENT(bcstats.pendingreads); } if (ISSET(bp->b_flags, B_CALL)) { /* if necessary, call out */ CLR(bp->b_flags, B_CALL); /* but note callout done */