Skip to content

Commit 4bb8593

Browse files
authored
Merge pull request #457 from qwe661234/Add_bg_thread
jit: Introduce background compilation
2 parents 892bc37 + 51ce53b commit 4bb8593

File tree

5 files changed

+76
-9
lines changed

5 files changed

+76
-9
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ jobs:
7575
- name: undefined behavior test
7676
run: |
7777
make clean && make ENABLE_UBSAN=1 check -j$(nproc)
78-
make ENABLE_JIT=1 clean clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check -j$(nproc)
78+
make ENABLE_JIT=1 clean && make ENABLE_JIT=1 ENABLE_UBSAN=1 check -j$(nproc)
7979
8080
host-arm64:
8181
needs: [detect-code-related-file-changes]
@@ -134,6 +134,9 @@ jobs:
134134
run: |
135135
sudo apt-get update -q -y
136136
sudo apt-get install -q -y clang clang-tools libsdl2-dev libsdl2-mixer-dev
137+
wget https://apt.llvm.org/llvm.sh
138+
chmod +x ./llvm.sh
139+
sudo ./llvm.sh 17
137140
shell: bash
138141
- name: run scan-build without JIT
139142
run: make distclean && scan-build -v -o ~/scan-build --status-bugs --use-cc=clang --force-analyze-debug-code --show-description -analyzer-config stable-report-filename=true -enable-checker valist,nullability make ENABLE_EXT_F=0 ENABLE_SDL=0 ENABLE_JIT=0

src/emulate.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,9 @@ static block_t *block_alloc(riscv_t *rv)
308308
block->has_loops = false;
309309
block->n_invoke = 0;
310310
INIT_LIST_HEAD(&block->list);
311+
#if RV32_HAS(T2C)
312+
block->compiled = false;
313+
#endif
311314
#endif
312315
return block;
313316
}
@@ -993,13 +996,14 @@ void rv_step(void *arg)
993996
((exec_t2c_func_t) block->func)(rv);
994997
prev = NULL;
995998
continue;
996-
} /* check if the execution path is strong hotspot */
997-
if (block->n_invoke >= THRESHOLD) {
998-
t2c_compile(block,
999-
(uint64_t) ((memory_t *) PRIV(rv)->mem)->mem_base);
1000-
((exec_t2c_func_t) block->func)(rv);
1001-
prev = NULL;
1002-
continue;
999+
} /* check if invoking times of t1 generated code exceed threshold */
1000+
else if (!block->compiled && block->n_invoke >= THRESHOLD) {
1001+
block->compiled = true;
1002+
queue_entry_t *entry = malloc(sizeof(queue_entry_t));
1003+
entry->block = block;
1004+
pthread_mutex_lock(&rv->wait_queue_lock);
1005+
list_add(&entry->list, &rv->wait_queue);
1006+
pthread_mutex_unlock(&rv->wait_queue_lock);
10031007
}
10041008
#endif
10051009
/* executed through the tier-1 JIT compiler */

src/feature.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,11 @@
5757
#define RV32_FEATURE_T2C 0
5858
#endif
5959

60+
/* T2C depends on JIT configuration */
61+
#if !RV32_FEATURE_JIT
62+
#undef RV32_FEATURE_T2C
63+
#define RV32_FEATURE_T2C 0
64+
#endif
65+
6066
/* Feature test macro */
6167
#define RV32_HAS(x) RV32_FEATURE_##x

src/riscv.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include "riscv_private.h"
2929
#include "utils.h"
3030
#if RV32_HAS(JIT)
31+
#if RV32_HAS(T2C)
32+
#include <pthread.h>
33+
#endif
3134
#include "cache.h"
3235
#include "jit.h"
3336
#define CODE_CACHE_SIZE (4 * 1024 * 1024)
@@ -184,6 +187,27 @@ IO_HANDLER_IMPL(byte, write_b, W)
184187
#undef R
185188
#undef W
186189

190+
#if RV32_HAS(T2C)
191+
static pthread_t t2c_thread;
192+
static void *t2c_runloop(void *arg)
193+
{
194+
riscv_t *rv = (riscv_t *) arg;
195+
while (rv->quit) {
196+
if (!list_empty(&rv->wait_queue)) {
197+
queue_entry_t *entry =
198+
list_last_entry(&rv->wait_queue, queue_entry_t, list);
199+
pthread_mutex_lock(&rv->wait_queue_lock);
200+
list_del_init(&entry->list);
201+
pthread_mutex_unlock(&rv->wait_queue_lock);
202+
t2c_compile(entry->block,
203+
(uint64_t) ((memory_t *) PRIV(rv)->mem)->mem_base);
204+
free(entry);
205+
}
206+
}
207+
return NULL;
208+
}
209+
#endif
210+
187211
riscv_t *rv_create(riscv_user_t rv_attr)
188212
{
189213
assert(rv_attr);
@@ -269,6 +293,14 @@ riscv_t *rv_create(riscv_user_t rv_attr)
269293
rv->jit_state = jit_state_init(CODE_CACHE_SIZE);
270294
rv->block_cache = cache_create(BLOCK_MAP_CAPACITY_BITS);
271295
assert(rv->block_cache);
296+
#if RV32_HAS(T2C)
297+
rv->quit = false;
298+
/* prepare wait queue. */
299+
pthread_mutex_init(&rv->wait_queue_lock, NULL);
300+
INIT_LIST_HEAD(&rv->wait_queue);
301+
/* activate the background compilation thread. */
302+
pthread_create(&t2c_thread, NULL, t2c_runloop, rv);
303+
#endif
272304
#endif
273305

274306
return rv;
@@ -353,6 +385,11 @@ void rv_delete(riscv_t *rv)
353385
memory_delete(attr->mem);
354386
block_map_destroy(rv);
355387
#else
388+
#if RV32_HAS(T2C)
389+
rv->quit = true;
390+
pthread_join(t2c_thread, NULL);
391+
pthread_mutex_destroy(&rv->wait_queue_lock);
392+
#endif
356393
mpool_destroy(rv->chain_entry_mp);
357394
jit_state_exit(rv->jit_state);
358395
cache_free(rv->block_cache);

src/riscv_private.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
#include "riscv.h"
1515
#include "utils.h"
1616
#if RV32_HAS(JIT)
17+
#if RV32_HAS(T2C)
18+
#include <pthread.h>
19+
#endif
1720
#include "cache.h"
1821
#endif
1922

@@ -70,7 +73,10 @@ typedef struct block {
7073
bool
7174
translatable; /**< Determine the block has RV32AF insturctions or not */
7275
bool has_loops; /**< Determine the block has loop or not */
73-
uint32_t offset; /**< The machine code offset in T1 code cache */
76+
#if RV32_HAS(T2C)
77+
bool compiled; /**< The T2C request is enqueued or not */
78+
#endif
79+
uint32_t offset; /**< The machine code offset in T1 code cache */
7480
uint32_t n_invoke; /**< The invoking times of T1 machine code */
7581
void *func; /**< The function pointer of T2 machine code */
7682
struct list_head list;
@@ -82,6 +88,12 @@ typedef struct {
8288
block_t *block;
8389
struct list_head list;
8490
} chain_entry_t;
91+
#if RV32_HAS(T2C)
92+
typedef struct {
93+
block_t *block;
94+
struct list_head list;
95+
} queue_entry_t;
96+
#endif
8597
#endif
8698

8799
typedef struct {
@@ -134,6 +146,11 @@ struct riscv_internal {
134146
#else
135147
struct cache *block_cache;
136148
struct mpool *chain_entry_mp;
149+
#if RV32_HAS(T2C)
150+
struct list_head wait_queue;
151+
pthread_mutex_t wait_queue_lock;
152+
volatile bool quit; /**< Determine the main thread is terminated or not */
153+
#endif
137154
#endif
138155
struct mpool *block_mp, *block_ir_mp;
139156

0 commit comments

Comments
 (0)