From owner-freebsd-hackers Wed Jul 31 20:48:05 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id UAA24705 for hackers-outgoing; Wed, 31 Jul 1996 20:48:05 -0700 (PDT) Received: from trapdoor.dstc.edu.au (root@trapdoor.dstc.edu.au [130.102.176.12]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id UAA24675 for ; Wed, 31 Jul 1996 20:47:53 -0700 (PDT) Received: from foxtail.dstc.edu.au (foxtail.dstc.edu.au [130.102.176.14]) by trapdoor.dstc.edu.au (8.6.9/8.6.12) with ESMTP id NAA27587; Thu, 1 Aug 1996 13:47:35 +1000 Received: (from leonard@localhost) by foxtail.dstc.edu.au (8.6.10/8.6.10) id NAA13864; Thu, 1 Aug 1996 13:47:35 +1000 From: David Leonard Message-Id: <199608010347.NAA13864@foxtail.dstc.edu.au> Subject: Re: kernel assertions (Rev. 1) To: michaelh@cet.co.jp Date: Thu, 1 Aug 1996 13:47:35 +1000 (EST) Cc: hackers@freebsd.org Reply-To: leonard@dstc.edu.au X-Mailer: ELM [version 2.4 PL25] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > void > bremfree(struct buf * bp) > { > int s = splbio(); > REQUIRE2(bp, "Expected bp to point to something") > REQUIRE1(bp->b_qindex != QUEUE_NONE, "Expected a buffer on a > queue"); > TAILQ_REMOVE(&bufqueues[bp->b_qindex], bp, b_freelist); > bp->b_qindex = QUEUE_NONE; > ENSURE2(bp->b_qindex == QUEUE_NONE, "Buffer should no longer be on > a queue"); > splx(s); > } This might be a little arcane, but as you haven't yet talked about what actual message is emitted, how about going the extra step in readable macros? something a little like this, maybe: REQUIRE("that bp points to something", bp != NULL); mod/file.c:123: require that bp points to something and ENSURE( "that the buffer is no longer queued", bp->b_qindex == QUEUE_NONE ); mod/file.c.124: Failed to ensure that the buffer is no longer queued I really like the idea of names such as REQUIRE/ENSURE over ASSERT, but i hesitate at the numbers. But... one could get used to it I suppose. (sounds like a microsoft attitude) Looking at it again, I think it would raise the readability (and hence learnability/searchability(?)) of the FreeBSD source tree no end! In some ways, having to express the predicate that you are trying to ENSURE() essentially documents your code better! Unless, of course you ENSURE( "bp!=NULL", bp!=NULL ); which I would like to see avoided :) Other problems I can think of are: - side effects of the conditionals - conditions that take longer than constant time to be evaluated So, sure you can whip up some simple-looking examples of ENSURE/REQUIRE, but what about when you end up with something like this: ENSURE( "nothing in the queue has an invalid buffer", ({ thing* x; for(x=queue->head;x;x=x->next) if ( !valid_buffer(x->buffer) ) return 0; return 1; }) ); first, valid_buffer() may have side effects which will alter operation if these (expensive) checks are compiled out ,and second, being a linear time check, an interrupt or something may happen in the middle which might affect the data structures being examined. the long-time problem can be handled with ENSURE2, ENSURE3 and so on, but does anyone have a nice way of handling the side-effect problem? d -- David Leonard Project Officer, DSTC The University of Queensland david.leonard@dstc.edu.au http://www.dstc.edu.au/~leonard/