meganz / mingw-std-threads

Standard threads implementation currently still missing on MinGW GCC on Windows
BSD 2-Clause "Simplified" License
439 stars 137 forks source link

tests.cpp file not working #49

Closed ghost closed 5 years ago

ghost commented 5 years ago

I downloaded and ran tests.cpp file in codeblocks, and I get a bunch of error, first being '::GetNativeSystemInfo has not been declared'. I suppose I have wrong mingw version, since this implementation of standard threads doesnt work out of the box?

ghost commented 5 years ago

Solution: I had to put #define _WIN32_WINNT 0x0501 in first line (before all includes).

nmcclatchey commented 5 years ago

It is, in fact, supposed to work out of the box. That it doesn't means that something has changed between the MinGW version you use and the ones on which we have tested the library.

The problem is likely to be a different default Windows version. If this is the case, we can almost certainly give a more useful diagnostic when problems occur.

If you do not define _WIN32_WINNT, what value is assigned to it when you include <windows.h> (if any)?

ghost commented 5 years ago

Without '#include "mingw.thread.h"' and '#define _WIN32_WINNT 0x0501', and writing '#include ' I wrote 'auto a = _WIN32_WINNT;' in main, went into debugger, checked value of a, which it was 1280 (int).

I have laptop from work, so I am guessing that my Windows are modified by company's IT so that some OS function are private, some disabled, ..., which is why this wrapper didn't work out of the box. Just a guess though.

nmcclatchey commented 5 years ago

Your version of MinGW has a default target Windows version of Windows 2000 (which didn't have thread support). This is good to know; it means we can check both for when a user requests to target an unsupported Windows version, and for when the default is insufficient. In either case, an error should be raised, though the latter case could also be extended to give performance hints such as "Select a target of Windows 7 for better performance. Here's how."

When MinGW, MSVC, etc. are configured to target a version of Windows before Windows XP, the system header windows.h typically will not include the signatures of functions not provided by the system. In the case of Windows 2000, those missing signatures include many of the functions vital for this library, such as functions used to join threads.

I expect to submit a PR with the errors/hints soon.

ghost commented 5 years ago

Thank you very much for your help, hope this bug (?) will be solved.

alxvasilev commented 5 years ago

BTW, what is the version of your MinGW? You can check by invoking the compiler with the --version flag.

nmcclatchey commented 5 years ago

Thank you very much for your help, hope this bug (?) will be solved.

It's not a bug, despite appearances. Your version of MinGW is configured to select Windows 2000 by default, and this is simply insufficient to support this library. This library depends on Windows XP features, and makes that explicit in the README. This library will also benefit from later versions; targeting Windows 7, for example, will improve the performance of condition_variables and mutexes.

Ideally, we would check whether _WIN32_WINNT is defined before including <windows.h>, and define it ourselves if it were not. However, we would need to make sure that the value we set is not less than the version that MinGW would use by default (a potentially-difficult process, as power-users may have set the default themselves when building MinGW).

@alxvasilev's question about the version of MinGW you are using is probably intended for this purpose. If we can determine the version of MinGW at which the default Windows target was first changed to Windows XP, we can use that information to adjust the default whenever it would be insufficient.

ghost commented 5 years ago

BTW, what is the version of your MinGW? You can check by invoking the compiler with the --version flag.

Sorry for late reply, I was sick. Is this what you are asking?

image

changshen commented 5 years ago

I have same problem. windows 10. gcc (GCC) 7.3.0

I download the zip file, unzip them to mingw\include folder using C::B 17.12 in compiler setting:->#defines: _WIN32_WINNT=0x0A00 add one line to test.cpp

include

Lots error.

mingw.mutex.h|162|error: 'SRWLOCK_INIT' was not declared in this scope| mingw.mutex.h||In member function 'void mingw_stdthread::recursive_timed_mutex::lock()':| mingw.mutex.h|324|error: 'owner_dead' is not a member of 'std::errc'| mingw.mutex.h|325|error: 'protocol_error' is not a member of 'std::errc'| mingw.shared_mutex.h|73|error: 'CHAR_BIT' was not declared in this scope| mingw.condition_variable.h|264|error: 'CONDITION_VARIABLE_INIT' was not declared in this scope| mingw.condition_variable.h||In member function 'bool mingw_stdthread::vista::condition_variable::wait_unique(mingw_stdthread::windows7::mutex, DWORD)':| mingw.condition_variable.h|312|error: 'CONDITION_VARIABLE_LOCKMODE_SHARED' was not declared in this scope| mingw.condition_variable.h||In member function 'bool mingw_stdthread::vista::condition_variable_any::wait_impl(mingw_stdthread::shared_lock&, DWORD)':| mingw.condition_variable.h|440|error: 'CONDITION_VARIABLE_LOCKMODE_SHARED' was not declared in this scope| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = int]':| test.cpp|200|required from 'struct test_future() [with T = int]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = int]'| test.cpp|392|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = int]':| test.cpp|208|required from 'struct test_future() [with T = int]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = int]'| test.cpp|392|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = int]':| test.cpp|216|required from 'struct test_future() [with T = int]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = int]'| test.cpp|392|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = int]':| test.cpp|242|required from 'void test_future() [with T = int]'| test.cpp|392|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = void]':| test.cpp|200|required from 'struct test_future() [with T = void]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = void]'| test.cpp|393|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = void]':| test.cpp|208|required from 'struct test_future() [with T = void]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = void]'| test.cpp|393|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = void]':| test.cpp|216|required from 'struct test_future() [with T = void]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = void]'| test.cpp|393|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = void]':| test.cpp|242|required from 'void test_future() [with T = void]'| test.cpp|393|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = int&]':| test.cpp|200|required from 'struct test_future() [with T = int&]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = int&]'| test.cpp|394|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = int&]':| test.cpp|208|required from 'struct test_future() [with T = int&]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = int&]'| test.cpp|394|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = int&]':| test.cpp|216|required from 'struct test_future() [with T = int&]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = int&]'| test.cpp|394|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = int&]':| test.cpp|242|required from 'void test_future() [with T = int&]'| test.cpp|394|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = const int&]':| test.cpp|200|required from 'struct test_future() [with T = const int&]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = const int&]'| test.cpp|395|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = const int&]':| test.cpp|208|required from 'struct test_future() [with T = const int&]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = const int&]'| test.cpp|395|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = const int&]':| test.cpp|216|required from 'struct test_future() [with T = const int&]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = const int&]'| test.cpp|395|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = const int&]':| test.cpp|242|required from 'void test_future() [with T = const int&]'| test.cpp|395|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = volatile int&]':| test.cpp|200|required from 'struct test_future() [with T = volatile int&]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = volatile int&]'| test.cpp|396|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = volatile int&]':| test.cpp|208|required from 'struct test_future() [with T = volatile int&]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = volatile int&]'| test.cpp|396|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = volatile int&]':| test.cpp|216|required from 'struct test_future() [with T = volatile int&]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = volatile int&]'| test.cpp|396|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = volatile int&]':| test.cpp|242|required from 'void test_future() [with T = volatile int&]'| test.cpp|396|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = const volatile int&]':| test.cpp|200|required from 'struct test_future() [with T = const volatile int&]::<lambda()>'| test.cpp|200|required from 'void test_future() [with T = const volatile int&]'| test.cpp|397|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|203|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda()> [with T = const volatile int&]':| test.cpp|208|required from 'struct test_future() [with T = const volatile int&]::<lambda()>'| test.cpp|208|required from 'void test_future() [with T = const volatile int&]'| test.cpp|397|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|211|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'test_future()::<lambda(mingw_stdthread::thread::id)> [with T = const volatile int&]':| test.cpp|216|required from 'struct test_future() [with T = const volatile int&]::<lambda(class mingw_stdthread::thread::id)>'| test.cpp|216|required from 'void test_future() [with T = const volatile int&]'| test.cpp|397|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|219|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T test_future()::Helper::call() const [with T = const volatile int&]':| test.cpp|242|required from 'void test_future() [with T = const volatile int&]'| test.cpp|397|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: format '%s' expects argument of type 'char', but argument 2 has type 'std::size_t {aka unsigned int}' [-Wformat=]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|238|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'T CustomAllocator::allocate(size_t) [with T = mingw_stdthread::detail::FutureStateAllocated<int, CustomAllocator >; size_t = unsigned int]':| test.cpp|399|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|92|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|92|note: in expansion of macro 'LOG'| test.cpp||In instantiation of 'void CustomAllocator::deallocate(T*, size_t) [with T = mingw_stdthread::detail::FutureStateAllocated<int, CustomAllocator >; size_t = unsigned int]':| test.cpp|404|required from here| test.cpp|27|warning: unknown conversion type character 'z' in format [-Wformat=]| test.cpp|97|note: in expansion of macro 'LOG'| test.cpp|27|warning: too many arguments for format [-Wformat-extra-args]| test.cpp|97|note: in expansion of macro 'LOG'|

nmcclatchey commented 5 years ago

@changshen In one case (error: 'CHAR_BIT' was not declared in this scope) it is a problem with the library itself, and will be fixed shortly (#51).

In other cases, the source is not obvious, and I have not been able to replicate the error. In particular, error: 'SRWLOCK_INIT' was not declared in this scope and the like are not occurring. If you can prepare an example where that occurs (including the .cbp file and all changes you made), it will be quite helpful.

In yet other cases, the problem is with your compiler settings. For example, the error mingw.mutex.h|324|error: 'owner_dead' is not a member of 'std::errc' (and most of the other errors you encounter) should only appear if you are compiling for a version of C++ earlier than C++11. I'm not sure why you're not encountering the #error commands that are intended to warn about this, but perhaps we can determine that shortly.

changshen commented 5 years ago

Thanks Dr. McClatchey in C:B I checked compiler option to use c++11. I just created a console project, replace main.cpp with the test.cpp code. add #include at the beginning, and compile the code. The header files are copied into MinGW include folder. This include folder is in the search path of C::B

nmcclatchey commented 5 years ago

@changshen I am pressed for time, right now, but I'll be able to investigate this in more detail next Thursday (February 28th). I hope you will be available to provide feedback as we explore the exact reasons for the errors that occurred.

Before then, try eliminating all #include "mingw.*.h" lines and the code specific to the MinGW std threads library (leave only logging statements in the test file). If my intuition is correct, this will still fail to compile, despite not interacting with the threading library. If even a pared-down test file does not compile, the error messages produced should give further insight into the problem you are encountering.

nmcclatchey commented 5 years ago

The remaining errors (not warnings) should be resolved by 079f9e6 . That commit changes handling of mutexes, and replaces the standard-library error codes with direct copies of the error codes that Windows supplies. It also alters behavior in the event of a recursive_mutex_* being accessed after a thread that holds it is terminated.

changshen commented 4 years ago

I have MingW on Windows 10. That windows.h in MinGW returns value as 0x500 Win version HEX = 0x500; WINVER = 0x500; WINNTVER(NTDDI_VERSION) = 0x500. Is that mean MinGW for windows 10 does not support threading? When I define global compiler settigns->#define with"_WIN32_WINNT=0x0700" I got compilation error: (code::block version 17.12, ) mingw.mutex.h |176 | error: 'SRWLOCK_INIT' was not declared in this scope mingw.condition_variable.h | 278 | error: 'CONDITION_VARIABLE_INIT' was not declared in this scope mingw.condition_variable.h | 326 | error: 'CONDITION_VARIABLE_LOCKMODE_SHARED' was not declared in this scope My Gcc compiler version: g++ (MinGW.org GCC-8.2.0-3) 8.2.0 Copyright (C) 2018 Free Software Foundation, Inc. comiler option is: mingw32-g++.exe -Wall -std=c++14 -fPIC -m32 -fexceptions -g -D_WIN32_WINNT=0x0700

update: I added those line to test,cpp and it compiles. Those variables are defined in windows visual studio c++ headers. But I am using MinGW so those headers are not in the search path. How to handle those correctly?

define RTL_SRWLOCK_INIT {0}

define RTL_CONDITION_VARIABLE_INIT {0}

define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1

define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT

define SRWLOCK_INIT RTL_SRWLOCK_INIT

unsigned long CONDITION_VARIABLE_LOCKMODE_SHARED = RTL_CONDITION_VARIABLE_LOCKMODE_SHARED;