1
0
forked from 0ad/0ad

pthread -> std::thread (3/7) - Replace pthread in other engine files

MapGenerator, TextureConverter, and some other files used pthread.

Differential Revision: https://code.wildfiregames.com/D1917
This was SVN commit r22649.
This commit is contained in:
wraitii 2019-08-12 08:16:28 +00:00
parent 8ef8a9de89
commit 107d3d461f
8 changed files with 64 additions and 80 deletions

View File

@ -66,7 +66,7 @@ CMapGeneratorWorker::CMapGeneratorWorker()
CMapGeneratorWorker::~CMapGeneratorWorker()
{
// Wait for thread to end
pthread_join(m_WorkerThread, NULL);
m_WorkerThread.join();
}
void CMapGeneratorWorker::Initialize(const VfsPath& scriptFile, const std::string& settings)
@ -79,17 +79,14 @@ void CMapGeneratorWorker::Initialize(const VfsPath& scriptFile, const std::strin
m_Settings = settings;
// Launch the worker thread
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0);
m_WorkerThread = std::thread(RunThread, this);
}
void* CMapGeneratorWorker::RunThread(void *data)
void* CMapGeneratorWorker::RunThread(CMapGeneratorWorker* self)
{
debug_SetThreadName("MapGenerator");
g_Profiler2.RegisterCurrentThread("MapGenerator");
CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(data);
shared_ptr<ScriptRuntime> mapgenRuntime = ScriptInterface::CreateRuntime(g_ScriptRuntime, RMS_RUNTIME_SIZE);
// Enable the script to be aborted

View File

@ -28,6 +28,7 @@
#include <mutex>
#include <set>
#include <string>
#include <thread>
class CMapGeneratorWorker;
@ -179,7 +180,7 @@ private:
/**
* Perform map generation in an independent thread.
*/
static void* RunThread(void* data);
static void* RunThread(CMapGeneratorWorker* self);
/**
* Perform the map generation.
@ -229,7 +230,7 @@ private:
/**
* Holds the mapgeneration thread identifier.
*/
pthread_t m_WorkerThread;
std::thread m_WorkerThread;
/**
* Avoids thread synchronization issues.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015 Wildfire Games.
/* Copyright (C) 2019 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -292,11 +292,7 @@ CTextureConverter::CTextureConverter(PIVFS vfs, bool highQuality) :
m_WorkerSem = SDL_CreateSemaphore(0);
ENSURE(m_WorkerSem);
ret = pthread_mutex_init(&m_WorkerMutex, NULL);
ENSURE(ret == 0);
ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0);
m_WorkerThread = std::thread(RunThread, this);
// Maybe we should share some centralised pool of worker threads?
// For now we'll just stick with a single thread for this specific use.
@ -305,19 +301,19 @@ CTextureConverter::CTextureConverter(PIVFS vfs, bool highQuality) :
CTextureConverter::~CTextureConverter()
{
// Tell the thread to shut down
pthread_mutex_lock(&m_WorkerMutex);
m_Shutdown = true;
pthread_mutex_unlock(&m_WorkerMutex);
{
std::lock_guard<std::mutex> lock(m_WorkerMutex);
m_Shutdown = true;
}
// Wake it up so it sees the notification
SDL_SemPost(m_WorkerSem);
// Wait for it to shut down cleanly
pthread_join(m_WorkerThread, NULL);
m_WorkerThread.join();
// Clean up resources
SDL_DestroySemaphore(m_WorkerSem);
pthread_mutex_destroy(&m_WorkerMutex);
}
bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath& src, const VfsPath& dest, const Settings& settings)
@ -463,9 +459,10 @@ bool CTextureConverter::ConvertTexture(const CTexturePtr& texture, const VfsPath
delete[] rgba;
}
pthread_mutex_lock(&m_WorkerMutex);
m_RequestQueue.push_back(request);
pthread_mutex_unlock(&m_WorkerMutex);
{
std::lock_guard<std::mutex> lock(m_WorkerMutex);
m_RequestQueue.push_back(request);
}
// Wake up the worker thread
SDL_SemPost(m_WorkerSem);
@ -484,13 +481,14 @@ bool CTextureConverter::Poll(CTexturePtr& texture, VfsPath& dest, bool& ok)
shared_ptr<ConversionResult> result;
// Grab the first result (if any)
pthread_mutex_lock(&m_WorkerMutex);
if (!m_ResultQueue.empty())
{
result = m_ResultQueue.front();
m_ResultQueue.pop_front();
std::lock_guard<std::mutex> lock(m_WorkerMutex);
if (!m_ResultQueue.empty())
{
result = m_ResultQueue.front();
m_ResultQueue.pop_front();
}
}
pthread_mutex_unlock(&m_WorkerMutex);
if (!result)
{
@ -530,20 +528,17 @@ bool CTextureConverter::Poll(CTexturePtr& texture, VfsPath& dest, bool& ok)
bool CTextureConverter::IsBusy()
{
pthread_mutex_lock(&m_WorkerMutex);
std::lock_guard<std::mutex> lock(m_WorkerMutex);
bool busy = !m_RequestQueue.empty();
pthread_mutex_unlock(&m_WorkerMutex);
return busy;
}
void* CTextureConverter::RunThread(void* data)
void CTextureConverter::RunThread(CTextureConverter* textureConverter)
{
debug_SetThreadName("TextureConverter");
g_Profiler2.RegisterCurrentThread("texconv");
CTextureConverter* textureConverter = static_cast<CTextureConverter*>(data);
#if CONFIG2_NVTT
// Wait until the main thread wakes us up
@ -552,17 +547,17 @@ void* CTextureConverter::RunThread(void* data)
g_Profiler2.RecordSyncMarker();
PROFILE2_EVENT("wakeup");
pthread_mutex_lock(&textureConverter->m_WorkerMutex);
if (textureConverter->m_Shutdown)
shared_ptr<ConversionRequest> request;
{
pthread_mutex_unlock(&textureConverter->m_WorkerMutex);
break;
std::lock_guard<std::mutex> lock(textureConverter->m_WorkerMutex);
if (textureConverter->m_Shutdown)
break;
// If we weren't woken up for shutdown, we must have been woken up for
// a new request, so grab it from the queue
request = textureConverter->m_RequestQueue.front();
textureConverter->m_RequestQueue.pop_front();
}
// If we weren't woken up for shutdown, we must have been woken up for
// a new request, so grab it from the queue
shared_ptr<ConversionRequest> request = textureConverter->m_RequestQueue.front();
textureConverter->m_RequestQueue.pop_front();
pthread_mutex_unlock(&textureConverter->m_WorkerMutex);
// Set up the result object
shared_ptr<ConversionResult> result(new ConversionResult());
@ -595,12 +590,9 @@ void* CTextureConverter::RunThread(void* data)
result->output.buffer[80] &= ~0x40; // DDPF_RGB in DDS_PIXELFORMAT.dwFlags
// Push the result onto the queue
pthread_mutex_lock(&textureConverter->m_WorkerMutex);
std::lock_guard<std::mutex> lock(textureConverter->m_WorkerMutex);
textureConverter->m_ResultQueue.push_back(result);
pthread_mutex_unlock(&textureConverter->m_WorkerMutex);
}
#endif
return NULL;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Wildfire Games.
/* Copyright (C) 2019 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -19,11 +19,12 @@
#define INCLUDED_TEXTURECONVERTER
#include "lib/file/vfs/vfs.h"
#include "lib/posix/posix_pthread.h"
#include "lib/external_libraries/libsdl.h"
#include "TextureManager.h"
#include <thread>
class MD5;
/**
@ -199,13 +200,13 @@ public:
bool IsBusy();
private:
static void* RunThread(void* data);
static void RunThread(CTextureConverter* data);
PIVFS m_VFS;
bool m_HighQuality;
pthread_t m_WorkerThread;
pthread_mutex_t m_WorkerMutex;
std::thread m_WorkerThread;
std::mutex m_WorkerMutex;
SDL_sem* m_WorkerSem;
struct ConversionRequest;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2010 Wildfire Games.
/* Copyright (C) 2019 Wildfire Games.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -82,16 +82,15 @@ void timer_LatchStartTime()
#endif
}
static pthread_mutex_t ensure_monotonic_mutex = PTHREAD_MUTEX_INITIALIZER;
static std::mutex ensure_monotonic_mutex;
// NB: does not guarantee strict monotonicity - callers must avoid
// dividing by the difference of two equal times.
static void EnsureMonotonic(double& newTime)
{
pthread_mutex_lock(&ensure_monotonic_mutex);
std::lock_guard<std::mutex> lock(ensure_monotonic_mutex);
static double maxTime;
maxTime = std::max(maxTime, newTime);
newTime = maxTime;
pthread_mutex_unlock(&ensure_monotonic_mutex);
}

View File

@ -30,11 +30,11 @@
#include "ps/ConfigDB.h"
#include "ps/Filesystem.h"
#include "ps/Profiler2.h"
#include "ps/ThreadUtil.h"
#include <fstream>
#include <mutex>
#include <string>
#include <thread>
#define DEBUG_UPLOADS 0
@ -143,8 +143,7 @@ public:
m_WorkerSem = SDL_CreateSemaphore(0);
ENSURE(m_WorkerSem);
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0);
m_WorkerThread = std::thread(RunThread, this);
}
~CUserReporterWorker()
@ -191,7 +190,7 @@ public:
// Wait for it to shut down cleanly
// TODO: should have a timeout in case of network hangs
pthread_join(m_WorkerThread, NULL);
m_WorkerThread.join();
return true;
}
@ -236,14 +235,12 @@ public:
}
private:
static void* RunThread(void* data)
static void RunThread(CUserReporterWorker* data)
{
debug_SetThreadName("CUserReportWorker");
g_Profiler2.RegisterCurrentThread("userreport");
static_cast<CUserReporterWorker*>(data)->Run();
return NULL;
data->Run();
}
void Run()
@ -489,7 +486,7 @@ private:
private:
// Thread-related members:
pthread_t m_WorkerThread;
std::thread m_WorkerThread;
std::mutex m_WorkerMutex;
SDL_sem* m_WorkerSem;

View File

@ -32,6 +32,8 @@
#include "ps/Profiler2.h"
#include "ps/XML/Xeromyces.h"
#include <thread>
ISoundManager* g_SoundManager = NULL;
#define SOURCE_NUM 64
@ -49,8 +51,7 @@ public:
m_DeadItems = new ItemsList;
m_Shutdown = false;
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this);
ENSURE(ret == 0);
m_WorkerThread = std::thread(RunThread, this);
}
~CSoundManagerWorker()
@ -76,7 +77,7 @@ public:
}
pthread_join(m_WorkerThread, NULL);
m_WorkerThread.join();
return true;
}
@ -103,14 +104,12 @@ public:
}
private:
static void* RunThread(void* data)
static void RunThread(CSoundManagerWorker* data)
{
debug_SetThreadName("CSoundManagerWorker");
g_Profiler2.RegisterCurrentThread("soundmanager");
static_cast<CSoundManagerWorker*>(data)->Run();
return NULL;
data->Run();
}
void Run()
@ -168,7 +167,7 @@ private:
private:
// Thread-related members:
pthread_t m_WorkerThread;
std::thread m_WorkerThread;
std::mutex m_WorkerMutex;
std::mutex m_DeadItemsMutex;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Wildfire Games.
/* Copyright (C) 2019 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -17,6 +17,8 @@
#include "precompiled.h"
#include <thread>
#include "GameLoop.h"
#include "MessagePasserImpl.h"
@ -37,6 +39,7 @@
#include "ps/DllLoader.h"
#include "ps/Filesystem.h"
#include "ps/Profile.h"
#include "ps/ThreadUtil.h"
#include "ps/GameSetup/Paths.h"
#include "renderer/Renderer.h"
@ -98,7 +101,7 @@ static void RendererIncrementalLoad()
while (more && timer_Time() - startTime < maxTime);
}
static void* RunEngine(void* data)
static void RunEngine(const CmdLineArgs& args)
{
debug_SetThreadName("engine_thread");
@ -107,8 +110,6 @@ static void* RunEngine(void* data)
g_Profiler2.RegisterCurrentThread("atlasmain");
const CmdLineArgs args = *reinterpret_cast<const CmdLineArgs*>(data);
MessagePasserImpl* msgPasser = (MessagePasserImpl*)AtlasMessage::g_MessagePasser;
// Register all the handlers for message which might be passed back
@ -267,8 +268,6 @@ static void* RunEngine(void* data)
SDL_Delay(0);
}
}
return NULL;
}
bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll)
@ -309,15 +308,14 @@ bool BeginAtlas(const CmdLineArgs& args, const DllLoader& dll)
Atlas_SetConfigDirectory(paths.Config().string().c_str());
// Run the engine loop in a new thread
pthread_t engineThread;
pthread_create(&engineThread, NULL, RunEngine, reinterpret_cast<void*>(const_cast<CmdLineArgs*>(&args)));
std::thread engineThread = std::thread(RunEngine, std::ref(args));
// Start Atlas UI on main thread
// (required for wxOSX/Cocoa compatibility - see http://trac.wildfiregames.com/ticket/500)
Atlas_StartWindow(L"ScenarioEditor");
// Wait for the engine to exit
pthread_join(engineThread, NULL);
engineThread.join();
// TODO: delete all remaining messages, to avoid memory leak warnings