// Typically we use the same global thread pool for all RAR modules.
static ThreadPool *GlobalPool=NULL;
static uint GlobalPoolUseCount=0;

static inline bool CriticalSectionCreate(CRITSECT_HANDLE *CritSection)
{
#ifdef _WIN_ALL
  InitializeCriticalSection(CritSection);
  return true;
#elif defined(_UNIX)
  return pthread_mutex_init(CritSection,NULL)==0;
#endif
}


static inline void CriticalSectionDelete(CRITSECT_HANDLE *CritSection)
{
#ifdef _WIN_ALL
  DeleteCriticalSection(CritSection);
#elif defined(_UNIX)
  pthread_mutex_destroy(CritSection);
#endif
}


static inline void CriticalSectionStart(CRITSECT_HANDLE *CritSection)
{
#ifdef _WIN_ALL
  EnterCriticalSection(CritSection);
#elif defined(_UNIX)
  pthread_mutex_lock(CritSection);
#endif
}


static inline void CriticalSectionEnd(CRITSECT_HANDLE *CritSection)
{
#ifdef _WIN_ALL
  LeaveCriticalSection(CritSection);
#elif defined(_UNIX)
  pthread_mutex_unlock(CritSection);
#endif
}


struct GlobalPoolCreateSync
{
  CRITSECT_HANDLE CritSection;
  GlobalPoolCreateSync()  { CriticalSectionCreate(&CritSection); }
  ~GlobalPoolCreateSync() { CriticalSectionDelete(&CritSection); }
};

static GlobalPoolCreateSync& GetPoolCreateSync() {
  static GlobalPoolCreateSync PoolCreateSync;
  return PoolCreateSync;
}


ThreadPool* CreateThreadPool()
{
  CriticalSectionStart(&(GetPoolCreateSync().CritSection));

  if (GlobalPoolUseCount++ == 0)
    GlobalPool=new ThreadPool(MaxPoolThreads);

  // We use a simple thread pool, which does not allow to add tasks from
  // different functions and threads in the same time. It is ok for RAR,
  // but UnRAR.dll can be used in multithreaded environment. So if one of
  // threads requests a copy of global pool and another copy is already
  // in use, we create and return a new pool instead of existing global.
  if (GlobalPoolUseCount > 1)
  {
    ThreadPool *Pool = new ThreadPool(MaxPoolThreads);
    CriticalSectionEnd(&(GetPoolCreateSync().CritSection));
    return Pool;
  }

  CriticalSectionEnd(&(GetPoolCreateSync().CritSection));
  return GlobalPool;
}


void DestroyThreadPool(ThreadPool *Pool)
{
  if (Pool!=NULL)
  {
    CriticalSectionStart(&(GetPoolCreateSync().CritSection));

    if (Pool==GlobalPool && GlobalPoolUseCount > 0 && --GlobalPoolUseCount == 0)
      delete GlobalPool;

    // To correctly work in multithreaded environment UnRAR.dll creates
    // new pools if global pool is already in use. We delete such pools here.
    if (Pool!=GlobalPool)
      delete Pool;

    CriticalSectionEnd(&(GetPoolCreateSync().CritSection));
  }
}


static THREAD_HANDLE ThreadCreate(NATIVE_THREAD_PTR Proc,void *Data)
{
#ifdef _UNIX
/*
  pthread_attr_t attr;
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
*/
  pthread_t pt;
  int Code=pthread_create(&pt,NULL/*&attr*/,Proc,Data);
  if (Code!=0)
  {
    wchar Msg[100];
    swprintf(Msg,ASIZE(Msg),L"\npthread_create failed, code %d\n",Code);
    ErrHandler.GeneralErrMsg(Msg);
    ErrHandler.SysErrMsg();
    ErrHandler.Exit(RARX_FATAL);
  }
  return pt;
#else
  DWORD ThreadId;
  HANDLE hThread=CreateThread(NULL,0x10000,Proc,Data,0,&ThreadId);
  if (hThread==NULL)
  {
    ErrHandler.GeneralErrMsg(L"CreateThread failed");
    ErrHandler.SysErrMsg();
    ErrHandler.Exit(RARX_FATAL);
  }
  return hThread;
#endif
}


static void ThreadClose(THREAD_HANDLE hThread)
{
#ifdef _UNIX
  pthread_join(hThread,NULL);
#else
  CloseHandle(hThread);
#endif
}


#ifdef _WIN_ALL
static void CWaitForSingleObject(HANDLE hHandle)
{
  DWORD rc=WaitForSingleObject(hHandle,INFINITE);
  if (rc==WAIT_FAILED)
  {
    ErrHandler.GeneralErrMsg(L"\nWaitForMultipleObjects error %d, GetLastError %d",rc,GetLastError());
    ErrHandler.Exit(RARX_FATAL);
  }
}
#endif


#ifdef _UNIX
static void cpthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
  int rc=pthread_cond_wait(cond,mutex);
  if (rc!=0)
  {
    ErrHandler.GeneralErrMsg(L"\npthread_cond_wait error %d",rc);
    ErrHandler.Exit(RARX_FATAL);
  }
}
#endif


uint GetNumberOfCPU()
{
#ifndef RAR_SMP
  return 1;
#else
#ifdef _UNIX
#ifdef _SC_NPROCESSORS_ONLN
  uint Count=(uint)sysconf(_SC_NPROCESSORS_ONLN);
  return Count<1 ? 1:Count;
#elif defined(_APPLE)
  uint Count;
  size_t Size=sizeof(Count);
  return sysctlbyname("hw.ncpu",&Count,&Size,NULL,0)==0 ? Count:1;
#endif
#else // !_UNIX
  DWORD_PTR ProcessMask;
  DWORD_PTR SystemMask;

  if (!GetProcessAffinityMask(GetCurrentProcess(),&ProcessMask,&SystemMask))
    return 1;
  uint Count=0;
  for (DWORD_PTR Mask=1;Mask!=0;Mask<<=1)
    if ((ProcessMask & Mask)!=0)
      Count++;
  return Count<1 ? 1:Count;
#endif

#endif // RAR_SMP
}


uint GetNumberOfThreads()
{
  uint NumCPU=GetNumberOfCPU();
  if (NumCPU<1)
    return 1;
  if (NumCPU>MaxPoolThreads)
    return MaxPoolThreads;
  return NumCPU;
}

