From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31028 invoked by alias); 1 Nov 2009 20:52:58 -0000 Received: (qmail 31019 invoked by uid 22791); 1 Nov 2009 20:52:57 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from fg-out-1718.google.com (HELO fg-out-1718.google.com) (72.14.220.154) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 01 Nov 2009 20:52:54 +0000 Received: by fg-out-1718.google.com with SMTP id e21so566840fga.12 for ; Sun, 01 Nov 2009 12:52:51 -0800 (PST) MIME-Version: 1.0 Received: by 10.87.38.23 with SMTP id q23mr1594718fgj.35.1257108767086; Sun, 01 Nov 2009 12:52:47 -0800 (PST) From: Jerome Souquieres Date: Sun, 01 Nov 2009 20:52:00 -0000 Message-ID: <1ca1a2b60911011252v76b5626cwd8b6fca144c857f2@mail.gmail.com> Subject: pthread_once non conformant To: ecos-devel@ecos.sourceware.org Content-Type: text/plain; charset=ISO-8859-1 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: 2009-11/txt/msg00000.txt.bz2 Hi, I think I've spotted a bug in pthread_once (in ecos v3.0). The current implementation does not enforce the part of the specification that says: "On return from pthread_once(), it is guaranteed that init_routine() has completed". Here is a proposal for a patch, I did not post it to ecos-patches because I currently don't have a working eCos target to test this. --- pthread.cxx 2009-01-29 18:47:52.000000000 +0100 +++ pthread-fixonce.cxx 2009-11-01 21:07:42.639875000 +0100 @@ -1328,22 +1328,23 @@ externC int pthread_once (pthread_once_t PTHREAD_ENTRY(); PTHREAD_CHECK( once_control ); PTHREAD_CHECK( init_routine ); - pthread_once_t old; - - // Do a test and set on the once_control object. pthread_mutex.lock(); - old = *once_control; - *once_control = 1; + // If the once_control is zero, call the init_routine(). + // the mutex must stay locked during init_routine because + // concurrent threads must be blocked until init_routine has + // done its business + if ( !*once_control ) + { + init_routine(); + *once_control = 1; + } pthread_mutex.unlock(); - - // If the once_control was zero, call the init_routine(). - if( !old ) init_routine(); PTHREAD_RETURN(0); }