2
0

StackHelper.cpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include "StackHelper.h"
  2. #include "BeefPerf.h"
  3. #include "ThreadPool.h"
  4. USING_NS_BF;
  5. // Debug code takes more stack space - allow more there
  6. #ifdef _DEBUG
  7. #define MAX_STACK_SIZE 32*1024*1024
  8. #else
  9. #define MAX_STACK_SIZE 16*1024*1024
  10. #endif
  11. //#define MAX_STACK_SIZE 1*1024*1024 // Testing
  12. static ThreadPool gThreadPool(8, MAX_STACK_SIZE);
  13. StackHelper::StackHelper()
  14. {
  15. }
  16. bool StackHelper::CanStackExpand(int wantBytes)
  17. {
  18. intptr stackBase = 0;
  19. int stackLimit = 0;
  20. BfpThreadResult threadResult;
  21. BfpThreadInfo_GetStackInfo(NULL, &stackBase, &stackLimit, BfpThreadInfoFlags_None, &threadResult);
  22. if (threadResult != BfpThreadResult_Ok)
  23. return true;
  24. //printf("StackInfo: %p %p %d\n", stackBase, &wantBytes, stackLimit);
  25. intptr expectedStackPtr = (intptr)(void*)&wantBytes - wantBytes;
  26. int resultSize = (int)(stackBase - expectedStackPtr);
  27. return resultSize <= stackLimit;
  28. }
  29. struct StackHelperExecuter
  30. {
  31. const std::function<void()>* mFunc;
  32. SyncEvent mDoneEvent;
  33. static void BFP_CALLTYPE Proc(void* threadParam)
  34. {
  35. auto _this = (StackHelperExecuter*)threadParam;
  36. (*_this->mFunc)();
  37. _this->mDoneEvent.Set();
  38. }
  39. void Wait()
  40. {
  41. mDoneEvent.WaitFor();
  42. }
  43. };
  44. bool StackHelper::Execute(const std::function<void()>& func)
  45. {
  46. // Only allow one threaded continuation
  47. if (gThreadPool.IsInJob())
  48. return false;
  49. StackHelperExecuter executer;
  50. executer.mFunc = &func;
  51. //printf("StackHelper executing!\n");
  52. gThreadPool.AddJob(StackHelperExecuter::Proc, (void*)&executer, 1);
  53. executer.Wait();
  54. return true;
  55. }