Skip to content

Commit

Permalink
Implement Thread Isolating
Browse files Browse the repository at this point in the history
Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
  • Loading branch information
ksh8281 authored and clover2123 committed Jul 15, 2021
1 parent f2e2aac commit 0cc277f
Show file tree
Hide file tree
Showing 31 changed files with 468 additions and 357 deletions.
47 changes: 28 additions & 19 deletions Allocator.cpp
Expand Up @@ -17,31 +17,36 @@
* USA
*/

#include "GCUtilInternal.h"
#include "Allocator.h"

#include <vector>
#include <algorithm>

GC_API void GC_CALL GC_set_on_collection_event(GC_on_collection_event_proc);

std::vector<std::pair<GC_on_event_proc, void*>> g_gcEventCallbacks;
std::vector<std::pair<GC_on_event_proc, void*>>& gcEventCallbacks()
{
static MAY_THREAD_LOCAL std::vector<std::pair<GC_on_event_proc, void*>> eventCallbacks;
return eventCallbacks;
}

GC_API void GC_CALL GC_add_event_callback(GC_on_event_proc fn, void* data)
{
g_gcEventCallbacks.push_back(std::make_pair(fn, data));
gcEventCallbacks().push_back(std::make_pair(fn, data));

GC_set_on_collection_event([](GC_EventType evtType) {
for (size_t i = 0; i < g_gcEventCallbacks.size(); i ++) {
g_gcEventCallbacks[i].first(evtType, g_gcEventCallbacks[i].second);
for (size_t i = 0; i < gcEventCallbacks().size(); i ++) {
gcEventCallbacks()[i].first(evtType, gcEventCallbacks()[i].second);
}
});
}

GC_API void GC_CALL GC_remove_event_callback(GC_on_event_proc fn, void* data)
{
auto iter = std::find(g_gcEventCallbacks.begin(), g_gcEventCallbacks.end(), std::make_pair(fn, data));
if (iter != g_gcEventCallbacks.end()) {
g_gcEventCallbacks.erase(iter);
auto iter = std::find(gcEventCallbacks().begin(), gcEventCallbacks().end(), std::make_pair(fn, data));
if (iter != gcEventCallbacks().end()) {
gcEventCallbacks().erase(iter);
}
}

Expand Down Expand Up @@ -71,27 +76,31 @@ struct HeapInfo {
// This structure holds information about the size of the
// allcoated memory area and a finalization user callback
// with its user defined data.
static std::map<void*, AllocInfo> addressTable;
std::map<void*, AllocInfo>& addressTable()
{
static MAY_THREAD_LOCAL std::map<void*, AllocInfo> table;
return table;
}

static HeapInfo heapInfo = { 0, 0, 0, 0, 0, 0, 0 };
static MAY_THREAD_LOCAL HeapInfo heapInfo = { 0, 0, 0, 0, 0, 0, 0 };

// The addressTable allocation should be in a separated function. This is
// important, because the noise (helper structiore allcoations) can be
// filtered out by the Freya tool of Valgrind.
void createAddressEntry(void* address, size_t size)
{
auto it = addressTable.find(address);
auto it = addressTable().find(address);
// The address should not exist.
assert(it == addressTable.end());
assert(it == addressTable().end());

addressTable[address] = { nullptr, nullptr, size };
addressTable()[address] = { nullptr, nullptr, size };
}

void unregisterGCAddress(void* address, void* data)
{
auto it = addressTable.find(address);
auto it = addressTable().find(address);
// The address should exist.
assert(it != addressTable.end());
assert(it != addressTable().end());

AllocInfo allocInfo = it->second;
// Execute the user defined callback.
Expand All @@ -101,7 +110,7 @@ void unregisterGCAddress(void* address, void* data)
heapInfo.allocated -= allocInfo.size;
heapInfo.free_count++;

addressTable.erase(it);
addressTable().erase(it);

#ifdef ESCARGOT_VALGRIND
VALGRIND_FREELIKE_BLOCK(address, 0);
Expand All @@ -118,9 +127,9 @@ void unregisterGCAddress(void* address, void* data)

void registerGCAddress(void* address, size_t siz)
{
auto it = addressTable.find(address);
auto it = addressTable().find(address);
// The address should not exist.
assert(it == addressTable.end());
assert(it == addressTable().end());

createAddressEntry(address, siz);

Expand Down Expand Up @@ -170,9 +179,9 @@ void GC_register_finalizer_no_order_hook(void* obj, GC_finalization_proc fn,
void* cd, GC_finalization_proc *ofn,
void** ocd)
{
auto it = addressTable.find(obj);
auto it = addressTable().find(obj);
// The address should exist.
assert(it != addressTable.end());
assert(it != addressTable().end());

(it->second).user_cb = fn;
(it->second).user_data = cd;
Expand Down
16 changes: 4 additions & 12 deletions CMakeLists.txt
Expand Up @@ -6,10 +6,6 @@ INCLUDE_DIRECTORIES(bdwgc/include)
FILE(GLOB GCUTIL_BDWGC_SRC bdwgc/*.c)
FILE(GLOB GCUTIL_SRC *.cpp)

#SET (GCUTIL_MODE "release" CACHE STRING "GCUTIL_MODE")
SET (GCUTIL_ENABLE_THREADING "0" CACHE STRING "GCUTIL_ENABLE_THREADING")
SET (GCUTIL_ENABLE_THREAD_LOCAL_ALLOC "0" CACHE STRING "GCUTIL_ENABLE_THREAD_LOCAL_ALLOC")

SET (GCUTIL_CFLAGS_INTERNAL -g3 -fdata-sections -ffunction-sections -DESCARGOT -Wno-unused-variable -fno-strict-aliasing -DGC_DLL=1 -fvisibility=hidden)
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DALL_INTERIOR_POINTERS=0 -DENABLE_DISCLAIM=1 -DGC_ATOMIC_UNCOLLECTABLE=1 -DGC_DONT_REGISTER_MAIN_STATIC_DATA=1 -DGC_ENABLE_SUSPEND_THREAD=1)
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DGC_NO_THREADS_DISCOVERY=1 -DGC_VERSION_MAJOR=8 -DGC_VERSION_MICRO=4 -DGC_VERSION_MINOR=0)
Expand All @@ -18,17 +14,13 @@ SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DHAVE_STRING_H=1 -DHAVE_S
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DIGNORE_DYNAMIC_LOADING=1 -DJAVA_FINALIZATION=1 -DMUNMAP_THRESHOLD=1 -DNO_EXECUTE_PERMISSION=1 -DSTDC_HEADERS=1 -DUSE_MMAP=1 -DUSE_MUNMAP=1)
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DHAVE_PTHREAD_GETATTR_NP=1 -DUSE_GET_STACKBASE_FOR_MAIN=1)

IF (${GCUTIL_ENABLE_THREADING} STREQUAL "1")
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DGC_BUILTIN_ATOMIC=1 -DGC_THREADS=1 -DPARALLEL_MARK=1 -D_REENTRANT=1 -DGC_ENABLE_INCREMENTAL=1)

IF (${GCUTIL_ENABLE_THREAD_LOCAL_ALLOC} STREQUAL "1")
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DTHREAD_LOCAL_ALLOC=1)
ENDIF()
IF (GCUTIL_ENABLE_THREADING)
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -D_REENTRANT=1 -DGC_THREAD_ISOLATE=1)
ENDIF()

IF (${GCUTIL_MODE} STREQUAL "debug")
IF (GCUTIL_MODE STREQUAL "debug")
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DKEEP_BACK_PTRS=1 -DSAVE_CALL_COUNT=8 -DDBG_HDRS_ALL=1 -DGC_DEBUG -O0)
ELSEIF (${GCUTIL_MODE} STREQUAL "release")
ELSE()
SET (GCUTIL_CFLAGS_INTERNAL ${GCUTIL_CFLAGS_INTERNAL} -DNO_DEBUGGING=1 -O2)
ENDIF()

Expand Down
36 changes: 36 additions & 0 deletions GCUtilInternal.h
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2021-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/

#ifndef __GCUtilInternal__
#define __GCUtilInternal__

#if defined(GC_THREAD_ISOLATE)

#if defined(_MSC_VER)
#define MAY_THREAD_LOCAL __declspec(thread)
#else
#define MAY_THREAD_LOCAL __thread
#endif

#else /* GC_THREAD_ISOLATE */

#define MAY_THREAD_LOCAL
#endif /* GC_THREAD_ISOLATE */

#endif
14 changes: 7 additions & 7 deletions bdwgc/allchblk.c
Expand Up @@ -19,9 +19,9 @@
#include <stdio.h>

#ifdef GC_USE_ENTIRE_HEAP
int GC_use_entire_heap = TRUE;
MAY_THREAD_LOCAL int GC_use_entire_heap = TRUE;
#else
int GC_use_entire_heap = FALSE;
MAY_THREAD_LOCAL int GC_use_entire_heap = FALSE;
#endif

/*
Expand Down Expand Up @@ -51,7 +51,7 @@
#ifndef GC_GCJ_SUPPORT
STATIC
#endif
struct hblk * GC_hblkfreelist[N_HBLK_FLS+1] = { 0 };
MAY_THREAD_LOCAL struct hblk * GC_hblkfreelist[N_HBLK_FLS+1] = { 0 };
/* List of completely empty heap blocks */
/* Linked through hb_next field of */
/* header structure associated with */
Expand All @@ -61,7 +61,7 @@
#ifndef GC_GCJ_SUPPORT
STATIC
#endif
word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
MAY_THREAD_LOCAL word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
/* Number of free bytes on each list. Remains visible to GCJ. */

/* Return the largest n such that the number of free bytes on lists */
Expand Down Expand Up @@ -393,7 +393,7 @@ STATIC void GC_add_to_fl(struct hblk *h, hdr *hhdr)
# define MUNMAP_THRESHOLD 6
# endif

GC_INNER int GC_unmap_threshold = MUNMAP_THRESHOLD;
GC_INNER MAY_THREAD_LOCAL int GC_unmap_threshold = MUNMAP_THRESHOLD;

/* Unmap blocks that haven't been recently touched. This is the only way */
/* way blocks are ever unmapped. */
Expand Down Expand Up @@ -670,7 +670,7 @@ GC_allochblk(size_t sz, int kind, unsigned flags/* IGNORE_OFF_PAGE or 0 */)
return result;
}

STATIC long GC_large_alloc_warn_suppressed = 0;
STATIC MAY_THREAD_LOCAL long GC_large_alloc_warn_suppressed = 0;
/* Number of warnings suppressed so far. */

/* The same, but with search restricted to nth free list. Flags is */
Expand Down Expand Up @@ -772,7 +772,7 @@ GC_allochblk_nth(size_t sz, int kind, unsigned flags, int n, int may_split)
&& size_needed == (signed_word)HBLKSIZE
&& IS_MAPPED(hhdr)) {
if (!GC_find_leak) {
static unsigned count = 0;
static MAY_THREAD_LOCAL unsigned count = 0;

/* The block is completely blacklisted. We need */
/* to drop some such blocks, since otherwise we spend */
Expand Down

0 comments on commit 0cc277f

Please sign in to comment.