<nickrobison>
Good morning folks! Does anyone have experience working with the HPX distributed maps? Are they initialized in the same way as the partitioned vectors? I'm running into some strange compile issues.
<hkaiser>
nickrobison: the distributed map is not really finished, sorry
<nickrobison>
Good to know. Would a bug report be helpful?
<hkaiser>
it's half-way done only...
<hkaiser>
absolutely!
<nickrobison>
Consider it done. Also, thank you all for a fantastic project!
<gonidelis[m]>
I am really trying to understand that `has_foo` example
<gonidelis[m]>
In this expression `void_t<decltype(std::declval<T&>().foo())` why is `&` necessary? (rvalue ref maybe?)
<gonidelis[m]>
And a more general question: In the whole example the main idea is that we create two occurancies of `has_foo` in order to check which one compiles (and thus which one has `foo`). But why isn't `class=void` needed in the second occurance? And why does the second `has_foo` need the `<>` ?
<zao>
gonidelis[m]: It might be helpful to read up or experiment on what kind of thing you get from declval<T>; is it considered a temporary?
<gonidelis[m]>
I know that sth like `std::declval<int>()` would do the job... right?
<K-ballo>
std::declval<int>() is an rvalue, std::declval<int&>() is an lvalue
<K-ballo>
this particular `has_foo` trait seems to be detecting only whether a type has a `foo` nullary member function callable on an lvalue instance
<K-ballo>
gonidelis[m]: consider `std::declval<int>() = 3` vs `std::declval<int&>() = 3`, one of those does not compile
<K-ballo>
the need for "two" classes and the defaulted void is the crux of class sfinae, maybe re-read the article or try another
<gonidelis[m]>
ok just on question. When I declare sth like `class my_obj;`, what value is `my_obj`: rvalue or lvalue?
<gonidelis[m]>
(or xvalue maybe????_
<gonidelis[m]>
)
<zao>
In the good old days, lvalues and rvalues were named from which side of an assignment they could be on.
<zao>
lvalues can be on the left side of an op=, rvalues cannot.
<zao>
An lvalue is a "nameable location", kind of.
<K-ballo>
classes aren't values, and to make it more confusing lvalue and rvalue is not a property of values but of expressions
<K-ballo>
my_obj x;
<K-ballo>
x.foo(); // lvalue
<K-ballo>
std::move(x).foo() // xvalue
<K-ballo>
my_obj().foo() // prvalue
<gonidelis[m]>
"...to make it more confusing..." ;p
<zao>
I stopped caring when C++11 came and ruined everything :D
<gonidelis[m]>
thank you guys!
akheir1 has joined #ste||ar
akheir has quit [Ping timeout: 246 seconds]
K-ballo has quit [Ping timeout: 256 seconds]
K-ballo has joined #ste||ar
nikunj97 has joined #ste||ar
alireza has joined #ste||ar
akheir1 has quit [Ping timeout: 246 seconds]
K-ballo has quit [Ping timeout: 272 seconds]
K-ballo has joined #ste||ar
K-ballo1 has joined #ste||ar
K-ballo has quit [Ping timeout: 256 seconds]
K-ballo1 is now known as K-ballo
K-ballo1 has joined #ste||ar
K-ballo has quit [Ping timeout: 264 seconds]
K-ballo1 is now known as K-ballo
alireza has quit [Quit: Leaving]
<Yorlik>
hkaiser: yt ?
<hkaiser>
Yorlik: here
<Yorlik>
I have a very strange bug in a thread_local initialization, since i added a spinlock to its initialization code
<hkaiser>
uhh - deadlock?
<Yorlik>
A thread_local spuriously becomes nullptr, and I guess there is a task migration in the middle of the initialization a possible cause
<hkaiser>
why do you need a spinlock while initializing a thread_local?
<Yorlik>
to protect a map I'm writing the value to, which maps OS thread IDs to pools
<hkaiser>
you need to use a std::mutex or similar in that case
<Yorlik>
I should do that. Good Idea
<hkaiser>
Yorlik: but it sounds fishy to me that you need to store a hpx thread-id into a map during initialization of a thread_local
<Yorlik>
OS thread ID, not hpx
<hkaiser>
ok
<hkaiser>
slightly better, but still murky ;-)
<weilewei>
libcds also uses OS thread id... which needs to be replaced by hpx thread id, just saying
<Yorlik>
I use it to poll instrumentation data, like engine count per thread and stuff
<hkaiser>
so you access a thread_local from a different thread?
<hkaiser>
weilewei: that's not an issue
<weilewei>
ok...
<hkaiser>
Yorlik: ^^
<Yorlik>
Doing some checks .. moment
nikunj97 has quit [Ping timeout: 258 seconds]
<Yorlik>
hkaiser: The mutex fixed it - I'm getting new problems now, but these are most likely unrelated. My new machine uncovered some remaining races I have to track down and fix now.
<hkaiser>
Yorlik: are you accessing thread_locals from a different thread?
<Yorlik>
I can't prove it, but I guess that's what happened because of a task migration.
<Yorlik>
I think we should have a function for initialization of thread locals on workers.
<hkaiser>
what do you store in that map of yours?
<Yorlik>
just something every worker calls at startup where we can customize the thread_local environment
<Yorlik>
I stor an association of OS threads to engine pools
<Yorlik>
This allows me to get a lua engine from the thread local pool and not have a lock
<Yorlik>
I later give back the engine on another thread if needed.
<Yorlik>
If a pool has to many engines I destroy/delete, if there is a lack I recreate
<Yorlik>
So it always rebalances
<hkaiser>
so you access the thread_local from a thread it was not created for
<Yorlik>
I guess that's what happens if there is a task migration during thread_local initialization
<Yorlik>
But again - I haven't proven it
<Yorlik>
Maybe with some logging it could be proven
<hkaiser>
Yorlik: I'd suggest that you avoid doing this by all means
<Yorlik>
I am not doing it intentionally
<hkaiser>
k
<Yorlik>
Absolutely not
<Yorlik>
I am always using the data meant for the local currently running thread.
<Yorlik>
But the spinlock tricked me here.
<Yorlik>
It all would not have happened with a proper worker thread initialization customization point.
<Yorlik>
Can't we just have a function we can override?
<hkaiser>
Yorlik: what for?
<Yorlik>
For example to set up the pools per worker - what I'm doing in a somewhat convoluted way now
<Yorlik>
I can imagine a bunch of things you might want to have thread local per worker
<Yorlik>
Using function thread_locals to set this up is not really elegant, I think.
bita_ has quit [Ping timeout: 260 seconds]
<hkaiser>
Yorlik: I have a hard time understanding what you mean
<Yorlik>
Sometimes you want to use something that is thread_local to your worker and just there and already initialized when you want to use it.
<Yorlik>
E.g. in my case a pool that can give me a lua state.
<Yorlik>
It's a service, an environment I want to set up to run my tasks in.
<Yorlik>
It would be cleaner if i could do this in a dedicated function.
<hkaiser>
Yorlik: make the thread_local a function local static and return the reference to it from the function
<Yorlik>
Just like that executor you wrote, which allows me to set up a task.
<hkaiser>
that will initialize things on demand, on first access
<Yorlik>
That's what I have now.
<hkaiser>
so what's the issue?
<Yorlik>
Not saying it's impossible to work with this.
<hkaiser>
it's rather elegant, I think
<hkaiser>
do the initialization work in the constructor of that thread_local
<Yorlik>
Well - it may just not yield :D
<Yorlik>
Never ever ...
<hkaiser>
right - you should always know what you're doing
<Yorlik>
But flying blind is so much more exciting :P