From owner-freebsd-arch Fri Dec 28 23:28:57 2001 Delivered-To: freebsd-arch@freebsd.org Received: from femail24.sdc1.sfba.home.com (femail24.sdc1.sfba.home.com [24.0.95.149]) by hub.freebsd.org (Postfix) with ESMTP id C758C37B43D; Fri, 28 Dec 2001 23:28:31 -0800 (PST) Received: from laptop.baldwin.cx ([24.2.39.156]) by femail24.sdc1.sfba.home.com (InterMail vM.4.01.03.20 201-229-121-120-20010223) with ESMTP id <20011229072830.USF20896.femail24.sdc1.sfba.home.com@laptop.baldwin.cx>; Fri, 28 Dec 2001 23:28:30 -0800 Message-ID: X-Mailer: XFMail 1.4.0 on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit MIME-Version: 1.0 In-Reply-To: Date: Fri, 28 Dec 2001 23:28:18 -0800 (PST) From: John Baldwin To: Michal Mertl Subject: Re: 64 bit counters Cc: arch@FreeBSD.ORG, John Hanley , Alfred Perlstein , Matthew Dillon , Mike Smith Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On 27-Dec-01 Michal Mertl wrote: > On Thu, 27 Dec 2001, Mike Smith wrote: >> > :Why do I think it never becomes wrong? Generally I'm adding rather small >> > :value (<1e6 or so) to 64 bit counter. When one addition overflows less >> > :significant 32 bits, several next additions don't overflow. >> > : >> > :u_int64_t+=u_long is: >> > :addl %eax,(u_int64_t) ; this is atomic, right? >> > :adcl $0,4(u_int64_t) >> > : >> > :If interrupt occurs in between these two instructions, then the less >> > :significant halt is right and more significant will be fixed after the >> > :execution returns to second instruction. Even if the interrupt modified >> > :the value, we can expect (read - be sure) it didn't modify the more >> > :significant half. >> > >> > You are absolutely right. The carry will only be set on the addl >> > which overflows the 32 bit counter and will not be set on any of >> > the other addl's that might be occuring just before, inbetween the >> > two instructions, or just after. So only one of those will cause the >> > msb to increment. >> > >> > For UP the addl instruction is atomic. For SMP we still have to lock >> > the >> > bus cycle. Something like this: >> > >> > lock; addl %eax,(u_int64_t) >> > lock; adcl $0,4(u_int64_t) >> >> This is all well and good, but not portable. > > Aren't all other architectures we support 64 bit? On i386 even present > form (32 bit addition) isn't atomic (no lock involved). On i386 for 64 > bits the compiler generates the code above (without locks) and on 64 bit > platforms I expect it would generate something at least similarly atomic > like 32 bit addition on i386 we use today (both stable and current). On > i586 we can have 64 bit atomic operations with cmpxchg8b. On Aplha I think > the long is 64 bit so counters are already 64 bit. > > Anyway the code probably should be rewritten to use mutexes or atomic > operations or whatever. I'll look at some current sources and maybe I'll > be able to understand what are all these locks, mutexes, msleep and so on. > > In the time being I'll keep my naive patch to add the functionality to > stable (it happens to work (probably only in 99.99999% of time and bit > less on SMP)). You can use cmpxchg8b on SMP systems (it's available on all machines that support SMP I think) and use non-SMP versions otherwise where needed. You would just implement the atomic_foo_64 versions this way. You would need to use cmpxchg8b instead of addl/adcl for the acq and rel variants for SMP. -- John Baldwin <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve!" - http://www.FreeBSD.org/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message