Skip to content

Commit

Permalink
Use a thread-safe temporary arena on every platform.
Browse files Browse the repository at this point in the history
This commit continues the work started in commits 521473e and
e84fd46 that parallelizes certain geometric operations. This commit
cleans up the temporary arena implementations and makes them
thread-safe.

Also, in commit 521473e, a call to FreeAllTemporary() was added
during initialization to create the heap on Windows. This is now
not necessary as the heap is created transparently on the first call
to AllocTemporary().
  • Loading branch information
whitequark committed May 22, 2020
1 parent 060a328 commit 7f1f9bb
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 100 deletions.
8 changes: 0 additions & 8 deletions src/CMakeLists.txt
Expand Up @@ -26,14 +26,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in

# platform utilities

if(WIN32)
set(util_SOURCES
platform/utilwin.cpp)
else()
set(util_SOURCES
platform/utilunix.cpp)
endif()

if(APPLE)
set(util_LIBRARIES
${APPKIT_LIBRARY})
Expand Down
3 changes: 0 additions & 3 deletions src/lib.cpp
Expand Up @@ -67,9 +67,6 @@ void Slvs_MakeQuaternion(double ux, double uy, double uz,

void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg)
{
// Create the temporary heap, if this is the first time we're solving.
FreeAllTemporary();

int i;
for(i = 0; i < ssys->params; i++) {
Slvs_Param *sp = &(ssys->param[i]);
Expand Down
64 changes: 61 additions & 3 deletions src/platform/platform.cpp
Expand Up @@ -18,6 +18,7 @@
#else
# include <unistd.h>
# include <sys/stat.h>
# include <mutex>
#endif

namespace SolveSpace {
Expand Down Expand Up @@ -605,9 +606,6 @@ std::vector<std::string> InitCli(int argc, char **argv) {
}
#endif

// Create the heap that we use to store Exprs and other temp stuff.
FreeAllTemporary();

// Extract the command-line arguments; the ones from main() are ignored,
// since they are in the OEM encoding.
int argcW;
Expand Down Expand Up @@ -681,5 +679,65 @@ void DebugPrint(const char *fmt, ...) {

#endif

//-----------------------------------------------------------------------------
// Temporary arena, on Windows.
//-----------------------------------------------------------------------------

#if defined(WIN32)

static HANDLE TempArena = NULL;

void *AllocTemporary(size_t size)
{
if(!TempArena)
TempArena = HeapCreate(0, 0, 0);
void *ptr = HeapAlloc(TempArena, HEAP_ZERO_MEMORY, size);
ssassert(ptr != NULL, "out of memory");
return ptr;
}

void FreeAllTemporary()
{
HeapDestroy(TempArena);
TempArena = NULL;
}

#endif

//-----------------------------------------------------------------------------
// Temporary arena, on Linux.
//-----------------------------------------------------------------------------

#if !defined(WIN32)

struct ArenaChunk {
ArenaChunk *next;
};

static std::mutex TempArenaMutex;
static ArenaChunk *TempArena = NULL;

void *AllocTemporary(size_t size)
{
ArenaChunk *chunk = (ArenaChunk *)calloc(1, sizeof(ArenaChunk) + size);
ssassert(chunk != NULL, "out of memory");
std::lock_guard<std::mutex> guard(TempArenaMutex);
chunk->next = TempArena;
TempArena = chunk;
return (void *)(chunk + 1);
}

void FreeAllTemporary()
{
std::lock_guard<std::mutex> guard(TempArenaMutex);
while(TempArena) {
ArenaChunk *chunk = TempArena;
TempArena = TempArena->next;
free(chunk);
}
}

#endif

}
}
4 changes: 4 additions & 0 deletions src/platform/platform.h
Expand Up @@ -70,6 +70,10 @@ std::vector<std::string> InitCli(int argc, char **argv);
// Debug print function.
void DebugPrint(const char *fmt, ...);

// Temporary arena functions.
void *AllocTemporary(size_t size);
void FreeAllTemporary();

}

#endif
49 changes: 0 additions & 49 deletions src/platform/utilunix.cpp

This file was deleted.

33 changes: 0 additions & 33 deletions src/platform/utilwin.cpp

This file was deleted.

7 changes: 3 additions & 4 deletions src/solvespace.h
Expand Up @@ -132,16 +132,15 @@ inline double Random(double vmax) {
#include "platform/gui.h"
#include "resource.h"

using Platform::AllocTemporary;
using Platform::FreeAllTemporary;

class Expr;
class ExprVector;
class ExprQuaternion;
class RgbaColor;
enum class Command : uint32_t;

// Temporary heap, defined in the platform-specific code.
void *AllocTemporary(size_t n);
void FreeAllTemporary();

enum class Unit : uint32_t {
MM = 0,
INCHES,
Expand Down

0 comments on commit 7f1f9bb

Please sign in to comment.