-
-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cannot build with msvc x86 #38
Comments
I have tried it on windows 10 with vs2015. Everything is ok. Maybe you could try to add an undefine in xmake.lua as below: if is_plat("windows") then
add_cxflags("-Ox", "-fp:fast", "-EHsc")
add_files("**.cpp")
if is_arch("x64") then
add_files("co/context/context_x64.asm")
else
add_files("co/context/context_x86.asm")
add_undefines("_WIN64")
end
end |
As I can know, on 32 bit platform, #ifdef _WIN32
#pragma warning (disable:4800)
#include <intrin.h>
#ifndef _WIN64
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif You may simply add |
Hi, thank you for your feedback. This is strange, I tried your solution but still got the same error. Meanwhile, I check However, I check MSDN and it seems these |
I have found it in LONGLONG
FORCEINLINE
_InterlockedIncrement64 (
_Inout_ _Interlocked_operand_ LONGLONG volatile *Addend
)
{
LONGLONG Old;
do {
Old = *Addend;
} while (InterlockedCompareExchange64(Addend,
Old + 1,
Old) != Old);
return Old + 1;
} |
Now I find it in |
Anyway, would it be possible to disable these |
Should also work on x86? May you have a test on it? |
Not work here 😂 Maybe we need more guys or more machines to test if this is a real issue. |
I got another computer and freshly installed visual studio 2019 and xmake. Still x86 cannot be built, neither with 2015 build toolset nor 2019 build toolset. I guess this is an actual problem. |
I have the same issue when compiling in visual studio 2019 for x86. #define __MACHINEARM_ARM64_X64 __MACHINEZ #define __MACHINEZ(X) /* NOTHING */ I guess izhengfan is right that x86 may not support it under certain versions, and they put /* NOTHING */ in their defination |
@izhengfan @dasuren |
@idealvin Need to add declaration through pragma intrinsic first. msvc will use it as a built-in function without links. __int64 _InterlockedExchangeAdd64(__int64 volatile* Destination, __int64 Value);
#pragma intrinsic(_InterlockedExchangeAdd64) You can see https://github.com/tboox/tbox/blob/master/src/tbox/platform/windows/atomic64.h |
@idealvin undef _MANAGED does not work. According to @waruqi 's comments, I added the lines below: diff --git a/base/win/atomic.h b/base/win/atomic.h
index d53e146..733832e 100644
--- a/base/win/atomic.h
+++ b/base/win/atomic.h
@@ -8,6 +8,20 @@
#ifndef _WIN64
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
+__int64 _InterlockedIncrement64(__int64 volatile* Dest);
+#pragma intrinsic(_InterlockedIncrement64)
+__int64 _InterlockedDecrement64(__int64 volatile* Dest);
+#pragma intrinsic(_InterlockedDecrement64)
+__int64 _InterlockedExchangeAdd64(__int64 volatile* Dest, __int64 value);
+#pragma intrinsic(_InterlockedExchangeAdd64)
+__int64 _InterlockedOr64(__int64 volatile* Dest, __int64 value);
+#pragma intrinsic(_InterlockedOr64)
+__int64 _InterlockedAnd64(__int64 volatile* Dest, __int64 value);
+#pragma intrinsic(_InterlockedAnd64)
+__int64 _InterlockedXor64(__int64 volatile* Dest, __int64 value);
+#pragma intrinsic(_InterlockedXor64)
+__int64 _InterlockedExchange64(__int64 volatile* Dest, __int64 value);
+#pragma intrinsic(_InterlockedExchange64)
#endif Now building of base, rpcgen and test pass, but unitest has link error:
|
Try adding #ifdef __cplusplus
extern "C" {
#endif
__int64 _InterlockedExchangeAdd64(__int64 volatile* Destination, __int64 Value);
#pragma intrinsic(_InterlockedExchangeAdd64)
#ifdef __cplusplus
}
#endif |
Written like https://github.com/izhengfan/co/blob/dev-with-ci/base/win/atomic.h#L16, still not work. I made a tiny CI script, you can check the result at https://github.com/izhengfan/co/commit/4cf5ebe226c76b343752025212a2b4f0b17a63ca/checks?check_suite_id=375823384 |
Because only _InterlockedCompareExchange64 exists for x86/msvc, so we need wrap other atomic64 apis using _InterlockedCompareExchange64. |
Sorry I still do not understand how to do it, could you directly fix the code in this repo? |
Hi All,
I moved all the 64 bits related functions to another block with #ifdef _WIN64. For 64 bit,it compiles fine and pass all the unit test.
which could be caused by the test cases like follows: where a _int64 parameter are passed to the 32bit application, where related code are skipped. Then I tried to replace _InterlockedExchange64 with some function which can be used under 32 bits and accept _int64 as parameter. However, it seems all the _int64 related functions are defined with _int64 parameter are end with **64. I remove all the 64 bit test case under x86 compiler, and now it pass all the test cased. So I have two questions: 1. do we need to use and test _int64 as input for x86 application? |
@dasuren I think this is a workaround, but not a good enough solution. For 32bit application, it is still desirable to have 64bit atomic operation. |
Need use _InterlockedCompareExchange64 to wrap other atomic64 apis for x86, because only _InterlockedCompareExchange64 exists for x86/msvc. for example: extern "C" {
__int64 _InterlockedCompareExchange64(__int64 volatile* Destination, __int64 Exchange, __int64 Comperand);
#pragma intrinsic(_InterlockedCompareExchange64)
}
static inline __int64 _InterlockedIncrement64 (__int64 volatile *Addend)
{
__int64 Old;
do {
Old = *Addend;
} while (_InterlockedCompareExchange64(Addend, Old + 1, Old) != Old);
return Old + 1;
} |
Thanks Waruqi for your suggestion and help. I did some research on "#pragma intrinsic" and FORCEINLINE. but still got confused by code where three parameter "declared" but only one is defined.And visual studio think it is legal....Guess I need to go back to the text books...wow, feels like I am using a fake C++ in the past several year.. :) |
Thanks to @waruqi 's instructions, I now successful fix this problem, like this: diff --git a/base/win/atomic.h b/base/win/atomic.h
index d53e146..a8e931f 100644
--- a/base/win/atomic.h
+++ b/base/win/atomic.h
@@ -8,6 +8,17 @@
#ifndef _WIN64
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
+extern "C" {
+__int64 _InterlockedCompareExchange64(__int64 volatile* Destination, __int64 Exchange, __int64 Comperand);
+#pragma intrinsic(_InterlockedCompareExchange64)
+}
+#define _InterlockedIncrement64 InterlockedIncrement64
+#define _InterlockedDecrement64 InterlockedDecrement64
+#define _InterlockedExchangeAdd64 InterlockedExchangeAdd64
+#define _InterlockedOr64 InterlockedOr64
+#define _InterlockedAnd64 InterlockedAnd64
+#define _InterlockedXor64 InterlockedXor64
+#define _InterlockedExchange64 InterlockedExchange64
#endif
namespace xx { Also, I notice that although x86 MSVC does not provide API like //@file winnt.h
LONGLONG
FORCEINLINE
_InlineInterlockedIncrement64 (
_Inout_ _Interlocked_operand_ LONGLONG volatile *Addend
)
{
LONGLONG Old;
do {
Old = *Addend;
} while (InterlockedCompareExchange64(Addend,
Old + 1,
Old) != Old);
return Old + 1;
}
#define InterlockedIncrement64 _InlineInterlockedIncrement64 |
@izhengfan //extern "C" {
//__int64 _InterlockedCompareExchange64(__int64 volatile* Destination, __int64 Exchange, __int64 Comperand);
//#pragma intrinsic(_InterlockedCompareExchange64)
//} Does it also work on your platform? |
@idealvin Yes, it still works. I guess win32 SDK has handled it well, so we don't need these lines. |
👌 Thanks for your work. |
Under
co/base/
:The text was updated successfully, but these errors were encountered: