Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 03 Nov 2004
Offline Last Active Yesterday, 04:26 PM

#5296473 Work queue with condition variable - design issue

Posted by Rattrap on 14 June 2016 - 08:15 AM

I've done something similar recently (not the priority side).


I actually made an atomic enum that tracked the state of the worker thread.

enum class WorkerThreadState : int

std::atomic<WorkerThreadState> State{WorkerThreadState::CheckingForJob};

I could then use the atomic compare_exchange commands to test the state to see if it was safe to change or if it had changed to a terminating state, leave it alone.

And since I had a reference to the state outside of the thread, I could query what the thread was doing at the moment.



Thread would start as CheckingForJob.  It would atomically check if the State was still CheckingForJob before checking the queue.  If it wasn't, then it was likely triggered to shutdown (Terminating).  This could have happened while processing a previous job.  Once a job was retrieved, it was set to RunningJob.  If no jobs were available, it would be set to Sleeping and wait for a condition variable to be triggered to check again.  The controlling thread would set the variable to Terminating when it was ready for it to shut down.  When set to Terminating, once whatever job it was working on was complete, it would stop the loop and set itself as ReadyToJoin.  A function outside the WorkerThread would check the vector of worker threads for threads that were ReadyToJoin and call join on them, then remove them from the vector.

#5296325 When things don't look the way things are

Posted by Rattrap on 13 June 2016 - 07:21 AM

I can't stand warnings either.  Currently the ones that have driven me the most mad are Intellisense warnings in VS 2015.  The code is right and works, but I think the templated nature of the code is a little too much for Intellisense. It reports that a function doesn't exist, despite compiling and executing just fine.


I remember doing something similar. I started writing a forum post so some other eyes could look at some code I couldn't get to compile and looked right to me.  As I was writing the post, I was actually writing out a list of expected responses, which then led me to realize what was actually wrong with the code.

#5294143 Creating Cross-Platform Code

Posted by Rattrap on 30 May 2016 - 06:40 AM

Thought I'd add that the upcoming Windows 10 Anniversary update will be adding some "native" Linux support. While you might not be able to test the program itself (not sure how much will or won't work), you will be able to run GCC from bash directly from Windows.

#5288016 Going multi-threaded | Batches and Jobs

Posted by Rattrap on 21 April 2016 - 12:08 PM

To my knowledge, C/C++ by itself has no notion of multi-threading.


As of C++11, C++ does have native thread support.

#5276198 [Visual C++] *.obj creation folder

Posted by Rattrap on 17 February 2016 - 03:38 PM

What I do to get around this is have VC++ makes all of the sub directories in the object folders.


In the Project Property Pages -> C/C++ -> Output Files

Object File Name = $(IntDir)%(RelativeDir)\

#5276148 VS2015 without internet explorer

Posted by Rattrap on 17 February 2016 - 11:07 AM

Suppose i get to register it somehow - will it keep working without internet explorer?


It does require an occasional re-checkin, so you might have issues.

#5270888 Wrong template instantiation with SFINAE

Posted by Rattrap on 13 January 2016 - 11:11 AM

This one is a long shot, but have you tried throwing a breakpoint on the non-ref AddRef and check to see if anything looks weird about the template parameter or the function parameters when it gets called?


And I definately get not being able to share everything, I'm just trying to fill in the gaps where I can :)

#5270878 Wrong template instantiation with SFINAE

Posted by Rattrap on 13 January 2016 - 10:38 AM

I see what your saying about the non-reffed version.  I tried stripping it down some (replaced ai:BehaviorTree with an empty class Test2 since I don't have all your headers),  Both calls ended up calling the first version of the function, which would seem to be the correct behavior, since it should only be the wrapper Asset getting manipulated.  Now something I notice (and am guessing this is just a bad cut and paste or just not a complete code), is that

TestAsset asset(L"Testing");

shouldn't work in your posted code, since in your example I don't see any kind of constructor of Asset that would pass along the parameter into the ai:BehaviorTree constructor.

#5270862 Wrong template instantiation with SFINAE

Posted by Rattrap on 13 January 2016 - 09:23 AM

It looks like it revolves around your decltype for the returns.  When I comment them out, it works fine.  I'm guess it has to do with trying to set the return type to void using the decltype (since the function doesn't have a return call).  So it is defaulting to the version that already has void as a return type.  long and int are effectively the same type in VS, so I don't think that would stop anything.



And thinking about it more (without further testing), void() might be making a return type of a function pointer with a return type of void, not the actual void type.

class Test
  void AddRef(){}
struct refCountHelper
  template <typename ObjectType>
  static auto AddRef(ObjectType* pObject)/* -> decltype(AddRef(pObject, 0))*/
    return AddRef<ObjectType>(pObject, 0);
  template <typename ObjectType>
  static auto AddRef(ObjectType* pObject, int)/* -> decltype(pObject->AddRef(), void())*/
    if (pObject)
  template<typename ObjectType>
  static void AddRef(ObjectType* pObject, long)
int main(int argc, char* argv[])
Test* test = new Test();
return 0;

#5269673 Criticism of C++

Posted by Rattrap on 06 January 2016 - 01:06 PM

At that moment, you wish you had never heard of constexpr (at least that's what I felt like!). Because if you had been told ahead of time that the function would be evaluated at runtime anyway, you would have used a better algorithm.


I feel the same way.  I love the concept, but it can be annoying sometimes.  I had a bit counting function implemented that called the Microsoft intrinsic version when it was available.  When VS2015 was released, I thought I was being clever and had implemented the fallback as a constexpr function.  Only to get smacked in the face by the fact that the intrinsic specializations couldn't coexist with the constexpr version.  They had to be named separate, which defeats what I was hoping for (not really thinking about how it would really work)... If it can be at compile-time, do it at compile-time.  If it can't be, use the intrinsic version if available, else the fallback.

#5265613 std::thread arguments and copies

Posted by Rattrap on 09 December 2015 - 12:59 PM

I think you're right, it's a bug in the MSVC implementation that non-copyable arguments don't work. I remember looking this up before. I wonder if it's fixed in the VS2015 compiler.

Tried it in VS2015.
Only got

constructed in 8456

as the result.
Added a sleep before the end of the code and got

constructed in 1216
called in 5312
destroyed in 5312

So it looks like it was probably fixed in 2015.

#5261758 [c++ | asm x64] I think I call a function in the wrong way

Posted by Rattrap on 12 November 2015 - 09:49 AM

Somebody help - Please!
What's the proper way to call a 'void Func (void)' function in x64 assembly??


Have you tried using the disassembler and debugger to see what a call look like?



Drop a break point on a function call.  Run the program.  After debugger stops at the break point, Go to the Windows menu and choose Disassembly (or ctrl + alt +d).

#5255732 Problem with reading a binary file into a vector

Posted by Rattrap on 05 October 2015 - 06:09 PM

Additionally, you can move the vector declaration after you have determined the size of the file and pass the size through the constructor.

#5255731 Problem with reading a binary file into a vector

Posted by Rattrap on 05 October 2015 - 06:05 PM

Try using resize instead of reserve. Resize will allocate enough usable space, reserve is used to prevent reallocations when using push_back and emplace_back.

Try calling size after you called reserve to see how much space you had available.

#5255675 Cross platform execution branching?

Posted by Rattrap on 05 October 2015 - 10:40 AM

But I don't think #defines are globally recognized right?


No, but instead of defining those in a file, you could feed it "globally" through the compiler.  Most compilers will allow you defined values as part of the compile settings.