Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 58644 invoked from network); 28 Aug 2007 16:57:49 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 28 Aug 2007 16:57:49 -0000 Received: (qmail 91210 invoked by uid 500); 28 Aug 2007 16:57:44 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 91143 invoked by uid 500); 28 Aug 2007 16:57:44 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 90720 invoked by uid 99); 28 Aug 2007 16:57:43 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Aug 2007 09:57:42 -0700 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of Farid_Zaripov@epam.com designates 217.21.63.3 as permitted sender) Received: from [217.21.63.3] (HELO EPMSA009.epam.com) (217.21.63.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 28 Aug 2007 16:58:31 +0000 Received: from [10.17.13.246] ([10.17.13.246]) by EPMSA009.epam.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Tue, 28 Aug 2007 19:57:01 +0300 Message-ID: <46D453D9.8010503@epam.com> Date: Tue, 28 Aug 2007 19:56:57 +0300 From: Farid Zaripov User-Agent: Thunderbird 1.5.0.10 (Windows/20070221) MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: [PATCH] Use __rw_atomic_xxx() on Windows Content-Type: multipart/mixed; boundary="------------060008020302080408040703" X-OriginalArrivalTime: 28 Aug 2007 16:57:02.0011 (UTC) FILETIME=[745E30B0:01C7E994] X-Virus-Checked: Checked by ClamAV on apache.org --------------060008020302080408040703 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Attached is a patch, adding __rw_atomic_{add|xchg}xx() functions on Win32/Win64 platforms. ChangeLog: * msvc-7.0.config: Added AS config variable. * msvc-8.0-x64.config: Ditto. * filterdef.js: Added definition of the CustomFileDef class * projectdef.js (InitAsmTool): New function to init custom build rule for .asm files. * projects.js: Added definitions of the platform dependent files. * utilities.js: Read AS configuration variable from the .config file. * i86/atomic.asm: New file with definitions of the __rw_atomic_xxx() for Win32 platform. * i86_64/atomic.asm: New file with definitions of the __rw_atomic_xxx() for Windows/x64 platform. * _mutex.h: Removed all dependencies on InterlockedXXX() API functions. Use new __rw_atomic_xxx() functions instead of InterlockedXXX(). * once.cpp [_WIN32 && _DLL]: Tell linker to export __atomic_xxx() functions, defined in .asm files. Farid. --------------060008020302080408040703 Content-Type: text/plain; name="atomic.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="atomic.patch" Index: etc/config/windows/filterdef.js =================================================================== --- etc/config/windows/filterdef.js (revision 570339) +++ etc/config/windows/filterdef.js (working copy) @@ -25,7 +25,7 @@ var sourceFilterName = "Source Files"; var sourceFilterUuid = "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"; -var sourceFilterExts = ".cpp;.cxx;.s"; +var sourceFilterExts = ".cpp;.cxx;.s;.asm"; var headerFilterName = "Header Files"; var headerFilterUuid = "{93995380-89BD-4b04-88EB-625FBE52EBFB}"; @@ -56,6 +56,21 @@ return str; } +//------------------------------------------------ +// CustomFileDef class +//------------------------------------------------ + +// CustomFileDef .ctor +function CustomFileDef(filepath, platform, initfun) +{ + this.filepath = filepath; + this.platform = platform; + this.initfun = initfun; +} + +// global array with platform dependent files definitions +var customFileDefs = new Array(); + // common macros var cmnMacros = new Array(); @@ -126,7 +141,29 @@ var VCFile = filter.AddFile(filename); if (null != filetype && typeof(VCFile.FileType) != "undefined") VCFile.FileType = filetype; - + + var customFileDef = null; + + if (!exclude) + { + // find the platform dependent file definition + for (var i = 0; i < customFileDefs.length; ++i) + { + var custFileDef = customFileDefs[i]; + var pos = VCFile.FullPath.length - custFileDef.filepath.length; + if (0 <= pos && pos == VCFile.FullPath.indexOf(custFileDef.filepath)) + { + customFileDef = custFileDef; + break; + } + } + + // exclude this file from build if current platform + // is not custom file target platform + if (null != customFileDef && customFileDef.platform != PLATFORM) + exclude = true; + } + if (exclude) { var cfgs = VCFile.FileConfigurations; @@ -144,6 +181,12 @@ cfg.ExcludedFromBuild = exclude; } } + else if (null != customFileDef && + "undefined" != typeof(customFileDef.initfun)) + { + // init + customFileDef.initfun(VCFile); + } } // create VCFilter object from the FilterDef definition Index: etc/config/windows/msvc-7.0.config =================================================================== --- etc/config/windows/msvc-7.0.config (revision 570339) +++ etc/config/windows/msvc-7.0.config (working copy) @@ -38,6 +38,7 @@ CXX=cl LD=cl AR=lib +AS=ml // Use singlethreaded or mutlithreaded CRT in 11s, 11d solution configurations // 0 for MS VisualStudio .NET and MS VisualStudio .NET 2003 Index: etc/config/windows/msvc-8.0-x64.config =================================================================== --- etc/config/windows/msvc-8.0-x64.config (revision 570339) +++ etc/config/windows/msvc-8.0-x64.config (working copy) @@ -1,2 +1,3 @@ #include msvc-8.0 PLATFORM=x64 +AS=ml64 Index: etc/config/windows/projectdef.js =================================================================== --- etc/config/windows/projectdef.js (revision 570339) +++ etc/config/windows/projectdef.js (working copy) @@ -941,3 +941,25 @@ return projectDef; } + +// init custom build rule for .asm files +function InitAsmTool(VCFile) +{ + var cfgs = VCFile.FileConfigurations; + for (var i = 1; i <= cfgs.Count; ++i) + { + var cfg = cfgs.Item(i); + if ((typeof(cfg.Tool.ToolKind) != "undefined" && + cfg.Tool.ToolKind != "VCCustomBuildTool") || + cfg.Tool.ToolName != "Custom Build Tool") + { + cfg.Tool = cfg.ProjectConfiguration.FileTools.Item("VCCustomBuildTool"); + } + + var tool = cfg.Tool; + tool.Description = "Compiling .asm file..."; + tool.Outputs = "$(IntDir)\\$(InputName).obj"; + tool.CommandLine = AS + " /c /nologo /Fo" + tool.Outputs + + " /W3 /Zi /Ta" + VCFile.RelativePath; + } +} Index: etc/config/windows/projects.js =================================================================== --- etc/config/windows/projects.js (revision 570339) +++ etc/config/windows/projects.js (working copy) @@ -84,6 +84,10 @@ projectDefs.push(new Array(configureDef)); /////////////////////////////////////////////////////////////////////////////// + // add platform dependent files + customFileDefs.push(new CustomFileDef("i86\\atomic.asm", "Win32", InitAsmTool)); + customFileDefs.push(new CustomFileDef("i86_64\\atomic.asm", "x64", InitAsmTool)); + var stdcxxDef = new ProjectDef(".stdcxx", typeLibrary); stdcxxDef.VCProjDir = ProjectsDir; stdcxxDef.FilterDefs.push( Index: etc/config/windows/utilities.js =================================================================== --- etc/config/windows/utilities.js (revision 570339) +++ etc/config/windows/utilities.js (working copy) @@ -32,6 +32,7 @@ var CXX = "cl"; var LD = "cl"; var AR = "lib"; +var AS = "ml"; var SLNVER="8.00"; var SLNCOMMENT=""; var UNICODELOG = false; @@ -112,6 +113,9 @@ case "AR": AR = arr[2]; break; + case "AS": + AS = arr[2]; + break; case "SLNVER": SLNVER = arr[2]; break; @@ -179,6 +183,7 @@ stream.WriteLine(" CXX=" + CXX); stream.WriteLine(" LD=" + LD); stream.WriteLine(" AR=" + AR); + stream.WriteLine(" AS=" + AS); stream.WriteLine(" SLNVER=" + SLNVER); stream.WriteLine(" SLNCOMMENT=" + SLNCOMMENT); stream.WriteLine(" UNICODELOG=" + UNICODELOG); Index: include/rw/_mutex.h =================================================================== --- include/rw/_mutex.h (revision 570431) +++ include/rw/_mutex.h (working copy) @@ -140,15 +140,7 @@ __declspec (dllimport) void __stdcall DeleteCriticalSection (_RTL_CRITICAL_SECTION*); -__declspec (dllimport) long __stdcall -InterlockedIncrement (_RWSTD_INTERLOCKED_T*); - -__declspec (dllimport) long __stdcall -InterlockedDecrement (_RWSTD_INTERLOCKED_T*); - -__declspec (dllimport) long __stdcall -InterlockedExchange (_RWSTD_INTERLOCKED_T*, long); - +_RWSTD_EXPORT int __rw_atomic_add32 (int*, int); } // extern "C" _RWSTD_NAMESPACE (__rw) { @@ -478,11 +470,11 @@ // implicit initialization used to prevent a g++ 2.95.2 warning on Tru64 // sorry: semantics of inline function static data are wrong (you'll wind // up with multiple copies) - static volatile long __cntr /* = 0 */; // initialization counter + static volatile int __cntr /* = 0 */; // initialization counter #if defined (_WIN32) || defined (_WIN64) // MT safe - if (0 == __cntr && 1 == InterlockedIncrement ((long*)&__cntr)) + if (0 == __cntr && 1 == __rw_atomic_add32 ((int*)&__cntr, +1)) #else // not so safe (volatile should help) if (0 == __cntr && 1 == ++__cntr) @@ -1161,19 +1153,20 @@ false); } -/********************** i386/gcc **************************************/ +/********************** i386/gcc || _M_IX86 *********************************/ -#elif defined (__i386__) && (defined (__GNUG__) || defined (__INTEL_COMPILER)) +#elif defined (__i386__) && (defined (__GNUG__) \ + || defined (__INTEL_COMPILER)) || defined (_M_IX86) extern "C" { -char __rw_atomic_add8 (char*, int); -short __rw_atomic_add16 (short*, short); -int __rw_atomic_add32 (int*, int); +_RWSTD_EXPORT char __rw_atomic_add8 (char*, int); +_RWSTD_EXPORT short __rw_atomic_add16 (short*, short); +_RWSTD_EXPORT int __rw_atomic_add32 (int*, int); -char __rw_atomic_xchg8 (char*, char); -short __rw_atomic_xchg16 (short*, short); -int __rw_atomic_xchg32 (int*, int); +_RWSTD_EXPORT char __rw_atomic_xchg8 (char*, char); +_RWSTD_EXPORT short __rw_atomic_xchg16 (short*, short); +_RWSTD_EXPORT int __rw_atomic_xchg32 (int*, int); } // extern "C" @@ -1349,85 +1342,39 @@ _RWSTD_STATIC_CAST (int, __y)); } +/********************** IA64/x86_64/_M_X64 *****************************/ -/********************** WIN 32/64 ************************************/ +#elif defined (__ia64) || defined (__x86_64) || defined (_M_X64) -#elif defined (_WIN32) +extern "C" { -// Interlocked[In|De]crement functions atomically modify their argument -// and return the new value +_RWSTD_EXPORT _RWSTD_INT8_T +__rw_atomic_xchg8 (_RWSTD_INT8_T*, _RWSTD_INT8_T); -// InterlockedExchange atomically sets the value pointed to by the first -// argument to that of the second argument and returns the original value +_RWSTD_EXPORT _RWSTD_INT16_T +__rw_atomic_xchg16 (_RWSTD_INT16_T*, _RWSTD_INT16_T); -inline int -__rw_atomic_preincrement (int &__x, bool) -{ - _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long)); - return InterlockedIncrement (_RWSTD_REINTERPRET_CAST (long*, &__x)); -} +_RWSTD_EXPORT _RWSTD_INT32_T +__rw_atomic_xchg32 (_RWSTD_INT32_T*, _RWSTD_INT32_T); -inline unsigned int -__rw_atomic_preincrement (unsigned int &__x, bool) -{ - return __rw_atomic_preincrement (_RWSTD_REINTERPRET_CAST (int&, __x), - false); -} +_RWSTD_EXPORT _RWSTD_INT8_T +__rw_atomic_add8 (_RWSTD_INT8_T*, _RWSTD_INT8_T); +_RWSTD_EXPORT _RWSTD_INT16_T +__rw_atomic_add16 (_RWSTD_INT16_T*, _RWSTD_INT16_T); -inline int -__rw_atomic_predecrement (int &__x, bool) -{ - _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long)); - return InterlockedDecrement (_RWSTD_REINTERPRET_CAST (long*, &__x)); -} +_RWSTD_EXPORT _RWSTD_INT32_T +__rw_atomic_add32 (_RWSTD_INT32_T*, _RWSTD_INT32_T); - -inline unsigned int -__rw_atomic_predecrement (unsigned int &__x, bool) -{ - return __rw_atomic_predecrement (_RWSTD_REINTERPRET_CAST (int&, __x), - false); -} - - -inline int -__rw_atomic_exchange (int &__x, int __y, bool) -{ - _RWSTD_COMPILE_ASSERT (sizeof __x == sizeof (long)); - return InterlockedExchange (_RWSTD_REINTERPRET_CAST (long*, &__x), - _RWSTD_STATIC_CAST (long, __y)); -} - - -inline unsigned int -__rw_atomic_exchange (unsigned int &__x, unsigned int __y, bool) -{ - return __rw_atomic_exchange (_RWSTD_REINTERPRET_CAST (int&, __x), - _RWSTD_STATIC_CAST (int, __y), false); -} - -/********************** IA64/x86_64 ***********************************/ - -#elif defined (__ia64) || defined (__x86_64) - -extern "C" { - -_RWSTD_INT8_T __rw_atomic_xchg8 (_RWSTD_INT8_T*, _RWSTD_INT8_T); -_RWSTD_INT16_T __rw_atomic_xchg16 (_RWSTD_INT16_T*, _RWSTD_INT16_T); -_RWSTD_INT32_T __rw_atomic_xchg32 (_RWSTD_INT32_T*, _RWSTD_INT32_T); - - -_RWSTD_INT8_T __rw_atomic_add8 (_RWSTD_INT8_T*, _RWSTD_INT8_T); -_RWSTD_INT16_T __rw_atomic_add16 (_RWSTD_INT16_T*, _RWSTD_INT16_T); -_RWSTD_INT32_T __rw_atomic_add32 (_RWSTD_INT32_T*, _RWSTD_INT32_T); - #ifdef _RWSTD_INT64_T -_RWSTD_INT64_T __rw_atomic_xchg64 (_RWSTD_INT64_T*, _RWSTD_INT64_T); -_RWSTD_INT64_T __rw_atomic_add64 (_RWSTD_INT64_T*, _RWSTD_INT64_T); +_RWSTD_EXPORT _RWSTD_INT64_T +__rw_atomic_xchg64 (_RWSTD_INT64_T*, _RWSTD_INT64_T); +_RWSTD_EXPORT _RWSTD_INT64_T +__rw_atomic_add64 (_RWSTD_INT64_T*, _RWSTD_INT64_T); + #endif // _RWSTD_INT64_T } // extern "C" Index: src/i86/atomic.asm =================================================================== --- src/i86/atomic.asm (revision 0) +++ src/i86/atomic.asm (revision 0) @@ -0,0 +1,178 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; i86/atomic.asm +; +; $Id$ +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Licensed to the Apache Software Foundation (ASF) under one or more +; contributor license agreements. See the NOTICE file distributed +; with this work for additional information regarding copyright +; ownership. The ASF licenses this file to you under the Apache +; License, Version 2.0 (the "License"); you may not use this file +; except in compliance with the License. You may obtain a copy of +; the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +; implied. See the License for the specific language governing +; permissions and limitations under the License. +; +; Copyright 2003-2006 Rogue Wave Software. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + .486 + .model flat + .code + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" char __rw_atomic_xchg8 (char *x, char y); +; +; Atomically assigns the 8-bit value y to *x and returns +; the original (before assignment) 8-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_xchg8 +___rw_atomic_xchg8 proc ; char (char *x, char y) + +arg_x = dword ptr 4 +arg_y = byte ptr 8 + + mov ecx, [esp+arg_x] ; %ecx = x + mov al, [esp+arg_y] ; %al = y + xchg al, [ecx] ; %al <-> (%ecx) + ret +___rw_atomic_xchg8 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" short __rw_atomic_xchg16 (short *x, short y); +; +; Atomically assigns the 16-bit value y to *x and returns +; the original (before assignment) 16-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_xchg16 +___rw_atomic_xchg16 proc ; short (short *x, short y) + +arg_x = dword ptr 4 +arg_y = word ptr 8 + + mov ecx, [esp+arg_x] ; %ecx = x + mov ax, [esp+arg_y] ; %eax = y + xchg ax, [ecx] ; %ax <-> (%ecx) + ret +___rw_atomic_xchg16 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int __rw_atomic_xchg32 (int *x, int y); +; +; Atomically assigns the 32-bit value y to *x and returns +; the original (before assignment) 32-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_xchg32 +___rw_atomic_xchg32 proc ; int (int *x, int y) + +arg_x = dword ptr 4 +arg_y = dword ptr 8 + + mov ecx, [esp+arg_x] ; %ecx = x + mov eax, [esp+arg_y] ; %eax = y + xchg eax, [ecx] ; %eax <-> (%ecx) + ret +___rw_atomic_xchg32 endp + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" char __rw_atomic_add8 (char *x, int y); +; +; Atomically increments the 8-bit value *x by y and returns +; the new (after increment) 8-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_add8 +___rw_atomic_add8 proc ; char (char *dst, int inc) + +arg_dst = dword ptr 4 +arg_inc = dword ptr 8 + + mov ecx, [esp+arg_dst] ; %ecx = dst + mov eax, [esp+arg_inc] ; %eax = inc + mov edx, eax + + lock xadd [ecx], al ; tmp = *dst; + ; dst += inc; + ; %al = tmp + + add eax, edx ; return %eax + inc + ret +___rw_atomic_add8 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" short __rw_atomic_add16 (short *x, short y); +; +; Atomically increments the 16-bit value *x by y and returns +; the new (after increment) 16-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_add16 +___rw_atomic_add16 proc ; short (short *dst, short inc) + +arg_dst = dword ptr 4 +arg_inc = dword ptr 8 + + mov ecx, [esp+arg_dst] ; %ecx = dst + mov eax, [esp+arg_inc] ; %eax = inc + mov edx, eax + + lock xadd [ecx], ax ; tmp = *dst; + ; dst += inc; + ; %ax = tmp + + add eax, edx ; return %eax + inc + ret +___rw_atomic_add16 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int __rw_atomic_add32 (int *x, int y); +; +; Atomically increments the 32-bit value *x by y and returns +; the new (after increment) 32-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 4 + public ___rw_atomic_add32 +___rw_atomic_add32 proc ; int (int *dst, int inc) + +arg_dst = dword ptr 4 +arg_inc = dword ptr 8 + + mov ecx, [esp+arg_dst] ; %ecx = dst + mov edx, [esp+arg_inc] ; %edx = inc + mov eax, edx + + lock xadd [ecx], eax ; tmp = *dst; + ; dst += inc; + ; %eax = tmp + + add eax, edx ; return %eax + inc + ret +___rw_atomic_add32 endp + + end Property changes on: src\i86\atomic.asm ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/i86_64/atomic.asm =================================================================== --- src/i86_64/atomic.asm (revision 0) +++ src/i86_64/atomic.asm (revision 0) @@ -0,0 +1,186 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; i86_64/atomic.asm +; +; $Id$ +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Licensed to the Apache Software Foundation (ASF) under one or more +; contributor license agreements. See the NOTICE file distributed +; with this work for additional information regarding copyright +; ownership. The ASF licenses this file to you under the Apache +; License, Version 2.0 (the "License"); you may not use this file +; except in compliance with the License. You may obtain a copy of +; the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +; implied. See the License for the specific language governing +; permissions and limitations under the License. +; +; Copyright 2003-2006 Rogue Wave Software. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + .code + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int8_t __rw_atomic_xchg8 (int8_t *x, int8_t y); +; +; Atomically assigns the 8-bit value y to *x and returns +; the original (before assignment) 8-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_xchg8 +__rw_atomic_xchg8 proc ; int8_t (int8_t *x, int8_t y) + ; %rcx = x + mov al, dl ; %al = y + xchg al, [rcx] ; %al <-> (%rcx) + ret +__rw_atomic_xchg8 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int16_t __rw_atomic_xchg16 (int16_t *x, int16_t y); +; +; Atomically assigns the 16-bit value y to *x and returns +; the original (before assignment) 16-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_xchg16 +__rw_atomic_xchg16 proc ; int16_t (int16_t *x, int16_t y) + ; %rcx = x + mov ax, dx ; %ax = y + xchg ax, [rcx] ; %ax <-> (%rcx) + ret +__rw_atomic_xchg16 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int32_t __rw_atomic_xchg32 (int32_t *x, int32_t y); +; +; Atomically assigns the 32-bit value y to *x and returns +; the original (before assignment) 32-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_xchg32 +__rw_atomic_xchg32 proc ; int32_t (int32_t *x, int32_t y) + ; %rcx = x + mov eax, edx ; %eax = y + xchg eax, [rcx] ; %eax <-> (%rcx) + ret +__rw_atomic_xchg32 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int32_t __rw_atomic_xchg64 (int64_t *x, int64_t y); +; +; Atomically assigns the 64-bit value y to *x and returns +; the original (before assignment) 64-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_xchg64 +__rw_atomic_xchg64 proc ; int64_t (int64_t *x, int64_t y) + ; %rcx = x + mov rax, rdx ; %rax = y + xchg rax, [rcx] ; %rax <-> (%rcx) + ret +__rw_atomic_xchg64 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int8_t __rw_atomic_add8 (int8_t *x, int8_t y); +; +; Atomically increments the 8-bit value *x by y and returns +; the new (after increment) 8-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_add8 +__rw_atomic_add8 proc ; int8_t (int8_t *dst, int8_t inc) + ; %rcx = dst + mov eax, edx ; %eax = inc + + lock xadd [rcx], al ; tmp = *dst + ; dst += inc + ; %al = tmp + add eax, edx ; return %al + inc + ret +__rw_atomic_add8 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int16_t __rw_atomic_add16 (int16_t *x, int16_t y); +; +; Atomically increments the 16-bit value *x by y and returns +; the new (after increment) 16-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_add16 +__rw_atomic_add16 proc ; int16_t (int16_t *dst, int16_t inc) + ; %rcx = dst + mov ax, dx ; %ax = inc + + lock xadd [rcx], ax ; tmp = *dst + ; dst += inc + ; eax = tmp + + add ax, dx ; return %ax + inc + ret +__rw_atomic_add16 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int32_t __rw_atomic_add32 (int32_t *x, int32_t y); +; +; Atomically increments the 32-bit value *x by y and returns +; the new (after increment) 32-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_add32 +__rw_atomic_add32 proc ; int32_t (int32_t *dst, int32_t inc) + ; %rcx = dst + mov eax, edx ; %eax = inc + + lock xadd [rcx], eax ; tmp = *dst + ; dst += inc + ; %eax = tmp + + add eax, edx ; return %eax + inc + ret +__rw_atomic_add32 endp + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; extern "C" int64_t __rw_atomic_add64 (int64_t *x, int64_t y); +; +; Atomically increments the 32-bit value *x by y and returns +; the new (after increment) 32-bit value of *x. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + align 16 + public __rw_atomic_add64 +__rw_atomic_add64 proc ; int64_t (int64_t *dst, int64_t inc) + ; %rcx = dst + mov rax, rdx ; %eax = inc + + lock xadd [rcx], rax ; tmp = *dst + ; dst += inc + ; %eax = tmp + + add rax, rdx ; return %eax + inc + ret +__rw_atomic_add64 endp + + end Property changes on: src\i86_64\atomic.asm ___________________________________________________________________ Name: svn:keywords + Id Name: svn:eol-style + native Index: src/once.cpp =================================================================== --- src/once.cpp (revision 570339) +++ src/once.cpp (working copy) @@ -188,3 +188,32 @@ } // extern "C" } // namespace __rw + +// export __rw_atomic_xxx() functions, defined in atomic.asm +#if defined (_WIN32) && defined (_DLL) + +# if defined (_M_IX86) + +# pragma comment(linker, "/EXPORT:___rw_atomic_add8") +# pragma comment(linker, "/EXPORT:___rw_atomic_add16") +# pragma comment(linker, "/EXPORT:___rw_atomic_add32") +# pragma comment(linker, "/EXPORT:___rw_atomic_xchg8") +# pragma comment(linker, "/EXPORT:___rw_atomic_xchg16") +# pragma comment(linker, "/EXPORT:___rw_atomic_xchg32") + +# elif defined (_M_X64) + +# pragma comment(linker, "/EXPORT:__rw_atomic_add8") +# pragma comment(linker, "/EXPORT:__rw_atomic_add16") +# pragma comment(linker, "/EXPORT:__rw_atomic_add32") +# pragma comment(linker, "/EXPORT:__rw_atomic_xchg8") +# pragma comment(linker, "/EXPORT:__rw_atomic_xchg16") +# pragma comment(linker, "/EXPORT:__rw_atomic_xchg32") + +# ifdef _RWSTD_INT64_T +# pragma comment(linker, "/EXPORT:__rw_atomic_add64") +# pragma comment(linker, "/EXPORT:__rw_atomic_xchg64") +# endif // _RWSTD_INT64_T +# endif // _M_IX86 + +#endif // _WIN32 && _DLL --------------060008020302080408040703--