@@ -50,6 +50,17 @@ typedef pthread_t js_thread_t;
50
50
51
51
#define CMD_NAME "run-test262"
52
52
53
+ typedef struct {
54
+ js_mutex_t agent_mutex ;
55
+ js_cond_t agent_cond ;
56
+ /* list of Test262Agent.link */
57
+ struct list_head agent_list ;
58
+ js_mutex_t report_mutex ;
59
+ /* list of AgentReport.link */
60
+ struct list_head report_list ;
61
+ int async_done ;
62
+ } ThreadLocalStorage ;
63
+
53
64
typedef struct namelist_t {
54
65
char * * array ;
55
66
int count ;
@@ -97,7 +108,6 @@ int start_index, stop_index;
97
108
int test_excluded ;
98
109
_Atomic int test_count , test_failed , test_skipped ;
99
110
_Atomic int new_errors , changed_errors , fixed_errors ;
100
- _Thread_local int async_done ;
101
111
102
112
void warning (const char * , ...) __attribute__((__format__ (__printf__ , 1 , 2 )));
103
113
void fatal (int , const char * , ...) __attribute__((__format__ (__printf__ , 2 , 3 )));
@@ -443,6 +453,7 @@ static void enumerate_tests(const char *path)
443
453
static JSValue js_print_262 (JSContext * ctx , JSValue this_val ,
444
454
int argc , JSValue * argv )
445
455
{
456
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
446
457
int i ;
447
458
const char * str ;
448
459
@@ -451,9 +462,9 @@ static JSValue js_print_262(JSContext *ctx, JSValue this_val,
451
462
if (!str )
452
463
return JS_EXCEPTION ;
453
464
if (!strcmp (str , "Test262:AsyncTestComplete" )) {
454
- async_done ++ ;
465
+ tls -> async_done ++ ;
455
466
} else if (strstart (str , "Test262:AsyncTestFailure" , NULL )) {
456
- async_done = 2 ; /* force an error */
467
+ tls -> async_done = 2 ; /* force an error */
457
468
}
458
469
if (outfile ) {
459
470
if (i != 0 )
@@ -552,28 +563,16 @@ static long cpu_count(void)
552
563
#endif
553
564
}
554
565
555
- typedef struct {
556
- js_mutex_t agent_mutex ;
557
- js_cond_t agent_cond ;
558
- /* list of Test262Agent.link */
559
- struct list_head agent_list ;
560
- js_mutex_t report_mutex ;
561
- /* list of AgentReport.link */
562
- struct list_head report_list ;
563
- } ThreadLocalStorage ;
564
-
565
566
static void init_thread_local_storage (ThreadLocalStorage * p )
566
567
{
567
568
js_mutex_init (& p -> agent_mutex );
568
569
js_cond_init (& p -> agent_cond );
569
570
init_list_head (& p -> agent_list );
570
571
js_mutex_init (& p -> report_mutex );
571
572
init_list_head (& p -> report_list );
573
+ p -> async_done = 0 ;
572
574
}
573
575
574
- // points to parent thread's TLS in agent threads
575
- static _Thread_local ThreadLocalStorage * tls ;
576
-
577
576
typedef struct {
578
577
struct list_head link ;
579
578
js_thread_t tid ;
@@ -597,17 +596,20 @@ static void add_helpers(JSContext *ctx);
597
596
598
597
static void * agent_start (void * arg )
599
598
{
600
- Test262Agent * agent = arg ;
599
+ ThreadLocalStorage * tls ;
600
+ Test262Agent * agent ;
601
601
JSRuntime * rt ;
602
602
JSContext * ctx ;
603
603
JSValue ret_val ;
604
604
int ret ;
605
605
606
+ agent = arg ;
606
607
tls = agent -> tls ; // shares thread-local storage with parent thread
607
608
rt = JS_NewRuntime ();
608
609
if (rt == NULL ) {
609
610
fatal (1 , "JS_NewRuntime failure" );
610
611
}
612
+ JS_SetRuntimeOpaque (rt , tls );
611
613
ctx = JS_NewContext (rt );
612
614
if (ctx == NULL ) {
613
615
JS_FreeRuntime (rt );
@@ -674,6 +676,7 @@ static void *agent_start(void *arg)
674
676
static JSValue js_agent_start (JSContext * ctx , JSValue this_val ,
675
677
int argc , JSValue * argv )
676
678
{
679
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
677
680
const char * script ;
678
681
Test262Agent * agent ;
679
682
@@ -697,6 +700,7 @@ static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
697
700
698
701
static void js_agent_free (JSContext * ctx )
699
702
{
703
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
700
704
struct list_head * el , * el1 ;
701
705
Test262Agent * agent ;
702
706
@@ -719,7 +723,7 @@ static JSValue js_agent_leaving(JSContext *ctx, JSValue this_val,
719
723
return JS_UNDEFINED ;
720
724
}
721
725
722
- static BOOL is_broadcast_pending (void )
726
+ static BOOL is_broadcast_pending (ThreadLocalStorage * tls )
723
727
{
724
728
struct list_head * el ;
725
729
Test262Agent * agent ;
@@ -734,6 +738,7 @@ static BOOL is_broadcast_pending(void)
734
738
static JSValue js_agent_broadcast (JSContext * ctx , JSValue this_val ,
735
739
int argc , JSValue * argv )
736
740
{
741
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
737
742
JSValue sab = argv [0 ];
738
743
struct list_head * el ;
739
744
Test262Agent * agent ;
@@ -765,7 +770,7 @@ static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
765
770
}
766
771
js_cond_broadcast (& tls -> agent_cond );
767
772
768
- while (is_broadcast_pending ()) {
773
+ while (is_broadcast_pending (tls )) {
769
774
js_cond_wait (& tls -> agent_cond , & tls -> agent_mutex );
770
775
}
771
776
js_mutex_unlock (& tls -> agent_mutex );
@@ -819,6 +824,7 @@ static JSValue js_agent_monotonicNow(JSContext *ctx, JSValue this_val,
819
824
static JSValue js_agent_getReport (JSContext * ctx , JSValue this_val ,
820
825
int argc , JSValue * argv )
821
826
{
827
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
822
828
AgentReport * rep ;
823
829
JSValue ret ;
824
830
@@ -843,6 +849,7 @@ static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
843
849
static JSValue js_agent_report (JSContext * ctx , JSValue this_val ,
844
850
int argc , JSValue * argv )
845
851
{
852
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
846
853
const char * str ;
847
854
AgentReport * rep ;
848
855
@@ -1338,6 +1345,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
1338
1345
const char * error_type , int eval_flags , int is_async ,
1339
1346
int * msec )
1340
1347
{
1348
+ ThreadLocalStorage * tls = JS_GetRuntimeOpaque (JS_GetRuntime (ctx ));
1341
1349
JSValue res_val , exception_val ;
1342
1350
int ret , error_line , pos , pos_line ;
1343
1351
BOOL is_error , has_error_line , ret_promise ;
@@ -1352,7 +1360,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
1352
1360
1353
1361
/* a module evaluation returns a promise */
1354
1362
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE ) != 0 );
1355
- async_done = 0 ; /* counter of "Test262:AsyncTestComplete" messages */
1363
+ tls -> async_done = 0 ; /* counter of "Test262:AsyncTestComplete" messages */
1356
1364
1357
1365
start = get_clock_ms ();
1358
1366
res_val = JS_Eval (ctx , buf , buf_len , filename , eval_flags );
@@ -1373,7 +1381,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
1373
1381
} else if (ret == 0 ) {
1374
1382
if (is_async ) {
1375
1383
/* test if the test called $DONE() once */
1376
- if (async_done != 1 ) {
1384
+ if (tls -> async_done != 1 ) {
1377
1385
res_val = JS_ThrowTypeError (ctx , "$DONE() not called" );
1378
1386
} else {
1379
1387
res_val = JS_UNDEFINED ;
@@ -1721,10 +1729,10 @@ JSContext *JS_NewCustomContext(JSRuntime *rt)
1721
1729
return ctx ;
1722
1730
}
1723
1731
1724
- int run_test_buf (const char * filename , char * harness , namelist_t * ip ,
1725
- char * buf , size_t buf_len , const char * error_type ,
1726
- int eval_flags , BOOL is_negative , BOOL is_async ,
1727
- BOOL can_block , int * msec )
1732
+ int run_test_buf (ThreadLocalStorage * tls , const char * filename , char * harness ,
1733
+ namelist_t * ip , char * buf , size_t buf_len ,
1734
+ const char * error_type , int eval_flags , BOOL is_negative ,
1735
+ BOOL is_async , BOOL can_block , int * msec )
1728
1736
{
1729
1737
JSRuntime * rt ;
1730
1738
JSContext * ctx ;
@@ -1734,6 +1742,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
1734
1742
if (rt == NULL ) {
1735
1743
fatal (1 , "JS_NewRuntime failure" );
1736
1744
}
1745
+ JS_SetRuntimeOpaque (rt , tls );
1737
1746
js_std_init_handlers (rt );
1738
1747
ctx = JS_NewCustomContext (rt );
1739
1748
if (ctx == NULL ) {
@@ -1782,7 +1791,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
1782
1791
return ret ;
1783
1792
}
1784
1793
1785
- int run_test (const char * filename , int * msec )
1794
+ int run_test (ThreadLocalStorage * tls , const char * filename , int * msec )
1786
1795
{
1787
1796
char harnessbuf [1024 ];
1788
1797
char * harness ;
@@ -1943,12 +1952,12 @@ int run_test(const char *filename, int *msec)
1943
1952
}
1944
1953
ret = 0 ;
1945
1954
if (use_nostrict ) {
1946
- ret = run_test_buf (filename , harness , ip , buf , buf_len ,
1955
+ ret = run_test_buf (tls , filename , harness , ip , buf , buf_len ,
1947
1956
error_type , eval_flags , is_negative , is_async ,
1948
1957
can_block , msec );
1949
1958
}
1950
1959
if (use_strict ) {
1951
- ret |= run_test_buf (filename , harness , ip , buf , buf_len ,
1960
+ ret |= run_test_buf (tls , filename , harness , ip , buf , buf_len ,
1952
1961
error_type , eval_flags | JS_EVAL_FLAG_STRICT ,
1953
1962
is_negative , is_async , can_block , msec );
1954
1963
}
@@ -1961,7 +1970,8 @@ int run_test(const char *filename, int *msec)
1961
1970
}
1962
1971
1963
1972
/* run a test when called by test262-harness+eshost */
1964
- int run_test262_harness_test (const char * filename , BOOL is_module )
1973
+ int run_test262_harness_test (ThreadLocalStorage * tls , const char * filename ,
1974
+ BOOL is_module )
1965
1975
{
1966
1976
JSRuntime * rt ;
1967
1977
JSContext * ctx ;
@@ -1977,6 +1987,7 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
1977
1987
if (rt == NULL ) {
1978
1988
fatal (1 , "JS_NewRuntime failure" );
1979
1989
}
1990
+ JS_SetRuntimeOpaque (rt , tls );
1980
1991
ctx = JS_NewContext (rt );
1981
1992
if (ctx == NULL ) {
1982
1993
JS_FreeRuntime (rt );
@@ -2072,18 +2083,18 @@ int include_exclude_or_skip(int i) // naming is hard...
2072
2083
2073
2084
void * run_test_dir_list (void * arg )
2074
2085
{
2086
+ ThreadLocalStorage tls_s , * tls = & tls_s ;
2075
2087
const char * p ;
2076
2088
int i , msec ;
2077
2089
2078
- tls = & (ThreadLocalStorage ){};
2079
2090
init_thread_local_storage (tls );
2080
2091
2081
2092
for (i = (uintptr_t )arg ; i < test_list .count ; i += nthreads ) {
2082
2093
if (INCLUDE != include_exclude_or_skip (i ))
2083
2094
continue ;
2084
2095
p = test_list .array [i ];
2085
2096
msec = 0 ;
2086
- run_test (p , & msec );
2097
+ run_test (tls , p , & msec );
2087
2098
if (verbose > 1 || (slow_test_threshold && msec >= slow_test_threshold ))
2088
2099
fprintf (stderr , "%s (%d ms)\n" , p , msec );
2089
2100
}
@@ -2124,6 +2135,7 @@ char *get_opt_arg(const char *option, char *arg)
2124
2135
2125
2136
int main (int argc , char * * argv )
2126
2137
{
2138
+ ThreadLocalStorage tls_s , * tls = & tls_s ;
2127
2139
int i , optind ;
2128
2140
BOOL is_dir_list ;
2129
2141
BOOL only_check_errors = FALSE;
@@ -2134,7 +2146,6 @@ int main(int argc, char **argv)
2134
2146
2135
2147
js_std_set_worker_new_context_func (JS_NewCustomContext );
2136
2148
2137
- tls = & (ThreadLocalStorage ){};
2138
2149
init_thread_local_storage (tls );
2139
2150
js_mutex_init (& stats_mutex );
2140
2151
@@ -2209,7 +2220,7 @@ int main(int argc, char **argv)
2209
2220
help ();
2210
2221
2211
2222
if (is_test262_harness ) {
2212
- return run_test262_harness_test (argv [optind ], is_module );
2223
+ return run_test262_harness_test (tls , argv [optind ], is_module );
2213
2224
}
2214
2225
2215
2226
nthreads = max_int (nthreads , 1 );
@@ -2276,7 +2287,7 @@ int main(int argc, char **argv)
2276
2287
} else {
2277
2288
while (optind < argc ) {
2278
2289
int msec = 0 ;
2279
- run_test (argv [optind ++ ], & msec );
2290
+ run_test (tls , argv [optind ++ ], & msec );
2280
2291
}
2281
2292
}
2282
2293
0 commit comments