higan-emu/libco

Support building with MSVC

Closed this issue · 9 comments

Hi there, I'm trying to compile the example test_timing.cpp under Windows. MSys2+MinGW-gcc worked.
With VS2019, however, I get

C2341 segment must be defined using #pragma data_seg, code_seg or section prior to use

in amd64.c here

If I change it to

  #ifdef _MSC_VER
    #pragma data_seg(".text")
  #endif

I get libco.obj : warning LNK4078: multiple '.text' sections found with different attributes (60500020).
Please advise.
Thank you!

Also, I get this access violation:
2021-09-12 20_08_55-testing (Debugging) - Microsoft Visual Studio

If you would like to reproduce this issue, this is the premake file I used to generate the project. The extension should be changed to .lua. Thank you again!
premake5.txt

The co_swap_function global variable actually contains program code, not data, so the linker needs to be told to store it in the code segment, not the data segment. In Unixy platforms (and apparently MinGW) this segment is called "text", which is why we have section(text) and similar incantations, but I don't know how to achieve that with MSVC. Possibly #pragma code_seg(".text") is part of it, but that's just a guess based on the error messages you pasted.

If you figure out how to get it working, and it's not too invasive, I would review a PR to add MSVC support.

Current support for MSVC requires you to have LIBCO_MPROTECT defined; this would use VirtualProtect on Windows to ensure the memory has the appropriate permissions at runtime.


Reading documentation, it appears that this should work:

#pragma section(".text") 

__declspec(allocate(".text"))
static const unsigned char co_swap_function[4096] = {

Would you be able to test?

It works. All's I had to do was define LIBCO_MPROTECT and uncomment alignas(4096)

context-switching timing test

MinGW-gcc/Release

0.789 seconds per  50 million subroutine calls (500000000 iterations)
10.147 seconds per 100 million co_switch  calls (500000000 iterations)
co_switch skew = 12.860583x

MSVC/Release

0.968 seconds per  50 million subroutine calls (500000000 iterations)
7.018 seconds per 100 million co_switch  calls (500000000 iterations)
co_switch skew = 7.250000x

Same machine, under Ubuntu

context-switching timing test

0.824 seconds per  50 million subroutine calls (500000000 iterations)
3.252 seconds per 100 million co_switch  calls (500000000 iterations)
co_switch skew = 3.945070x

@merryhime @Screwtapello Could you please review my PR? I hope adding premake is ok for you?

There is at least one mistake in my PR here. This filters every Visual Studio project. Since VS is also a thing on macOS, this line should read
filter { "system:windows", "action:vs*" }

Our new GitHub Actions CI builds and runs our examples on MSVC, so I believe MSVC is now properly supported.