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

concurrent_queue does not work when the object only has constructor with arguments #885

Closed
VitorRamos opened this issue Aug 26, 2022 · 3 comments · Fixed by #886
Closed
Labels

Comments

@VitorRamos
Copy link

VitorRamos commented Aug 26, 2022

The problem:

#include <oneapi/tbb.h>
#include <oneapi/tbb/concurrent_queue.h>

class A
{
public:
    A(int a, int b) { }
};

int main(){
    oneapi::tbb::concurrent_queue<A> q1;
}

Compiler output

g++ -I repos/oneTBB/include -L repos/oneTBB/build/gnu_11.2_cxx11_64_relwithdebinfo main.cpp -ltbb -o main
In file included from repos/oneTBB/include/oneapi/tbb.h:42,
                 from main.cpp:1:
repos/oneTBB/include/oneapi/tbb/concurrent_queue.h: In instantiation of ‘void tbb::detail::d2::concurrent_queue<T, Allocator>::clear() [with T = A; Allocator = tbb::detail::d1::cache_aligned_allocator<A>]’:
repos/oneTBB/include/oneapi/tbb/concurrent_queue.h:111:9:   required from ‘tbb::detail::d2::concurrent_queue<T, Allocator>::~concurrent_queue() [with T = A; Allocator = tbb::detail::d1::cache_aligned_allocator<A>]’
main.cpp:11:38:   required from here
repos/oneTBB/include/oneapi/tbb/concurrent_queue.h:152:15: error: no matching function for call to ‘A::A()’
  152 |             T value;
      |               ^~~~~
main.cpp:7:5: note: candidate: ‘A::A(int, int)’
    7 |     A(int a, int b) { }
      |     ^
main.cpp:7:5: note:   candidate expects 2 arguments, 0 provided
main.cpp:4:7: note: candidate: ‘constexpr A::A(const A&)’
    4 | class A
      |       ^
main.cpp:4:7: note:   candidate expects 1 argument, 0 provided
main.cpp:4:7: note: candidate: ‘constexpr A::A(A&&)’
main.cpp:4:7: note:   candidate expects 1 argument, 0 provided
make: *** [Makefile:5: all] Error 1

The problem is cause by the function clear of concurrent_queue (oneTBB/include/oneapi/tbb/concurrent_queue.h:152) that instantiates an object to to be popped and clear the queue.

bool try_pop( T& result ) {
    return internal_try_pop(&result);
}

void clear() {
    while (!empty()) {
        T value;
        try_pop(value);
    }
}

Is it possible to use void* so that we can use concurrent_queue in these cases?

void clear() {
    while (!empty()) {
        void *value = malloc(sizeof(T));
        internal_try_pop(value);
        free(value);
    }
}

If that is ok, I can submit a PR.

@kboyarinov
Copy link
Contributor

@VitorRamos, thank you for reporting the issue and proposing the solution.
Unfortunately, it would not work because it results in undefined behavior - call to malloc only allocates the memory for value and then it would be assigned inside of internal_try_pop. It results in assigning the value that was not created by the constructor call.
We also cannot explicitly call the constructor because we do not know which constructors are available and would not want to require any.
I have made a quick fix in PR #886 that explicitly informs the internal_try_pop that the value popped should not be assigned . It should fix the issue.

@VitorRamos
Copy link
Author

@kboyarinov, thanks for the fix and explanation.

@kboyarinov
Copy link
Contributor

@VitorRamos, I have just merged the fix into oneTBB master.
Feel free to re-open the issue or create a separate one if it does not satisfy your use case.

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

Successfully merging a pull request may close this issue.

2 participants