From owner-freebsd-hackers@FreeBSD.ORG Fri May 29 13:08:07 2015 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 9A661628 for ; Fri, 29 May 2015 13:08:07 +0000 (UTC) (envelope-from sebastian.huber@embedded-brains.de) Received: from mail.embedded-brains.de (host-82-135-62-35.customer.m-online.net [82.135.62.35]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 0C33B18DA for ; Fri, 29 May 2015 13:08:06 +0000 (UTC) (envelope-from sebastian.huber@embedded-brains.de) Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id 272832A1820; Fri, 29 May 2015 15:01:31 +0200 (CEST) Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id W10bWwgkvo-o; Fri, 29 May 2015 15:01:30 +0200 (CEST) Received: from localhost (localhost.localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id A60DD2A192A; Fri, 29 May 2015 15:01:30 +0200 (CEST) X-Virus-Scanned: amavisd-new at zimbra.eb.localhost Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id YNRGKmh0hW7k; Fri, 29 May 2015 15:01:30 +0200 (CEST) Received: from [192.168.96.129] (unknown [192.168.96.129]) by mail.embedded-brains.de (Postfix) with ESMTPSA id 7DEC92A1820; Fri, 29 May 2015 15:01:30 +0200 (CEST) Message-ID: <55686300.3080100@embedded-brains.de> Date: Fri, 29 May 2015 15:00:48 +0200 From: Sebastian Huber User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: freebsd-hackers@freebsd.org CC: phk@phk.freebsd.dk Subject: Problem with timecounters and memory model Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 May 2015 13:08:07 -0000 Hello, we ported the FreeBSD timecounters to the RTEMS real-time operating=20 system. On PowerPC with GCC 4.9 I noticed the following problem. We have void binuptime(struct bintime *bt) { struct timehands *th; u_int gen; do { th =3D timehands; gen =3D th->th_generation; *bt =3D th->th_offset; bintime_addx(bt, th->th_scale * tc_delta(th)); } while (gen =3D=3D 0 || gen !=3D th->th_generation); } This is only valid if th->th_offset is read after th->th_generation and=20 the last write to th->th_generation is observable to all consumers=20 before the next write to th->th_offset etc. On PowerPC we get the following code via GCC 4.9: binuptime: stwu 1,-32(1) #,, mflr 0 #, stw 26,8(1) #, stw 0,36(1) #, stw 27,12(1) #, stw 28,16(1) #, stw 29,20(1) #, stw 31,28(1) #, stw 30,24(1) #, mr 30,3 # bt, bt .L41: lwz 31,timehands@sdarel(13) # timehands, th lwz 28,0(31) # th_3->th_counter, tc lwz 8,40(31) # th_3->th_offset, th_3->th_offset lwz 9,0(28) # tc_13->tc_get_timecount, tc_13->tc_get_timecount mr 3,28 #, tc lwz 10,44(31) # th_3->th_offset, th_3->th_offset lwz 6,32(31) # th_3->th_offset, th_3->th_offset mtctr 9 #, tc_13->tc_get_timecount lwz 7,36(31) # th_3->th_offset, th_3->th_offset <- we read th_generation after th_offset lwz 27,64(31) # th_3->th_generation, gen stw 8,8(30) # *bt_5(D), th_3->th_offset stw 10,12(30) # *bt_5(D), th_3->th_offset stw 6,0(30) # *bt_5(D), th_3->th_offset stw 7,4(30) # *bt_5(D), th_3->th_offset lwz 26,20(31) # th_3->th_scale, D.6097 lwz 29,16(31) # th_3->th_scale, D.6097 bctrl # Adding a compiler memory barrier yields: void binuptime(struct bintime *bt) { struct timehands *th; uint32_t gen; do { th =3D timehands; gen =3D th->th_generation; __asm__ volatile("" ::: "memory"); *bt =3D th->th_offset; bintime_addx(bt, th->th_scale * tc_delta(th)); } while (gen =3D=3D 0 || gen !=3D th->th_generation); } binuptime: stwu 1,-32(1) #,, mflr 0 #, stw 26,8(1) #, stw 0,36(1) #, stw 27,12(1) #, stw 28,16(1) #, stw 29,20(1) #, stw 31,28(1) #, stw 30,24(1) #, mr 30,3 # bt, bt .L41: lwz 31,timehands@sdarel(13) # timehands, th lwz 27,64(31) # th_3->th_generation, gen <- we read th_generation before th_offset lwz 28,0(31) # th_3->th_counter, tc lwz 9,44(31) # th_3->th_offset, th_3->th_offset lwz 8,36(31) # th_3->th_offset, th_3->th_offset mr 3,28 #, tc lwz 10,40(31) # th_3->th_offset, th_3->th_offset lwz 7,32(31) # th_3->th_offset, th_3->th_offset stw 9,12(30) # *bt_6(D), th_3->th_offset lwz 9,0(28) # tc_14->tc_get_timecount, tc_14->tc_get_timecount stw 8,4(30) # *bt_6(D), th_3->th_offset mtctr 9 #, tc_14->tc_get_timecount stw 10,8(30) # *bt_6(D), th_3->th_offset stw 7,0(30) # *bt_6(D), th_3->th_offset lwz 26,20(31) # th_3->th_scale, D.6097 lwz 29,16(31) # th_3->th_scale, D.6097 bctrl # This version seems to work at least on uni-processor systems. Shouldn't=20 there be real memory barriers the synchronize the reads/writes to=20 th_generation for SMP machines? --=20 Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.huber@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine gesch=C3=A4ftliche Mitteilung im Sinne des EHUG= .