From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25631 invoked by alias); 13 Feb 2013 11:36:54 -0000 Received: (qmail 25623 invoked by uid 22791); 13 Feb 2013 11:36:53 -0000 X-SWARE-Spam-Status: No, hits=1.6 required=5.0 tests=BAYES_50,RCVD_IN_DNSWL_NONE,RCVD_IN_HOSTKARMA_YE,RDNS_NONE X-Spam-Check-By: sourceware.org Received: from Unknown (HELO mail-01.name-services.com) (69.64.155.193) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Feb 2013 11:36:46 +0000 Received: from workrbnw7 ([87.116.30.226]) by mail-01.name-services.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 13 Feb 2013 03:36:20 -0800 From: =?iso-8859-1?Q?Ren=E9_Schipp_von_Branitz_Nielsen?= To: Subject: Cyg_Mutex::check_this() fails Date: Wed, 13 Feb 2013 11:36:00 -0000 Message-ID: <000901ce09de$3d3dc0d0$b7b94270$@cc> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Sender: rbn@optisoft.cc X-EchoSenderHash: [rbn]-[optisoft*cc] Mailing-List: contact ecos-devel-help@ecos.sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: ecos-devel-owner@ecos.sourceware.org X-SW-Source: 2013-02/txt/msg00000.txt.bz2 ...Sending this from my private mail account because the eCos mailserver blocks mail containing confidentiality disclaimers, which I can't prevent when sending from my work mail account... :( :( --------------------oOo-------------------- Hello folks, I have a condition variable, c, tied to a mutex, m, and used like this with a FIFO, f: void producer(void) { cyg_mutex_lock(&m); copy_to_fifo(&f, some_data); cyg_cond_signal(&c); cyg_mutex_unlock(&m); } void consumer_thread(cyg_addrword_t data) { cyg_mutex_lock(&m); while (1) { while (fifo_empty(&f)) { cyg_cond_wait(&c); } // m is locked here. // Empty FIFO. while (!fifo_empty(&f)) { copy_from_fifo(&f, &some_data); cyg_mutex_unlock(); // Do something with some_data ... cyg_mutex_lock(); } } } The following description refers to line numbers of rev. 1.15 of mutex.cxx. When the system is under heavy interrupt load, threads may get scheduled in and out more frequently than when not. Under these circumstances, I sometimes get an assertion (cyg_assert_msg()) stemming from line 197 of mutex.cxx, which is Cyg_Mutex::check_this(). Placing a breakpoint in this function reveals that it happens when the consumer is about to wake up, that is, in line 651, which is the second half of Cyg_Condition_Variable::wait_inner( Cyg_Mutex *mx ). A closer look at wait_inner() shows that when CYG_ASSERTCLASS( mx, "Corrupt mutex") is invoked, the scheduler is not locked, which in turn means that Cyg_Mutex::check_this() line 197 is tested non-atomically. Line 197 contains: if (( locked && owner =3D=3D NULL ) return false; So if the preemptive scheduler schedules the caller of cyg_cond_wait() out in between the test of "locked" and "owner =3D=3D NULL", and the mutex state changes while scheduled out, we have a problem. As I see it, CYG_ASSERTCLASS(some_obj, "some message") serves two purposes: 1) check that some_obj is non-NULL and 2) check that some_obj->check_this() returns TRUE. IMO, only the first check needs to be made by wait_inner(), because line #677 attempts to reacquire the mutex (mx->lock()), which itself performs the check_this() check - and with the scheduler locked. There are other places in mutex.cxx where CYG_ASSERTCLASS(Cyg_Mutex, "message") is invoked without the scheduler locked, but I can't judge whether these are OK or not. Bottomline is that I suggest to change line #651 of mutex.cxx from CYG_ASSERTCLASS( mx, "Corrupt mutex"); to CYG_ASSERT(mx, "Invalid mutex pointer"); /* Or some other message */ Or is there anything fundamental, I have missed here? Comments are appreciated. Thanks in advance, Ren=E9 Schipp von Branitz Nielsen Vitesse Semiconductor Corporation