Closed Bug 30902 Opened 25 years ago Closed 25 years ago

True atomic implementation of NSPR atomic routines for Unix/Linux on x86

Categories

(NSPR :: NSPR, defect, P3)

x86
Linux
defect

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: wtc, Assigned: wtc)

Details

Attachments

(3 files)

We should implement the NSPR atomic routines (increment, decrement, set, and add) in x86 assembly code for Unix/Linux on x86 processors.
To test my code on Linux/x86, save the first attachment (id=6225) as mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, then apply the second attachment (id=6226) as a patch to your mozilla source tree. You only need to rebuild mozilla/nsprpub. As I don't really know x86 assembly language, I'd appreciate it if you could review the x86 assembly code (attachment 6225 [details]). Hopefully the comments in there make it self-explanatory.
Status: NEW → ASSIGNED
I'm not qualified to review the assembly, but just curious if you've done any profiling to see what the difference looks like. Cc'ing morse -- maybe he can review this.
No, I haven't done any profiling to see what the difference looks like.
I had some Linux kernel types look at it, and they thought it could be improved. In fact, they recommended that we ask to get the Linux kernel versions (http://lxr.linux.no/source/include/asm-i386/atomic.h) licensed under the MPL for our modification and use. I've sent some mail, and I'll let you know what I hear back.
You could use inline assembly in a C source file; the x86 implementation of these atomic ops are in ntmisc.c
My assembly code (attachment 6225 [details]) is based on the MSVC inline assembly code in ntmisc.c. I did not use the gcc inline assembly code in ntmisc.c because it hasn't been tested, not to mention that I can't understand the strange syntax. It doesn't seem to be correct either. For example, the gcc inline assembly codes of _PR_MD_ATOMIC_INCREMENT and _PR_MD_ATOMIC_DECREMENT are identical.
Target Milestone: --- → 4.1
The inline assembly code for gcc on Windows that Srinivas referred to is in the file mozilla/nsprpub/pr/src/md/windows/ntmisc.c, ifdef'd with __GNUC__. Note that some of that code may be incorrect, for example, the the gcc inline assembly codes of _PR_MD_ATOMIC_INCREMENT and _PR_MD_ATOMIC_DECREMENT are identical.
(added patch above) wan-teh, after looking at the linux kernel impl, and the solaris/ultrasparc impl, and poking into intel man pages, i came up with my own impl using gcc's __asm__() syntax. then i looked at your impl. yours looks fine to me. the only thing i would change is that you probably can use incl/decl instead of add/sub/mov. i prefer to use gcc's asm stuff so that gcc will tackle the overhead, but that's a personal preference, and your asm code looks like it's roughly equivalent to (and a bit less redundant than) the gcc asm output. in other words, "ship it". :)
Robey, as we discussed in email, I can't use incl/decl because the current spec. of PR_AtomicIncrement and PR_AtomicDecrement says they return the result, not just the sign of the result, of the increment/decrement. Checked in my patch (attachments 6225, 6226) on the main trunk of NSPR. Note that SeaMonkey is *not* pulling the tip of NSPR. /cvsroot/mozilla/nsprpub/pr/include/md/_linux.h, revision 3.26 /cvsroot/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, initial revision: 3.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile, revision 3.29 /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile.in, revision 1.14 /cvsroot/mozilla/nsprpub/pr/src/md/unix/objs.mk, revision 3.29
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → FIXED
Removed the 'nop' instructions that accidentally slipped in. /cvsroot/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, revision 3.2
I added an alternative implementation of PR_AtomicSet (using cmpxchg instead of xchg) in the comments. Also replaced a memory-to-register move by a register-to-register move in PR_AtomicAdd. /cvsroot/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, revision 3.3
Merged the patch onto the NSPRPUB_RELEASE_4_0_BRANCH. /cvsroot/mozilla/nsprpub/pr/include/md/_linux.h, revision 3.23.10.3 /cvsroot/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, revision 3.3.2.1 (new file) /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile, revision 3.28.6.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile.in, revision 1.13.6.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/objs.mk, revision 3.28.8.1
Target Milestone: 4.1 → 4.0.1
I merged the patch onto the NSPRPUB_CLIENT_BRANCH. /cvsroot/mozilla/nsprpub/pr/include/md/_linux.h, revision 3.24.2.2 /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile, revision 3.28.20.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/Makefile.in, revision 1.13.20.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/objs.mk, revision 3.28.22.1 /cvsroot/mozilla/nsprpub/pr/src/md/unix/os_Linux_x86.s, revision 3.3.4.1 (new file)
Target Milestone: 4.0.1 → 4.0.2
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: