Skip to content
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

Need correction for std::future (and probably std::shared_mutex) #17

Open
philave opened this issue Apr 28, 2017 · 6 comments
Open

Need correction for std::future (and probably std::shared_mutex) #17

philave opened this issue Apr 28, 2017 · 6 comments

Comments

@philave
Copy link

philave commented Apr 28, 2017

Currently, std::future class doesn’t work as all of its implementation is hidden under _GLIBCXX_HAS_GTHREADS macro. g++ generates error: invalid use of incomplete type 'class std::future'

@alxvasilev
Copy link
Contributor

The scope of this project initially was to provide just the basic platform-dependent primitives, on top of which the rest of the missing functionality could be implemented. Contribution of implementation of the remaining missing functionality is certainly welcome.

@ashdnazg
Copy link

ashdnazg commented Jul 9, 2017

@lhmouse
Copy link

lhmouse commented Jan 24, 2018

I think you will be interested in https://gcc-mcf.lhmouse.com/. 😂

Rather than reinvent std::thread, std::mutex, std::condition_variable etc once more, I decided to implement __gthread_* functions directly which GCC's threading stuff is based on, which eventually enables everything including std::once_flag, std::promise, std::shared_mutex, std::notify_all_at_thread_exit(), etc.

Introduction: https://github.com/lhmouse/mcfgthread/wiki
Benchmarking: https://github.com/lhmouse/mcfgthread/wiki/Benchmarking

@cvtsi2sd
Copy link
Contributor

cvtsi2sd commented Jan 26, 2018

@lhmouse I'm all for fixing this stuff at the gthread level and then just letting libstdc++ do its own thing, but I'd rather avoid:

  • breaking compatibility with older Windows versions
  • exploiting undocumented interfaces

In facts, I was thinking of completing the gthr-win32 stuff with what is missing (essentially, thread creation/join/detach and condition variables). It would be nice to finally have the choice between mcfgthread (bleeding edge, for new systems) and a complete classic win32 thread model (slower, but with a simpler and more compatible implementation).

I'm particularly obsessed by the idea of having a "simple", reliable gthread layer, as the "posix" (=winpthread) threading model aimed to something similar, but unfortunately is complex, messy code, is subtly broken (we found race conditions in thread creation/join/detach, with threads ending up having their associated support structure completely mixed up), with no clear way to salvage it. The fact that the bug linked above went completely ignored is also a strong indicator that winpthreads is essentially abandoned.

@lhmouse
Copy link

lhmouse commented Jan 26, 2018

@cvtsi2sd

@lhmouse I'm all for fixing this stuff at the gthread level and then just letting libstdc++ do its own thing, but I'd rather avoid:

  • breaking compatibility with older Windows versions
  • exploiting undocumented interfaces

Well then you might have few other options. You have to either implement condition variables yourself (it is hard to implement correctly, we know) or use the native one since Vista.

In facts, I was thinking of completing the gthr-win32 stuff with what is missing (essentially, thread creation/join/detach and condition variables).

You can do that. GCC's gthr.h has documented what is needed well.

It would be nice to finally have the choice between mcfgthread (bleeding edge, for new systems) and a complete classic win32 thread model (slower, but with a simpler and more compatible implementation).

Thank you.

I'm particularly obsessed by the idea of having a "simple", reliable gthread layer, as the "posix" (=winpthread) threading model aimed to something similar, but unfortunately is complex, messy code, is subtly broken (we found race conditions in thread creation/join/detach, with threads ending up having their associated support structure completely mixed up), with no clear way to salvage it. The fact that the bug linked above went completely ignored is also a strong indicator that winpthreads is essentially abandoned.

I can't agree with you more. There are more issues with winpthreads. The fact that the bug is ignored might be due to the requirement of specialized knowledge. People can't fix it without enough knowledge, which is not practical either because those people have been busy with their work, life, etc.

Hence the goal of mcfgthread is to be as tiny as possible. There is little unnecessary code. A few important implementation details are documented on its Wiki pages.

@nmcclatchey
Copy link
Contributor

With shared_mutex implemented, it's time to take a fresh look at which features are still missing:

  • File "mingw.condition_variable.h" does not supply the function notify_all_at_thread_exit.
    • Full compliance is impractical.
      • Full compliance requires a mutex to remain locked until after all thread-local variables are destroyed.
      • Thread-local variables are only destroyed after thread exit. I see no way to run code in the same thread after this point.
      • Mutex behavior is defined only when
    • Partial compliance is possible.
      • Can add a "cleanup" function pointer, called in-thread after the user-specified code returns or throws.
        • Not compliant because this will occur before destruction of thread-local storage.
      • For Windows XP and higher, can spawn a new thread that uses WaitForSingleObject on the original thread to wait for it to exit.
        • Not compliant because passing the mutex to the waiting thread would require unlocking it in the original thread and re-locking it in the waiting thread.
      • For Windows Vista and higher, can use the Fiber Local Storage callback to make Windows call a function on thread exit.
        • Not compliant because FLS callback is not guaranteed to occur after destruction of thread-local storage; this then provides little or no advantage over modifying the function passed to the thread.
        • Would require care to call FlsAlloc exactly once, to avoid consuming the entirety of a a finite resource.
  • File "mingw.future.h" is missing.
    • Full compliance is practical.
      • Unlike notify_all_at_thread_exit, the functions std::promise::make_ready_at_thread_exit and std::promise::set_value_at_thread_exit can use a waiter-thread without transferring ownership of a mutex between threads, depending on how the classes are implemented.
        • For Windows XP and higher, can spawn a new thread that uses WaitForSingleObject on the original thread to wait for it to exit.
    • The existing MinGW implementation might possibly be used, depending on details of its implementation. See the above comment by ashdnazg.
      • Using the header itself, rather than selectively copying features, would require a hack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants