diff --git a/build/make/targets/common_vm.xml b/build/make/targets/common_vm.xml
index fb53825..d2897b4 100644
--- a/build/make/targets/common_vm.xml
+++ b/build/make/targets/common_vm.xml
@@ -234,18 +234,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/make/targets/cunit.test.xml b/build/make/targets/cunit.test.xml
index 456a0a9..b1bcf7f 100644
--- a/build/make/targets/cunit.test.xml
+++ b/build/make/targets/cunit.test.xml
@@ -1,13 +1,13 @@
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-]]>
-
+
+
+
+
+ ]]>
+
-
-
-
-
-
-]]>
-
+
+
+
+
+
+
+
+ ]]>
+
+
-
-
+
+
+
@@ -235,6 +285,7 @@
+
@@ -246,6 +297,7 @@
-
+
+
diff --git a/build/make/targets/test.xml b/build/make/targets/test.xml
index 1b61b5a..c3ccc74 100644
--- a/build/make/targets/test.xml
+++ b/build/make/targets/test.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/vm/gcv4/src/gc_threads.cpp b/vm/gcv4/src/gc_threads.cpp
index dfc9b3c..be3bfe5 100644
--- a/vm/gcv4/src/gc_threads.cpp
+++ b/vm/gcv4/src/gc_threads.cpp
@@ -123,7 +123,7 @@ #endif
stat = hysem_create(&_gc_thread_work_done_event, 0, 1);
assert(stat == TM_ERROR_NONE);
_thread_handle=NULL;
- stat = hythread_create_with_group(&_thread_handle, get_thread_group(), 0, 0, 0, gc_thread_func, this);
+ stat = hythread_create(&_thread_handle, 0, 0, 0, gc_thread_func, this);
if (stat != TM_ERROR_NONE) {
DIE("GC_Thread::GC_Thread(..): CreateThread() failed...exiting...");
}
diff --git a/vm/include/open/hythread_ext.h b/vm/include/open/hythread_ext.h
index a604d32..5d81d50 100644
--- a/vm/include/open/hythread_ext.h
+++ b/vm/include/open/hythread_ext.h
@@ -189,9 +189,8 @@ hythread_group_t VMCALL get_java_thread_
*/
//@{
-IDATA VMCALL hythread_attach_ex(hythread_t *handle, hythread_library_t lib);
-IDATA VMCALL hythread_attach_to_group(hythread_t *handle, hythread_library_t lib, hythread_group_t group);
-IDATA hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data);
+IDATA VMCALL hythread_create_with_group(hythread_t new_thread, hythread_group_t group, UDATA stacksize, UDATA priority, hythread_entrypoint_t func, void *data);
+IDATA VMCALL hythread_attach_to_group(hythread_t new_handle, hythread_library_t lib, hythread_group_t group);
UDATA VMCALL hythread_clear_interrupted_other(hythread_t thread);
IDATA VMCALL hythread_join(hythread_t t);
IDATA VMCALL hythread_join_timed(hythread_t t, I_64 millis, IDATA nanos);
@@ -199,7 +198,7 @@ IDATA VMCALL hythread_join_interruptable
IDATA VMCALL hythread_get_self_id();
IDATA VMCALL hythread_get_id(hythread_t t);
hythread_t VMCALL hythread_get_thread(IDATA id);
-IDATA VMCALL hythread_struct_init(hythread_t *ret_thread);
+IDATA VMCALL hythread_struct_init(hythread_t new_thread);
IDATA VMCALL hythread_cancel_all(hythread_group_t group);
IDATA hythread_group_create(hythread_group_t *group);
IDATA VMCALL hythread_group_release(hythread_group_t group);
@@ -211,6 +210,7 @@ UDATA VMCALL hythread_get_thread_times(h
UDATA hythread_get_thread_stacksize(hythread_t thread);
UDATA VMCALL hythread_uses_fast_tls(void);
IDATA VMCALL hythread_get_hythread_offset_in_tls(void);
+IDATA VMCALL hythread_get_struct_size();
IDATA VMCALL hythread_thread_lock(hythread_t thread);
IDATA VMCALL hythread_thread_unlock(hythread_t thread);
diff --git a/vm/tests/unit/framework/testframe.h b/vm/tests/unit/framework/testframe.h
index 5334f1b..44bf2d8 100644
--- a/vm/tests/unit/framework/testframe.h
+++ b/vm/tests/unit/framework/testframe.h
@@ -22,6 +22,8 @@
#ifndef _TESTFRAME_H_
#define _TESTFRAME_H_
+#include
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/vm/tests/unit/thread/test_java_basic.c b/vm/tests/unit/thread/test_java_basic.c
index a0169c3..518216b 100644
--- a/vm/tests/unit/thread/test_java_basic.c
+++ b/vm/tests/unit/thread/test_java_basic.c
@@ -67,7 +67,7 @@ int test_jthread_attach(void) {
tested_thread_sturct_t * tts;
// Initialize tts structures and run all tested threads
- tested_os_threads_run(run_for_test_jthread_attach);
+ tested_os_threads_run((hythread_entrypoint_t)run_for_test_jthread_attach);
// Make second attach to the same jthread.
reset_tested_thread_iterator(&tts);
@@ -222,7 +222,7 @@ void JNICALL run_for_test_jthread_timed_
} else {
// wait until timeout or previous thread ends
status = jthread_timed_join(prev_tts->java_thread, timed_join_wait_time, 0);
- printf("-------- status = %08x (%i) %i\n", status, status, timed_join_wait_time);
+ printf("-------- status = %#08x (%d) %d\n", (int)status, (int)status, timed_join_wait_time);
tts->phase = TT_PHASE_DEAD;
if (timed_join_wait_time > CLICK_TIME_MSEC * 10){
// must be thread end
diff --git a/vm/tests/unit/thread/test_native_basic.c b/vm/tests/unit/thread/test_native_basic.c
index cc7db45..0811326 100644
--- a/vm/tests/unit/thread/test_native_basic.c
+++ b/vm/tests/unit/thread/test_native_basic.c
@@ -40,8 +40,8 @@ int test_hythread_self_base(void) {
int test_hythread_create(void){
apr_pool_t *pool;
void **args;
- hythread_t thread = NULL;
- int r;
+ hythread_t thread;
+ IDATA r;
apr_pool_create(&pool, NULL);
@@ -53,7 +53,10 @@ int test_hythread_create(void){
((jthread_threadattr_t *)args[1])->stacksize = 1024000;
((jthread_threadattr_t *)args[1])->priority = 1;
- r = hythread_create_with_group(&thread, args[0], 1024000, 1, 0, start_proc, args);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ r = hythread_create_with_group(thread, args[0], 1024000, 1,
+ (hythread_entrypoint_t)start_proc, args);
tf_assert(r == 0 && "thread creation failed");
r = hythread_join(thread);
@@ -107,8 +110,10 @@ int test_hythread_iterator(void) {
hylatch_create(&end, 1);
for (i = 0; i < n; i++) {
- thread = NULL;
- hythread_create_with_group(&thread, group, 0, 0, 0, start_proc_empty, NULL);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ hythread_create_with_group(thread, group, 0, 0,
+ (hythread_entrypoint_t)start_proc_empty, NULL);
}
// Wait util all threads have started.
@@ -117,7 +122,7 @@ int test_hythread_iterator(void) {
// Notify all threads
hylatch_count_down(end);
- printf ("iterator size: %d\n", hythread_iterator_size(iterator));
+ printf ("iterator size: %d\n", (int)hythread_iterator_size(iterator));
tf_assert(hythread_iterator_size(iterator) == n);
i = 0;
while(hythread_iterator_has_next(iterator)) {
@@ -145,8 +150,10 @@ int test_hythread_iterator_default(void)
hylatch_create(&end, 1);
for (i = 0; i < n; i++) {
- thread = NULL;
- hythread_create(&thread, 0, 0, 0, start_proc_empty, NULL);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ hythread_create_with_group(thread, NULL, 0, 0,
+ (hythread_entrypoint_t)start_proc_empty, NULL);
}
// Wait util all threads have started.
@@ -155,7 +162,7 @@ int test_hythread_iterator_default(void)
// Notify all threads
hylatch_count_down(end);
- printf("default group iterator: %d\n", hythread_iterator_size(iterator));
+ printf("default group iterator: %d\n", (int)hythread_iterator_size(iterator));
tf_assert(hythread_iterator_size(iterator) >= n);
i = 0;
while(hythread_iterator_has_next(iterator)) {
@@ -182,7 +189,7 @@ int test_hythread_create_many(void){
void **args;
hythread_t thread = NULL;
hythread_group_t group = NULL;
- int r;
+ IDATA r;
char *buf;
int i = 10;
@@ -199,9 +206,10 @@ int test_hythread_create_many(void){
((jthread_threadattr_t *)args[1])->stacksize = 1024000;
((jthread_threadattr_t *)args[1])->priority = 1;
- thread = NULL;
-
- r = hythread_create_with_group(&thread, group, 1024000, 1, 0, start_proc, args);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ r = hythread_create_with_group(thread, group, 1024000, 1,
+ (hythread_entrypoint_t)start_proc, args);
tf_assert(r == 0 && "thread creation failed");
buf = (char *)apr_pcalloc(pool, sizeof(char)*12);
diff --git a/vm/tests/unit/thread/test_native_fat_monitor.c b/vm/tests/unit/thread/test_native_fat_monitor.c
index 1923407..909c606 100644
--- a/vm/tests/unit/thread/test_native_fat_monitor.c
+++ b/vm/tests/unit/thread/test_native_fat_monitor.c
@@ -60,8 +60,10 @@ int test_wait_signal(void){
waiting_count = 0;
for (i = 0; i < NMB; i++){
- threads[i] = NULL;
- hythread_create(&threads[i], 0, 0, 0, run_for_test_wait_signal, NULL);
+ threads[i] = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(threads[i]);
+ hythread_create_with_group(threads[i], NULL, 0, 0,
+ (hythread_entrypoint_t)run_for_test_wait_signal, NULL);
}
// Wait till all tested threads call wait()
diff --git a/vm/tests/unit/thread/test_native_suspend.c b/vm/tests/unit/thread/test_native_suspend.c
index 0137c6d..e908c7d 100644
--- a/vm/tests/unit/thread/test_native_suspend.c
+++ b/vm/tests/unit/thread/test_native_suspend.c
@@ -28,7 +28,7 @@ int start_proc(void *args);
int test_hythread_thread_suspend(void){
apr_pool_t *pool;
void **args;
- hythread_t thread = NULL;
+ hythread_t thread;
hythread_thin_monitor_t lockword_ptr;
IDATA status;
int i;
@@ -41,7 +41,10 @@ int test_hythread_thread_suspend(void){
args[0] = &lockword_ptr;
args[1] = 0;
- hythread_create(&thread, 0, 0, 0, start_proc, args);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ hythread_create_with_group(thread, NULL, 0, 0,
+ (hythread_entrypoint_t)start_proc, args);
hythread_sleep(500);
hythread_suspend_other(thread);
hythread_suspend_disable();
@@ -63,7 +66,7 @@ int test_hythread_thread_suspend(void){
hythread_join(thread);
- tf_assert_same((int)args[1], 1);
+ tf_assert_same((IDATA)args[1], 1);
return 0;
}
@@ -86,8 +89,10 @@ int test_hythread_thread_suspend_all(voi
args[0] = lockword_ptr;
args[1] = 0;
for(i = 0; i < 10; i++) {
- thread = NULL;
- hythread_create(&thread, 0, 0, 0, start_proc, args);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ hythread_create_with_group(thread, NULL, 0, 0,
+ (hythread_entrypoint_t)start_proc, args);
}
hythread_sleep(500);
hythread_suspend_all(NULL, ((HyThread_public*)hythread_self())->group);
diff --git a/vm/tests/unit/thread/test_native_thin_monitor.c b/vm/tests/unit/thread/test_native_thin_monitor.c
index 1cadbfe..868d1eb 100644
--- a/vm/tests/unit/thread/test_native_thin_monitor.c
+++ b/vm/tests/unit/thread/test_native_thin_monitor.c
@@ -106,7 +106,7 @@ int test_hythread_thin_monitor_fat_unloc
tf_assert_same(status, TM_ERROR_NONE);
status = hythread_thin_monitor_wait_timed(&lockword_ptr, 1000,100);
- printf("status: %d\n", status);
+ printf("status: %d\n", (int)status);
tf_assert_same(status, TM_ERROR_TIMEOUT);
status = hythread_thin_monitor_exit(&lockword_ptr);
@@ -119,7 +119,7 @@ int start_proc(void *args);
int test_hythread_thin_monitor_enter_contended(void){
apr_pool_t *pool;
void **args;
- hythread_t thread = NULL;
+ hythread_t thread;
hythread_thin_monitor_t lockword_ptr;
IDATA status;
int i;
@@ -137,7 +137,10 @@ int test_hythread_thin_monitor_enter_con
args[0] = &lockword_ptr;
args[1] = 0;
- status = hythread_create(&thread, 0, 0, 0, start_proc, args);
+ thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ status = hythread_create_with_group(thread, NULL, 0, 0,
+ (hythread_entrypoint_t)start_proc, args);
tf_assert_same(status, TM_ERROR_NONE);
for(i = 0; i < 100000; i++) {
tf_assert_same(args[1], 0);
@@ -153,9 +156,9 @@ int test_hythread_thin_monitor_enter_con
status = hythread_thin_monitor_enter(&lockword_ptr);
tf_assert_same(status, TM_ERROR_NONE);
args[1] = 0;
- thread = NULL;
hythread_suspend_enable();
- status = hythread_create(&thread, 0, 0, 0, start_proc, args);
+ status = hythread_create_with_group(thread, NULL, 0, 0,
+ (hythread_entrypoint_t)start_proc, args);
tf_assert_same(status, TM_ERROR_NONE);
for(i = 0; i < 100000; i++) {
tf_assert_same(args[1], 0);
@@ -167,7 +170,7 @@ int test_hythread_thin_monitor_enter_con
hythread_join(thread);
- tf_assert_same((int)args[1], 1);
+ tf_assert_same((IDATA)args[1], 1);
return 0;
}
diff --git a/vm/tests/unit/thread/test_performance.h b/vm/tests/unit/thread/test_performance.h
deleted file mode 100644
index 5a662be..0000000
--- a/vm/tests/unit/thread/test_performance.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Alexander Shipilov
- * @version $Revision$
- */
-
-#include
-#include
-#include
-#include "testframe.h"
-#include "thread_unit_test_utils.h"
-#include "apr_time.h"
-#include "apr_pools.h"
-#include "apr_thread_cond.h"
-#include "apr_thread_proc.h"
-#include "apr_thread_mutex.h"
-#include "thread_private.h"
-
-/*
- * Number of iterations for each test
- * PERF_FIDELITY ~ measurement_fidelity ~ 1/running_time
- * Make sure that PERF_FIDELITY * ITERATIONS don't exceed threads limit
- */
-int const PERF_FIDELITY = 10;
-
-/*
- * Coefficient shows how much TMH performance could be worse than APR
- */
-float const PERF_COEFFICIENT = 3;
-
-/*
- * Locks for waiting
- */
-hymutex_t tm_mutex_lock;
-hycond_t tm_condition_lock = NULL;
-apr_thread_mutex_t* apr_mutex_lock = NULL;
-apr_thread_cond_t* apr_condition_lock = NULL;
-
-/*
-* Locks for concurrent mutex tests
-*/
-hymutex_t tm_concurrent_mutex_lock;
-apr_thread_mutex_t* apr_concurrent_mutex_lock = NULL;
-
-/*
-* Data variable and iterations constant for concurrent mutex tests
-*/
-int concurrent_mutex_data = 1;
-int const concurrent_mutex_iterations = 1000;
-int const concurrent_mutex_iterations_few_threads = 150000;
-
-int check_result(int difference, int otherdiff) {
- log_info("TMN result is: %i", difference/concurrent_mutex_iterations);
- log_info("APR result is: %i", otherdiff/concurrent_mutex_iterations);
- if (difference > (otherdiff * PERF_COEFFICIENT)) {
- if (!(difference == 0 || otherdiff == 0)) {
- return TEST_FAILED;
- }
- }
- return TEST_PASSED;
-}
diff --git a/vm/tests/unit/thread/test_performance_basic.c b/vm/tests/unit/thread/test_performance_basic.c
deleted file mode 100644
index aa9bc44..0000000
--- a/vm/tests/unit/thread/test_performance_basic.c
+++ /dev/null
@@ -1,583 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Alexander Shipilov
- * @version $Revision: 1.1.2.3 $
- */
-
-#include "test_performance.h"
-
-int proc_empty(void *args) {
- return 0;
-}
-
-void* APR_THREAD_FUNC proc_apr_empty(apr_thread_t *thread, void *args) {
- return 0;
-}
-
-int proc_waiting(void *args) {
- hymutex_lock(&tm_mutex_lock);
- hycond_wait(&tm_condition_lock, &tm_mutex_lock);
- hymutex_unlock(&tm_mutex_lock);
- return 0;
-}
-
-void* APR_THREAD_FUNC proc_apr_waiting(apr_thread_t *thread, void *args) {
- apr_thread_mutex_lock(apr_mutex_lock);
- apr_thread_cond_wait(apr_condition_lock, apr_mutex_lock);
- apr_thread_mutex_unlock(apr_mutex_lock);
- return 0;
-}
-
-/*
- * Test hythread_self()
- */
-int test_hythread_self(void){
-
- apr_time_t start, end;
-
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 1500000;
-
- hythread_t tm_native_thread;
-
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_threadkey_private_get((void **)(&tm_native_thread), TM_THREAD_KEY);
- assert(!statapr);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- tm_native_thread = hythread_self();
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
- * Test test_hymutex_create_destroy()
- */
-int test_hymutex_create_destroy(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 15000;
-
- apr_pool_t *pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, pool);
- assert(!statapr);
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- apr_pool_destroy(pool);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- apr_mutex_lock = NULL;
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
- * Test test_hymutex_lock_unlock()
- */
-int test_hymutex_lock_unlock(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 150000;
-
- apr_pool_t *pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, pool);
- assert(!statapr);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_thread_mutex_lock(apr_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_mutex_unlock(apr_mutex_lock);
- assert(!statapr);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- apr_pool_destroy(pool);
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = hymutex_lock(&tm_mutex_lock);
- assert(!stat);
- stat = hymutex_unlock(&tm_mutex_lock);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
- * Test test_hymutex_trylock_unlock()
- */
-int test_hymutex_trylock_unlock(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 150000;
-
- apr_pool_t *pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, pool);
- assert(!statapr);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_thread_mutex_trylock(apr_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_mutex_unlock(apr_mutex_lock);
- assert(!statapr);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- apr_pool_destroy(pool);
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = hymutex_trylock(&tm_mutex_lock);
- assert(!stat);
- stat = hymutex_unlock(&tm_mutex_lock);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
- * Test test_hythread_create()
- */
-int test_hythread_create(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 300;
-
- int OTHER_FIDELITY;
- int const MAX_THREADS = 1000;
-
- hythread_t thread = NULL;
- void *args = NULL;
- apr_thread_t *apr_thread = NULL;
- apr_threadattr_t *apr_attrs = NULL;
- apr_pool_t *pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- if ((ITERATIONS * PERF_FIDELITY) > MAX_THREADS) {
- OTHER_FIDELITY = (MAX_THREADS / ITERATIONS);
- } else {
- OTHER_FIDELITY = PERF_FIDELITY;
- }
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < OTHER_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_thread_create(&apr_thread, apr_attrs, proc_apr_empty, args, pool);
- apr_thread_join(&statapr, apr_thread);
- assert(!statapr);
- assert(!statapr);
- apr_pool_destroy(pool);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- aprdiff = aprdiff / OTHER_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < OTHER_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- thread = NULL;
- stat = hythread_create(&thread, 0, 0, 0, proc_empty, args);
- assert(!stat);
- stat = hythread_join(thread);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- difference = difference / OTHER_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
-* Test test_hythread_thread_suspend_enable_disable()
-*/
-int test_hythread_thread_suspend_enable_disable(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 1500000;
-
- apr_status_t statapr;
-
- hythread_t tm_native_thread;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- statapr = apr_threadkey_private_get((void **)(&tm_native_thread), TM_THREAD_KEY);
- assert(!statapr);
- statapr = apr_threadkey_private_set((void *)(tm_native_thread), TM_THREAD_KEY);
- assert(!statapr);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- hythread_suspend_disable();
- hythread_suspend_enable();
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
-* Test test_hythread_set_private_data()
-*/
-int test_hythread_set_private_data(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 1000000;
-
- hythread_t thread = NULL;
- void *args = NULL;
- void *data = NULL;
- apr_thread_t *apr_thread = NULL;
- apr_threadattr_t *apr_attrs = NULL;
-
- apr_pool_t *pool;
- apr_pool_t *locks_pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- // Create pools, locks and thread
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_pool_create(&locks_pool, NULL);
- assert(!statapr);
- statapr = apr_thread_cond_create(&apr_condition_lock, locks_pool);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, locks_pool);
- assert(!statapr);
- statapr = apr_thread_create(&apr_thread, apr_attrs, proc_apr_waiting, args, pool);
- assert(!statapr);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = apr_thread_data_set(data, "DATA", 0, apr_thread);
- assert(!stat);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- statapr = apr_thread_cond_signal(apr_condition_lock);
- assert(!statapr);
- apr_thread_join(&statapr, apr_thread);
- assert(!statapr);
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_cond_destroy(apr_condition_lock);
- assert(!statapr);
- apr_pool_destroy(locks_pool);
- apr_pool_destroy(pool);
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- // Create locks and thread
- stat = hycond_create(&tm_condition_lock);
- assert(!stat);
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- stat = hythread_create(&thread, 0, 0, 0, proc_waiting, args);
- assert(!stat);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = hythread_set_private_data(thread, data);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- stat = hycond_notify(tm_condition_lock);
- assert(!stat);
- stat = hythread_join(thread);
- assert(!stat);
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- stat = hycond_destroy(tm_condition_lock);
- assert(!stat);
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-/*
-* Test test_hythread_get_private_data()
-*/
-int test_hythread_get_private_data(void) {
-
- apr_time_t start, end;
- long difference = 0, aprdiff = 0;
-
- int i, j;
- long ITERATIONS = 1000000;
-
- hythread_t thread = NULL;
- void *args = NULL;
- void *data = NULL;
- apr_thread_t *apr_thread = NULL;
- apr_threadattr_t *apr_attrs = NULL;
-
- apr_pool_t *pool;
- apr_pool_t *locks_pool;
-
- IDATA stat;
- apr_status_t statapr;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- // Create pools, locks and thread
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_pool_create(&locks_pool, NULL);
- assert(!statapr);
- statapr = apr_thread_cond_create(&apr_condition_lock, locks_pool);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, locks_pool);
- assert(!statapr);
- statapr = apr_thread_create(&apr_thread, apr_attrs, proc_apr_waiting, args, pool);
- assert(!statapr);
- // Set private data
- stat = apr_thread_data_set(data, "DATA", 0, apr_thread);
- assert(!stat);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- stat = apr_thread_data_get(&data, "DATA", apr_thread);
- assert(!stat);
- }
- end = apr_time_now();
- aprdiff = aprdiff + (end - start);
- }
- statapr = apr_thread_cond_signal(apr_condition_lock);
- assert(!statapr);
- apr_thread_join(&statapr, apr_thread);
- assert(!statapr);
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_cond_destroy(apr_condition_lock);
- assert(!statapr);
- apr_pool_destroy(locks_pool);
- apr_pool_destroy(pool);
- aprdiff = aprdiff / PERF_FIDELITY;
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- // Create locks and thread
- stat = hycond_create(&tm_condition_lock);
- assert(!stat);
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- stat = hythread_create(&thread, 0, 0, 0, proc_waiting, args);
- assert(!stat);
- // Set private data
- stat = hythread_set_private_data(thread, data);
- assert(!stat);
- for (j = 0; j < PERF_FIDELITY; j++) {
- start = apr_time_now();
- for (i = 0; i < ITERATIONS; i++) {
- data = hythread_get_private_data(thread);
- assert(!stat);
- }
- end = apr_time_now();
- difference = difference + (end - start);
- }
- stat = hycond_notify(tm_condition_lock);
- assert(!stat);
- stat = hythread_join(thread);
- assert(!stat);
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- stat = hycond_destroy(tm_condition_lock);
- assert(!stat);
- difference = difference / PERF_FIDELITY;
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-TEST_LIST_START
- TEST(test_hythread_self)
- TEST(test_hymutex_create_destroy)
- TEST(test_hymutex_lock_unlock)
- TEST(test_hymutex_trylock_unlock)
- TEST(test_hythread_create)
- TEST(test_hythread_thread_suspend_enable_disable)
- TEST(test_hythread_set_private_data)
- TEST(test_hythread_get_private_data)
-TEST_LIST_END;
diff --git a/vm/tests/unit/thread/test_performance_concurrent_mutex.c b/vm/tests/unit/thread/test_performance_concurrent_mutex.c
deleted file mode 100644
index 9acac5f..0000000
--- a/vm/tests/unit/thread/test_performance_concurrent_mutex.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @author Alexander Shipilov
- * @version $Revision: 1.1.2.3 $
- */
-
-#include "test_performance.h"
-
-int test_hythread_cuncurrent_mutex_apr(apr_thread_t* apr_threads_array[],
- int THREADS_NUMBER, apr_thread_start_t func);
-
-int test_hythread_cuncurrent_mutex_tm(hythread_t threads_array[],
- int THREADS_NUMBER, hythread_entrypoint_t func);
-
-int check_result_few_threads(int difference, int otherdiff);
-
-int test_hythread_cuncurrent_mutex_run_test_few_threads(int THREADS_NUMBER,
- apr_thread_t* apr_threads_array[],
- apr_thread_start_t apr_func,
- hythread_t threads_array[],
- hythread_entrypoint_t hythread_func);
-
-int test_hythread_cuncurrent_mutex_run_test(int THREADS_NUMBER,
- apr_thread_t* apr_threads_array[],
- apr_thread_start_t apr_func,
- hythread_t threads_array[],
- hythread_entrypoint_t hythread_func);
-
-int iterations;
-
-/*
- * Concurrent mutex functions
- */
-
-int proc_concurrent(void *args) {
-
- int j = 0;
-
- hymutex_lock(&tm_mutex_lock);
- hycond_wait(&tm_condition_lock, &tm_mutex_lock);
- hymutex_unlock(&tm_mutex_lock);
-
- for (j = 0; j < iterations; j++) {
- hymutex_lock(tm_concurrent_mutex_lock);
- concurrent_mutex_data = 1;
- hymutex_unlock(tm_concurrent_mutex_lock);
- }
-
- return 0;
-}
-
-void* APR_THREAD_FUNC proc_apr_concurrent(apr_thread_t *thread, void *args) {
-
- int j = 0;
-
- apr_thread_mutex_lock(apr_mutex_lock);
- apr_thread_cond_wait(apr_condition_lock, apr_mutex_lock);
- apr_thread_mutex_unlock(apr_mutex_lock);
-
- for (j = 0; j < iterations; j++) {
- apr_thread_mutex_lock(apr_concurrent_mutex_lock);
- concurrent_mutex_data = 1;
- apr_thread_mutex_unlock(apr_concurrent_mutex_lock);
- }
- return 0;
-}
-
-/*
- * Concurrent mutex tests
- */
-
-int test_hythread_cuncurrent_mutex1(void){
-
- const int THREADS_NUMBER = 1;
- hythread_t threads_array[1];
- apr_thread_t* apr_threads_array[1];
-
- return test_hythread_cuncurrent_mutex_run_test_few_threads(THREADS_NUMBER,
- apr_threads_array,
- proc_apr_concurrent,
- threads_array,
- proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex2(void){
-
- const int THREADS_NUMBER = 2;
- hythread_t threads_array[2];
- apr_thread_t* apr_threads_array[2];
-
- return test_hythread_cuncurrent_mutex_run_test_few_threads(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex4(void){
-
- const int THREADS_NUMBER = 4;
- hythread_t threads_array[4];
- apr_thread_t* apr_threads_array[4];
-
- return test_hythread_cuncurrent_mutex_run_test_few_threads(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex8(void){
-
- const int THREADS_NUMBER = 8;
- hythread_t threads_array[8];
- apr_thread_t* apr_threads_array[8];
-
- return test_hythread_cuncurrent_mutex_run_test_few_threads(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex16(void){
-
- const int THREADS_NUMBER = 16;
- hythread_t threads_array[16];
- apr_thread_t* apr_threads_array[16];
-
- return test_hythread_cuncurrent_mutex_run_test(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex32(void){
-
- const int THREADS_NUMBER = 32;
- hythread_t threads_array[32];
- apr_thread_t* apr_threads_array[32];
-
- return test_hythread_cuncurrent_mutex_run_test(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex64(void){
-
- const int THREADS_NUMBER = 64;
- hythread_t threads_array[64];
- apr_thread_t* apr_threads_array[64];
-
- return test_hythread_cuncurrent_mutex_run_test(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex128(void){
-
- const int THREADS_NUMBER = 128;
- hythread_t threads_array[128];
- apr_thread_t* apr_threads_array[128];
-
- return test_hythread_cuncurrent_mutex_run_test(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex256(void){
-
- const int THREADS_NUMBER = 256;
- hythread_t threads_array[256];
- apr_thread_t* apr_threads_array[256];
-
- return test_hythread_cuncurrent_mutex_run_test(THREADS_NUMBER,
- apr_threads_array, proc_apr_concurrent, threads_array, proc_concurrent);
-}
-
-int test_hythread_cuncurrent_mutex_run_test(int THREADS_NUMBER,
- apr_thread_t* apr_threads_array[],
- apr_thread_start_t apr_func,
- hythread_t threads_array[],
- hythread_entrypoint_t hythread_func)
-{
- long difference = 0, aprdiff = 0;
-
- iterations = concurrent_mutex_iterations;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- aprdiff = test_hythread_cuncurrent_mutex_apr(apr_threads_array, THREADS_NUMBER, apr_func);
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- difference = test_hythread_cuncurrent_mutex_tm(threads_array, THREADS_NUMBER, hythread_func);
- tested_threads_destroy();
-
- return check_result(difference, aprdiff);
-}
-
-int test_hythread_cuncurrent_mutex_run_test_few_threads(int THREADS_NUMBER,
- apr_thread_t* apr_threads_array[],
- apr_thread_start_t apr_func,
- hythread_t threads_array[],
- hythread_entrypoint_t hythread_func)
-{
- long difference = 0, aprdiff = 0;
-
- iterations = concurrent_mutex_iterations_few_threads;
-
- /* APR test */
- tested_threads_run(default_run_for_test);
- aprdiff = test_hythread_cuncurrent_mutex_apr(apr_threads_array, THREADS_NUMBER, apr_func);
- tested_threads_destroy();
-
- /* Thread manager test */
- tested_threads_run(default_run_for_test);
- difference = test_hythread_cuncurrent_mutex_tm(threads_array, THREADS_NUMBER, hythread_func);
- tested_threads_destroy();
-
- return check_result_few_threads(difference, aprdiff);
-}
-
-int test_hythread_cuncurrent_mutex_apr(apr_thread_t* apr_threads_array[],
- int THREADS_NUMBER, apr_thread_start_t func)
-{
- int i;
-
- apr_time_t start, end;
-
- void *args = NULL;
- apr_threadattr_t *apr_attrs = NULL;
-
- apr_pool_t* pool;
- apr_pool_t* locks_pool;
-
- apr_status_t statapr;
-
- for (i = 0; i < THREADS_NUMBER; i++) {
- apr_threads_array[i] = NULL;
- }
- // Create pools and locks
- statapr = apr_pool_create(&pool, NULL);
- assert(!statapr);
- statapr = apr_pool_create(&locks_pool, NULL);
- assert(!statapr);
- statapr = apr_thread_cond_create(&apr_condition_lock, locks_pool);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_mutex_lock, APR_THREAD_MUTEX_DEFAULT, locks_pool);
- assert(!statapr);
- statapr = apr_thread_mutex_create(&apr_concurrent_mutex_lock, APR_THREAD_MUTEX_DEFAULT, locks_pool);
- assert(!statapr);
- // Create threads
- for (i = 0; i < THREADS_NUMBER; i++) {
- statapr = apr_thread_create(&apr_threads_array[i], apr_attrs, func, args, pool);
- assert(!statapr);
- }
- jthread_sleep(1000, 1);
- start = apr_time_now();
- statapr = apr_thread_cond_broadcast(apr_condition_lock);
- assert(!statapr);
- for (i = 0; i < THREADS_NUMBER; i++) {
- apr_thread_join(&statapr, apr_threads_array[i]);
- assert(!statapr);
- }
- end = apr_time_now();
- statapr = apr_thread_mutex_destroy(apr_concurrent_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_mutex_destroy(apr_mutex_lock);
- assert(!statapr);
- statapr = apr_thread_cond_destroy(apr_condition_lock);
- assert(!statapr);
- apr_pool_destroy(locks_pool);
- apr_pool_destroy(pool);
- return (end - start);
-}
-
-int test_hythread_cuncurrent_mutex_tm(hythread_t threads_array[],
- int THREADS_NUMBER, hythread_entrypoint_t func)
-{
- int i;
-
- apr_time_t start, end;
-
- void *args = NULL;
-
- IDATA stat;
-
- for (i = 0; i < THREADS_NUMBER; i++) {
- threads_array[i] = NULL;
- }
- stat = hycond_create(&tm_condition_lock);
- assert(!stat);
- stat = hymutex_create(&tm_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- stat = hymutex_create(&tm_concurrent_mutex_lock, APR_THREAD_MUTEX_DEFAULT);
- assert(!stat);
- for (i = 0; i < THREADS_NUMBER; i++) {
- hythread_create(&threads_array[i], 0, 0, 0, func, args);
- }
- jthread_sleep(1000, 1);
- start = apr_time_now();
- hycond_notify_all(tm_condition_lock);
- for (i = 0; i < THREADS_NUMBER; i++) {
- hythread_join(threads_array[i]);
- }
- end = apr_time_now();
- stat = hymutex_destroy(&tm_concurrent_mutex_lock);
- assert(!stat);
- stat = hymutex_destroy(&tm_mutex_lock);
- assert(!stat);
- stat = hycond_destroy(&tm_condition_lock);
- assert(!stat);
- return (end - start);
-}
-
-int check_result_few_threads(int difference, int otherdiff) {
- float base, fraction;
-
- base = difference / concurrent_mutex_iterations_few_threads;
- fraction = difference % concurrent_mutex_iterations_few_threads;
- fraction = fraction / concurrent_mutex_iterations_few_threads;
- base = base + fraction;
- log_info("TMN result is: %4.2f", base);
-
- base = otherdiff / concurrent_mutex_iterations_few_threads;
- fraction = otherdiff % concurrent_mutex_iterations_few_threads;
- fraction = fraction / concurrent_mutex_iterations_few_threads;
- base = base + fraction;
- log_info("APR result is: %4.2f", base);
-
- if (difference > (otherdiff * PERF_COEFFICIENT)) {
- if (!(difference == 0 || otherdiff == 0)) {
- return TEST_FAILED;
- }
- }
- return TEST_PASSED;
-}
-
-TEST_LIST_START
- TEST(test_hythread_cuncurrent_mutex1)
- TEST(test_hythread_cuncurrent_mutex2)
- TEST(test_hythread_cuncurrent_mutex4)
- TEST(test_hythread_cuncurrent_mutex8)
- TEST(test_hythread_cuncurrent_mutex16)
- TEST(test_hythread_cuncurrent_mutex32)
- TEST(test_hythread_cuncurrent_mutex64)
- TEST(test_hythread_cuncurrent_mutex128)
- TEST(test_hythread_cuncurrent_mutex256)
-TEST_LIST_END;
diff --git a/vm/tests/unit/thread/utils/thread_unit_test_utils.c b/vm/tests/unit/thread/utils/thread_unit_test_utils.c
index ce4a66a..eec5eaf 100644
--- a/vm/tests/unit/thread/utils/thread_unit_test_utils.c
+++ b/vm/tests/unit/thread/utils/thread_unit_test_utils.c
@@ -19,11 +19,11 @@ #include
#include "jni.h"
#include "testframe.h"
#include "thread_unit_test_utils.h"
-#include
-#include
-#include
-#include
-#include
+#include "open/jthread.h"
+#include "open/hythread.h"
+#include "open/hythread_ext.h"
+#include "open/ti_thread.h"
+#include "open/thread_externals.h"
#include "apr_time.h"
@@ -269,10 +269,11 @@ void tested_os_threads_run(hythread_entr
reset_tested_thread_iterator(&tts);
while(next_tested_thread(&tts)){
// Create thread
- status = hythread_create(&tts->native_thread, // new thread OS handle
- 0, 5, 0,
- run_method_param, // start proc
- tts);
+ tts->native_thread =
+ (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(tts->native_thread);
+ status = hythread_create_with_group(tts->native_thread,
+ NULL, 0, 5, run_method_param, tts);
tf_assert_v(status == TM_ERROR_NONE);
tested_thread_wait_started(tts);
}
diff --git a/vm/tests/unit/thread/utils/thread_unit_test_utils.h b/vm/tests/unit/thread/utils/thread_unit_test_utils.h
index df38e78..2b59412 100644
--- a/vm/tests/unit/thread/utils/thread_unit_test_utils.h
+++ b/vm/tests/unit/thread/utils/thread_unit_test_utils.h
@@ -15,6 +15,7 @@
* limitations under the License.
*/
+#include
#include "jvmti_types.h"
#include "apr_thread_proc.h"
#include "open/hycomp.h"
diff --git a/vm/thread/src/hythr.def b/vm/thread/src/hythr.def
index 4ca2155..194e510 100644
--- a/vm/thread/src/hythr.def
+++ b/vm/thread/src/hythr.def
@@ -1,4 +1,4 @@
-LIBRARY HYTHR
+LIBRARY HYTHR
EXPORTS
@@ -40,6 +40,7 @@ hythread_get_priority
hythread_tls_get
hythread_tls_get_request_offset
hythread_tls_get_offset
+hythread_get_struct_size
hythread_global_lock
hythread_global_unlock
hythread_attach_to_group
@@ -88,9 +89,6 @@ hythread_thin_monitor_get_owner
hythread_native_resource_is_live
hythread_reclaim_resources
-
-
-
hysem_post
hysem_wait
hysem_destroy
@@ -121,7 +119,6 @@ hymutex_trylock
hymutex_unlock
hymutex_destroy
-
hythread_is_alive
hythread_is_terminated
hythread_init
diff --git a/vm/thread/src/hythr.exp b/vm/thread/src/hythr.exp
index 4b60884..8feb5dc 100644
--- a/vm/thread/src/hythr.exp
+++ b/vm/thread/src/hythr.exp
@@ -41,6 +41,7 @@ hythread_tls_get_request_offset;
hythread_get_hythread_offset_in_tls;
hythread_uses_fast_tls;
hythread_tls_get_offset;
+hythread_get_struct_size;
hythread_global_lock;
hythread_global_unlock;
hythread_attach_to_group;
diff --git a/vm/thread/src/linux/os_thread.c b/vm/thread/src/linux/os_thread.c
index 75329f0..1b7f567 100644
--- a/vm/thread/src/linux/os_thread.c
+++ b/vm/thread/src/linux/os_thread.c
@@ -50,23 +50,23 @@ int os_thread_create(/* out */osthread_t
int (VMAPICALL *func)(void*), void *data)
{
pthread_t thread;
- pthread_attr_t attr, *pattr = NULL;
+ pthread_attr_t attr;
int r;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
if (stacksize != 0) {
- pattr = &attr;
- pthread_attr_init(pattr);
- r = pthread_attr_setstacksize(pattr, stacksize);
+ r = pthread_attr_setstacksize(&attr, stacksize);
if (r) {
- pthread_attr_destroy(pattr);
+ pthread_attr_destroy(&attr);
return r;
}
}
- r = pthread_create(&thread, pattr, (void*(*)(void*))func, data);
+ r = pthread_create(&thread, &attr, (void*(*)(void*))func, data);
- if (pattr)
- pthread_attr_destroy(pattr);
+ pthread_attr_destroy(&attr);
if (r == 0) {
*phandle = thread;
diff --git a/vm/thread/src/thread_init.c b/vm/thread/src/thread_init.c
index 41c5501..f8e845a 100644
--- a/vm/thread/src/thread_init.c
+++ b/vm/thread/src/thread_init.c
@@ -73,8 +73,6 @@ #endif
* @param[out] lib pointer to the created thread library
* @return The thread library's initStatus will be set to 0 on success or
* a negative value on failure.
- *
- * @see hythread_attach, hythread_shutdown
*/
IDATA VMCALL hythread_lib_create(hythread_library_t * lib) {
apr_status_t apr_status;
@@ -121,8 +119,6 @@ void VMCALL hythread_lib_destroy(hythrea
* @param[in] lib pointer to the thread library to be initialized (non-NULL)
* @return The thread library's initStatus will be set to 0 on success or
* a negative value on failure.
- *
- * @see hythread_attach, hythread_shutdown
*/
void VMCALL hythread_init(hythread_library_t lib) {
apr_status_t apr_status;
diff --git a/vm/thread/src/thread_native_basic.c b/vm/thread/src/thread_native_basic.c
index 6a6b95e..a625c79 100644
--- a/vm/thread/src/thread_native_basic.c
+++ b/vm/thread/src/thread_native_basic.c
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-/**
+/**
* @author Nikolay Kuznetsov
*/
@@ -47,8 +47,6 @@ typedef struct {
extern hythread_group_t TM_DEFAULT_GROUP;
extern hythread_library_t TM_LIBRARY;
static int VMAPICALL thread_start_proc(void *arg);
-static hythread_t allocate_thread();
-static void reset_thread(hythread_t thread);
static IDATA register_to_group(hythread_t thread, hythread_group_t group);
#define NAKED __declspec(naked)
@@ -69,23 +67,23 @@ int next_id = 1;
/*
IDATA add_to_fast_thread_array(hythread_t thread,int id)
{
- if (id>=MAX_ID)
- {
- if (MAX_ID<1000)
- {
- MAX_ID=1000;
- fast_thread_array=(hythread_t *)malloc(MAX_ID*sizeof(hythread_t));
- }
- else
- {
- MAX_ID*=2;
- fast_thread_array=(hythread_t *)realloc(fast_thread_array,MAX_ID*sizeof(hythread_t));
- }
- if (fast_thread_array==NULL)
- return TM_ERROR_OUT_OF_MEMORY;
- }
- fast_thread_array[id]=thread;
- return TM_ERROR_NONE;
+ if (id>=MAX_ID)
+ {
+ if (MAX_ID<1000)
+ {
+ MAX_ID=1000;
+ fast_thread_array=(hythread_t *)malloc(MAX_ID*sizeof(hythread_t));
+ }
+ else
+ {
+ MAX_ID*=2;
+ fast_thread_array=(hythread_t *)realloc(fast_thread_array,MAX_ID*sizeof(hythread_t));
+ }
+ if (fast_thread_array==NULL)
+ return TM_ERROR_OUT_OF_MEMORY;
+ }
+ fast_thread_array[id]=thread;
+ return TM_ERROR_NONE;
}*/
static void thread_set_self(hythread_t thread);
@@ -98,54 +96,52 @@ static void thread_set_self(hythread_t t
* @param[in] func function to run in the new thread
* @param[in] data argument to be passed to starting function
*/
-IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t group, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data) {
- hythread_t new_thread;
+IDATA VMCALL hythread_create_with_group(hythread_t new_thread,
+ hythread_group_t group,
+ UDATA stacksize,
+ UDATA priority,
+ hythread_entrypoint_t func,
+ void *data)
+{
+ int result;
+ hythread_t self;
thread_start_proc_data * start_proc_data;
- int r;
-
- if (ret_thread) {
- hythread_struct_init(ret_thread);
- new_thread = *ret_thread;
- } else {
- new_thread = allocate_thread();
- }
-
- if (new_thread == NULL) {
- return TM_ERROR_OUT_OF_MEMORY;
- }
- new_thread->library = hythread_self()->library;
+ assert(new_thread);
+ hythread_struct_init(new_thread);
+
+ self = hythread_self();
+ new_thread->library = self ? self->library : TM_LIBRARY;
new_thread->priority = priority ? priority : HYTHREAD_PRIORITY_NORMAL;
new_thread->stacksize = stacksize ? stacksize : TM_DEFAULT_STACKSIZE;
- //new_thread->suspend_request = suspend ? 1 : 0;
-
+
+ // No need to zero allocated memory because all fields are initilized below.
start_proc_data =
(thread_start_proc_data *) malloc(sizeof(thread_start_proc_data));
-
if (start_proc_data == NULL) {
return TM_ERROR_OUT_OF_MEMORY;
}
- // Set up thread body procedure
+ // Set up thread body procedure
start_proc_data->thread = new_thread;
start_proc_data->group = group == NULL ? TM_DEFAULT_GROUP : group;
start_proc_data->start_proc = func;
start_proc_data->start_proc_args = data;
- // we need to make sure thread will not register itself with a thread group
- // until os_thread_create returned and initialized thread->os_handle properly
+ // Need to make sure thread will not register itself with a thread group
+ // until os_thread_create returned and initialized thread->os_handle properly.
hythread_global_lock();
- r = os_thread_create(&new_thread->os_handle, new_thread->stacksize,
+ result = os_thread_create(&new_thread->os_handle, new_thread->stacksize,
priority, thread_start_proc, (void *)start_proc_data);
- assert(/* error */ r || new_thread->os_handle /* or thread created ok */);
+ assert(/* error */ result || new_thread->os_handle /* or thread created ok */);
hythread_global_unlock();
-
- return r;
+
+ return result;
}
/**
* Create a new OS thread.
- *
+ *
* The created thread is attached to the threading library.
*
* Unlike POSIX, this doesn't require an attributes structure.
@@ -164,48 +160,47 @@ IDATA VMCALL hythread_create_with_group(
*
* @see hythread_exit, hythread_resume
*/
-IDATA VMCALL hythread_create(hythread_t *ret_thread, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data) {
- return hythread_create_with_group(ret_thread, NULL, stacksize, priority, suspend, func, data);
+IDATA VMCALL hythread_create(hythread_t *handle, UDATA stacksize, UDATA priority, UDATA suspend, hythread_entrypoint_t func, void *data) {
+ hythread_t thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ if (handle) {
+ *handle = thread;
+ }
+ return hythread_create_with_group(thread, NULL, stacksize, priority, func, data);
}
/**
* Registers the current OS thread with the threading subsystem.
*
- * @param[in] handle thread to register
- * @param[in] lib thread library to attach to
- * @param[in] group thread group, or NULL; in case of NULL this thread will go to the default group
+ * @param[in] new_thread thread to register
+ * @param[in] lib thread library to attach to
+ * @param[in] group thread group, or NULL; in case of NULL this thread will
+ * go to the default group
*/
-IDATA hythread_attach_to_group(hythread_t * handle, hythread_library_t lib, hythread_group_t group) {
- hythread_t thread;
-
- if (lib == NULL) {
- lib = TM_LIBRARY;
- }
+IDATA hythread_attach_to_group(hythread_t new_thread,
+ hythread_library_t lib,
+ hythread_group_t group)
+{
+ hythread_t self;
- // Do nothing and return if the thread is already attached
- thread = tm_self_tls;
- if (thread) {
- if (handle) {
- *handle = thread;
- }
+ assert(new_thread);
+ self = hythread_self();
+ if (self) {
+ // The thread is already attached, just fill a given thread structure.
+ *new_thread = *self;
return TM_ERROR_NONE;
}
- if (handle) {
- hythread_struct_init(handle);
- thread = *handle;
- } else {
- thread = allocate_thread();
- }
- if (thread == NULL) {
- return TM_ERROR_OUT_OF_MEMORY;
- }
- thread->library = lib;
- thread->os_handle = os_thread_current();
- assert(thread->os_handle);
- TRACE(("TM: native attached: native: %p ", tm_self_tls));
-
- return register_to_group(thread, group == NULL ? TM_DEFAULT_GROUP : group);
+ hythread_struct_init(new_thread);
+ assert(lib == NULL);
+ new_thread->library = TM_LIBRARY;
+ new_thread->os_handle = os_thread_current();
+ assert(new_thread->os_handle);
+
+ TRACE(("TM: native attached: native: %p ", self));
+
+ return register_to_group(new_thread,
+ (group == NULL ? TM_DEFAULT_GROUP : group));
}
/**
@@ -222,11 +217,16 @@ IDATA hythread_attach_to_group(hythread_
* @param[out] handle pointer to a hythread_t to be set (will be ignored if null)
* @return 0 on success or negative value on failure
*
- * @note (*handle) should be NULL or point to hythread_t structure
+ * @note (*handle) should be NULL or point to hythread_t structure
* @see hythread_detach
*/
IDATA VMCALL hythread_attach(hythread_t *handle) {
- return hythread_attach_to_group(handle, TM_LIBRARY, NULL);
+ hythread_t thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ assert(thread);
+ if (handle) {
+ *handle = thread;
+ }
+ return hythread_attach_to_group(thread, NULL, NULL);
}
/**
@@ -236,28 +236,27 @@ IDATA VMCALL hythread_attach(hythread_t
* @param[in] lib thread library to attach thread to
* @return 0 on success or negative value on failure
*
- * @note (*handle) should be NULL or point to hythread_t structure
+ * @note (*handle) should be NULL or point to hythread_t structure
* @see hythread_detach
*/
IDATA VMCALL hythread_attach_ex(hythread_t *handle, hythread_library_t lib) {
- return hythread_attach_to_group(handle, lib, NULL);
+ assert(handle);
+ return hythread_attach_to_group(*handle, NULL, NULL);
}
/**
* Detaches a thread from the threading library.
- *
+ *
* @note Assumes that the thread being detached is already attached.
- *
+ *
* If the thread is an attached thread, then detach should only be called by the thread
* itself. Internal resources associated with the thread are freed.
- *
+ *
* If the thread is already dead, this call will destroy it.
- *
+ *
* @param[in] thread a hythread_t representing the thread to be detached.
* If this is NULL, the current thread is detached.
* @return none
- *
- * @see hythread_attach
*/
void VMCALL hythread_detach(hythread_t thread) {
IDATA status;
@@ -265,24 +264,27 @@ void VMCALL hythread_detach(hythread_t t
if (thread == NULL) {
thread = hythread_self();
}
-
+
// Acquire global TM lock to prevent concurrent access to thread list
status = hythread_global_lock(NULL);
assert(status == TM_ERROR_NONE);
// No actions required in case the specified thread is detached already.
if (thread->group != NULL) {
- assert(thread == tm_self_tls);
-
- thread_set_self(NULL);
+ // The thread can be detached from the other thread in case
+ // of forceful termination by hythread_cancel(), but thread
+ // local storage can be zeroed only for current thread.
+ if (thread == hythread_self() ) {
+ thread_set_self(NULL);
+ }
fast_thread_array[thread->thread_id] = NULL;
-
+
thread->prev->next = thread->next;
thread->next->prev = thread->prev;
thread->group->threads_count--;
thread->group = NULL;
}
-
+
hythread_global_unlock(NULL);
assert(status == TM_ERROR_NONE);
}
@@ -292,7 +294,7 @@ void VMCALL hythread_detach(hythread_t t
*
* @param[in] t thread to join
*/
-IDATA VMCALL hythread_join(hythread_t t) {
+IDATA VMCALL hythread_join(hythread_t t) {
return hylatch_wait(t->join_event);
}
/**
@@ -304,7 +306,7 @@ IDATA VMCALL hythread_join(hythread_t t)
* @return TM_THREAD_TIMEOUT or 0 in case thread
* was successfully joined.
*/
-IDATA VMCALL hythread_join_timed(hythread_t t, I_64 millis, IDATA nanos) {
+IDATA VMCALL hythread_join_timed(hythread_t t, I_64 millis, IDATA nanos) {
return hylatch_wait_timed(t->join_event, millis, nanos);
}
@@ -317,40 +319,28 @@ IDATA VMCALL hythread_join_timed(hythrea
* @return TM_THREAD_TIMEOUT or TM_THREAD_INTERRUPTED or 0 in case thread
* was successfully joined.
*/
-IDATA VMCALL hythread_join_interruptable(hythread_t t, I_64 millis, IDATA nanos) {
+IDATA VMCALL hythread_join_interruptable(hythread_t t, I_64 millis, IDATA nanos) {
return hylatch_wait_interruptable(t->join_event, millis, nanos);
}
/**
* Yield the processor.
- *
+ *
* @return none
*/
void VMCALL hythread_yield() {
- //apr_thread_yield returns void
+ //apr_thread_yield returns void
apr_thread_yield();
}
-/**
- * Return the hythread_t for the current thread.
- *
- * @note Must be called only by an attached thread
- *
- * @return hythread_t for the current thread
- *
- * @see hythread_attach
- *
- */
-#ifdef APR_TLS_USE
+
/**
* Return the hythread_t for the current thread.
*
* @note Must be called only by an attached thread
*
* @return hythread_t for the current thread
- *
- * @see hythread_attach
- *
*/
+#ifdef APR_TLS_USE
hythread_t hythread_self_slow() {
hythread_t thread;
apr_status_t UNUSED apr_status;
@@ -365,24 +355,14 @@ hythread_t hythread_self_slow() {
static void thread_set_self(hythread_t thread) {
apr_threadkey_private_set(thread, TM_THREAD_KEY);
}
-#else
+#else
#if defined(_WIN32) && defined(HYTHREAD_FAST_TLS)
-/**
- * Return the hythread_t for the current thread.
- *
- * @note Must be called only by an attached thread
- *
- * @return hythread_t for the current thread
- *
- * @see hythread_attach
- *
- */
+
hythread_t hythread_self_slow() {
return hythread_self();
}
-static void thread_set_self(hythread_t thread) {
- // tm_self_tls = thread;
+static void thread_set_self(hythread_t thread) {
#ifndef _WIN64
# if (_MSC_VER >= 1400)
__writefsdword(offsetof(NT_TIB, ArbitraryUserPointer), thread);
@@ -396,17 +376,9 @@ #else
__writegsqword(offsetof(NT_TIB, ArbitraryUserPointer), thread);
#endif
}
-#else
-/**
- * Return the hythread_t for the current thread.
- *
- * @note Must be called only by an attached thread
- *
- * @return hythread_t for the current thread
- *
- * @see hythread_attach
- *
- */
+
+#else // defined(_WIN32) && defined(HYTHREAD_FAST_TLS)
+
hythread_t hythread_self_slow() {
return hythread_self();
}
@@ -414,21 +386,21 @@ hythread_t hythread_self_slow() {
static void thread_set_self(hythread_t thread) {
tm_self_tls = thread;
}
-#endif
-#endif
+#endif // defined(_WIN32) && defined(HYTHREAD_FAST_TLS)
+#endif // defined APR_TLS_USE
IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable) {
IDATA status;
-
+
hythread_t thread = tm_self_tls;
-
+
if (nanos == 0 && millis == 0) {
hythread_yield();
return TM_ERROR_NONE;
- }
+ }
// Report error in case current thread is not attached
if (!thread) return TM_ERROR_UNATTACHED_THREAD;
-
+
hymutex_lock(&thread->mutex);
thread->state |= TM_THREAD_STATE_SLEEPING;
status = condvar_wait_impl(&thread->condition, &thread->mutex, millis, nanos, interruptable);
@@ -438,24 +410,24 @@ IDATA thread_sleep_impl(I_64 millis, IDA
return (status == TM_ERROR_INTERRUPT && interruptable) ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
}
-/**
- * Suspend the current thread from executing
+/**
+ * Suspend the current thread from executing
* for at least the specified time.
*
* @param[in] millis
- * @param[in] nanos
+ * @param[in] nanos
* @return 0 on success
* HYTHREAD_INVALID_ARGUMENT if the arguments are invalid
* HYTHREAD_INTERRUPTED if the sleep was interrupted
*
* @see hythread_sleep
*/
-IDATA VMCALL hythread_sleep_interruptable(I_64 millis, IDATA nanos) {
+IDATA VMCALL hythread_sleep_interruptable(I_64 millis, IDATA nanos) {
return thread_sleep_impl(millis, nanos, WAIT_INTERRUPTABLE);
}
-/**
- * Suspend the current thread from executing
+/**
+ * Suspend the current thread from executing
* for at least the specified time.
*
* @param[in] millis minimum number of milliseconds to sleep
@@ -469,7 +441,7 @@ IDATA VMCALL hythread_sleep(I_64 millis)
/**
* Returns the id of the specific thread.
- *
+ *
* @return 0 on success
*/
IDATA VMCALL hythread_get_id(hythread_t t) {
@@ -492,7 +464,7 @@ hythread_t VMCALL hythread_get_thread(ID
}
/**
- * Get thread group.
+ * Get thread group.
*
* @param[out] group hythread_group_t* pointer to group
* @param[in] thread hythread_t thread
@@ -503,23 +475,24 @@ IDATA VMCALL hythread_get_group(hythread
return TM_ERROR_NONE;
}
-/**
+/**
* Terminates a running thread.
- *
+ *
* @note This should only be used as a last resort. The system may be in
* an unpredictable state once a thread is cancelled. In addition, the thread
* may not even stop running if it refuses to cancel.
- *
- * @param[in] thread a thread to be terminated
+ *
+ * @param[in] thread a thread to be terminated
* @return none
*/
void VMCALL hythread_cancel(hythread_t thread) {
+ hythread_detach(thread);
os_thread_cancel(thread->os_handle);
}
-/**
+/**
* Terminates all running threads in the given group.
- *
+ *
* @param[in] group thread group
* @see hythread_cancel
*/
@@ -531,32 +504,20 @@ IDATA VMCALL hythread_cancel_all(hythrea
if (!group) {
group = TM_DEFAULT_GROUP;
}
-
+
iter = hythread_iterator_create(group);
while ((next = hythread_iterator_next (&iter)) != NULL) {
if (next != self) {
hythread_cancel(next);
//since this method being used at shutdown it does not
//make any sense to exit on error, but continue terminating threads
- }
+ }
}
+ hythread_iterator_release(&iter);
return TM_ERROR_NONE;
}
-/**
- * Allocates and initializes a new thread_t structure.
- *
- */
-IDATA VMCALL hythread_struct_init(hythread_t *ret_thread) {
- assert(ret_thread);
- if (*ret_thread) {
- reset_thread(*ret_thread);
- return TM_ERROR_NONE;
- }
- (*ret_thread) = allocate_thread();
- return (*ret_thread) == NULL ? TM_ERROR_OUT_OF_MEMORY : TM_ERROR_NONE;
-}
//==============================================================================
// Private functions
@@ -569,7 +530,7 @@ static IDATA register_to_group(hythread_
assert(thread);
assert(group);
-
+
// Acquire global TM lock to prevent concurrent access to thread list
status = hythread_global_lock(NULL);
assert(status == 0);
@@ -580,18 +541,18 @@ static IDATA register_to_group(hythread_
assert(thread == tm_self_tls);
thread->state |= TM_THREAD_STATE_ALIVE | TM_THREAD_STATE_RUNNABLE;
-
+
if (!thread->thread_id) {
U_32 i;
for(i = 0; i < MAX_ID; i++) {
- // increase next_id to allow thread_id change
+ // increase next_id to allow thread_id change
next_id++;
if (next_id == MAX_ID) {
- next_id = 1;
+ next_id = 1;
}
if (fast_thread_array[next_id] == NULL) {
thread->thread_id = next_id;
- free_slot_found = 1;
+ free_slot_found = 1;
break;
}
}
@@ -612,71 +573,52 @@ static IDATA register_to_group(hythread_
thread->next = cur;
thread->prev = prev;
prev->next = cur->prev = thread;
- return hythread_global_unlock(NULL);
+ return hythread_global_unlock(NULL);
}
-/*
- * Allocates and initializes a new thread_t structure
- *
- * @return created and initialized thread_t structure
+/**
+ * Initializes a new thread structure.
*/
-static hythread_t allocate_thread() {
- hythread_t ptr;
+IDATA VMCALL hythread_struct_init(hythread_t new_thread)
+{
IDATA status;
- ptr = (hythread_t )calloc(1, sizeof(HyThread));
- if (ptr == NULL) return NULL;
-
- ptr->os_handle = (osthread_t)NULL;
- ptr->priority = HYTHREAD_PRIORITY_NORMAL;
- ptr->stacksize = os_get_foreign_thread_stack_size();
-
- // Suspension
- ptr->request = 0;
- ptr->suspend_count = 0;
- ptr->disable_count = 0;
- status = hylatch_create(&ptr->join_event, 1);
- assert(status == TM_ERROR_NONE);
- status = hysem_create(&ptr->resume_event, 0, 1);
- assert(status == TM_ERROR_NONE);
- status = hymutex_create(&ptr->mutex, TM_MUTEX_NESTED);
- assert(status == TM_ERROR_NONE);
- status = hycond_create(&ptr->condition);
- assert(status == TM_ERROR_NONE);
-
- ptr->state = TM_THREAD_STATE_ALLOCATED;
- return ptr;
-}
-
-static void reset_thread(hythread_t thread) {
- IDATA UNREF status;
- if (thread->os_handle) {
- int UNREF res = os_thread_join(thread->os_handle);
- assert(!res);
+ assert(new_thread);
+ if (!new_thread->stacksize) {
+ // Create thread primitives
+ status = hylatch_create(&new_thread->join_event, 1);
+ assert(status == TM_ERROR_NONE);
+ status = hysem_create(&new_thread->resume_event, 0, 1);
+ assert(status == TM_ERROR_NONE);
+ status = hymutex_create(&new_thread->mutex, TM_MUTEX_NESTED);
+ assert(status == TM_ERROR_NONE);
+ status = hycond_create(&new_thread->condition);
+ assert(status == TM_ERROR_NONE);
+ new_thread->stacksize = os_get_foreign_thread_stack_size();
}
- hymutex_lock(&thread->mutex);
-
- thread->os_handle = (osthread_t)NULL;
- thread->priority = HYTHREAD_PRIORITY_NORMAL;
+ new_thread->os_handle = (osthread_t)NULL;
+ new_thread->priority = HYTHREAD_PRIORITY_NORMAL;
- // Suspension
- thread->request = 0;
- thread->suspend_count = 0;
- thread->disable_count = 0;
- thread->safepoint_callback = NULL;
- thread->state = TM_THREAD_STATE_ALLOCATED;
+ // Suspension reset
+ new_thread->request = 0;
+ new_thread->suspend_count = 0;
+ new_thread->disable_count = 0;
+ new_thread->safepoint_callback = NULL;
- hymutex_unlock(&thread->mutex);
+ hymutex_lock(&new_thread->mutex);
+ new_thread->state = TM_THREAD_STATE_ALLOCATED;
+ hymutex_unlock(&new_thread->mutex);
- status = hylatch_set(thread->join_event, 1);
+ status = hylatch_set(new_thread->join_event, 1);
assert(status == TM_ERROR_NONE);
- status = hysem_set(thread->resume_event, 0);
+ status = hysem_set(new_thread->resume_event, 0);
assert(status == TM_ERROR_NONE);
-
+
+ return TM_ERROR_NONE;
}
-// Wrapper around user thread start proc. Used to perform some duty jobs
+// Wrapper around user thread start proc. Used to perform some duty jobs
// right after thread is started.
//////
static int VMAPICALL thread_start_proc(void *arg) {
@@ -686,7 +628,7 @@ static int VMAPICALL thread_start_proc(v
hythread_entrypoint_t start_proc;
hythread_group_t group;
void *data;
-
+
start_proc_data = (thread_start_proc_data *) arg;
thread = start_proc_data->thread;
start_proc = start_proc_data->start_proc;
@@ -712,7 +654,7 @@ static int VMAPICALL thread_start_proc(v
// Shutdown sequence.
status = hythread_global_lock(NULL);
assert(status == TM_ERROR_NONE);
- assert(hythread_is_suspend_enabled());
+ assert(hythread_is_suspend_enabled());
thread->state = TM_THREAD_STATE_TERMINATED | (TM_THREAD_STATE_INTERRUPTED & thread->state);
hythread_detach(thread);
@@ -720,19 +662,19 @@ static int VMAPICALL thread_start_proc(v
hylatch_count_down(thread->join_event);
status = hythread_global_unlock(NULL);
- assert(status == TM_ERROR_NONE);
-
+ assert(status == TM_ERROR_NONE);
+
return 0;
}
-extern HY_CFUNC void VMCALL
- hythread_exit (hythread_monitor_t monitor) {
-
+extern HY_CFUNC void VMCALL
+hythread_exit (hythread_monitor_t monitor) {
+
if (monitor !=NULL && monitor->owner == hythread_self()) {
monitor->recursion_count = 0;
hythread_monitor_exit(monitor);
}
-
+ hythread_detach(NULL);
os_thread_exit(0);
// unreachable statement
abort();
@@ -891,3 +833,9 @@ IDATA VMCALL hythread_decrease_nondaemon
status = hymutex_unlock(&lib->TM_LOCK);
return status;
} // hythread_countdown_nondaemon_threads
+
+IDATA VMCALL hythread_get_struct_size()
+{
+ return (IDATA)sizeof(HyThread);
+} // hythread_get_struct_size
+
diff --git a/vm/thread/src/thread_native_fat_monitor.c b/vm/thread/src/thread_native_fat_monitor.c
index f4a282c..45bda8d 100644
--- a/vm/thread/src/thread_native_fat_monitor.c
+++ b/vm/thread/src/thread_native_fat_monitor.c
@@ -51,14 +51,16 @@ IDATA VMCALL hythread_monitor_init_with_
return TM_ERROR_OUT_OF_MEMORY;
}
r = hymutex_create(&mon->mutex, TM_MUTEX_NESTED);
- if (r) goto cleanup;
+ if (r) {
+ goto cleanup;
+ }
r = hycond_create(&mon->condition);
- if (r) goto cleanup;
+ if (r) {
+ goto cleanup;
+ }
mon->flags = flags;
mon->name = name;
- mon->owner = 0;
- mon->notify_flag = 0;
*mon_ptr = mon;
return TM_ERROR_NONE;
@@ -165,10 +167,6 @@ IDATA monitor_wait_impl(hythread_monitor
return TM_ERROR_ILLEGAL_STATE;
}
-#ifdef _DEBUG
- mon_ptr->last_wait=tm_self_tls;
-#endif
-
saved_recursion = mon_ptr->recursion_count;
assert(saved_recursion>=0);
@@ -184,12 +182,15 @@ #endif
do {
apr_time_t start;
- assert(0 <= mon_ptr->notify_flag && mon_ptr->notify_flag < mon_ptr->wait_count);
+ assert(mon_ptr->notify_count >= 0);
+ assert(mon_ptr->notify_count < mon_ptr->wait_count);
start = apr_time_now();
status = condvar_wait_impl(&mon_ptr->condition, &mon_ptr->mutex, ms, nano, interruptable);
if (status != TM_ERROR_NONE
- || mon_ptr->notify_flag || hythread_interrupted(self))
+ || mon_ptr->notify_count || hythread_interrupted(self))
+ {
break;
+ }
// we should not change ms and nano if both are 0 (meaning "no timeout")
if (ms || nano) {
apr_interval_time_t elapsed;
@@ -209,14 +210,23 @@ #endif
assert(0 <= nano && nano < 1000000);
}
} while (1);
- if (mon_ptr->notify_flag)
- mon_ptr->notify_flag -= 1;
+
+ // consume the notify_count unless we got an error
+ // or were interrupted
+ if (mon_ptr->notify_count > 0
+ && ((status == TM_ERROR_NONE && !hythread_interrupted(self))
+ || mon_ptr->notify_count == mon_ptr->wait_count))
+ {
+ mon_ptr->notify_count--;
+ }
+
hymutex_lock(&self->mutex);
self->state &= ~TM_THREAD_STATE_IN_MONITOR_WAIT;
self->current_condition = NULL;
self->waited_monitor = NULL;
hymutex_unlock(&self->mutex);
mon_ptr->wait_count--;
+ assert(mon_ptr->notify_count <= mon_ptr->wait_count);
if (self->request) {
int save_count;
@@ -326,7 +336,7 @@ IDATA VMCALL hythread_monitor_notify_all
if (mon_ptr->owner != tm_self_tls) {
return TM_ERROR_ILLEGAL_STATE;
}
- mon_ptr->notify_flag = mon_ptr->wait_count;
+ mon_ptr->notify_count = mon_ptr->wait_count;
return hycond_notify_all(&mon_ptr->condition);
}
@@ -372,8 +382,8 @@ IDATA VMCALL hythread_monitor_notify(hyt
if (mon_ptr->owner != tm_self_tls) {
return TM_ERROR_ILLEGAL_STATE;
}
- if (mon_ptr->notify_flag < mon_ptr->wait_count)
- mon_ptr->notify_flag += 1;
+ if (mon_ptr->notify_count < mon_ptr->wait_count)
+ mon_ptr->notify_count += 1;
return hycond_notify(&mon_ptr->condition);
}
diff --git a/vm/thread/src/thread_native_interrupt.c b/vm/thread/src/thread_native_interrupt.c
index 6641b6f..5b3f219 100644
--- a/vm/thread/src/thread_native_interrupt.c
+++ b/vm/thread/src/thread_native_interrupt.c
@@ -37,7 +37,6 @@ static IDATA HYTHREAD_PROC interrupter_t
*/
void VMCALL hythread_interrupt(hythread_t thread) {
IDATA status;
- hythread_t thr = NULL;
hymutex_lock(&thread->mutex);
thread->state |= TM_THREAD_STATE_INTERRUPTED;
@@ -49,19 +48,20 @@ void VMCALL hythread_interrupt(hythread_
// If thread was doing any kind of wait, notify it.
if (thread->state & (TM_THREAD_STATE_PARKED | TM_THREAD_STATE_SLEEPING)) {
if (thread->current_condition) {
- status = hycond_notify_all(thread->current_condition);
- assert(status == TM_ERROR_NONE);
- }
+ status = hycond_notify_all(thread->current_condition);
+ assert(status == TM_ERROR_NONE);
+ }
} else if (thread->state & TM_THREAD_STATE_IN_MONITOR_WAIT) {
if (thread->current_condition && (hythread_monitor_try_enter(thread->waited_monitor) == TM_ERROR_NONE)) {
hythread_monitor_interrupt_wait(thread->waited_monitor, thread);
hythread_monitor_exit(thread->waited_monitor);
} else {
- status = hythread_create(&thr, 0, 0, 0, interrupter_thread_function, (void *)thread);
+ hythread_t interrupt_thread = (hythread_t)calloc(1, hythread_get_struct_size());
+ status = hythread_create_with_group(interrupt_thread, 0, 0, 0,
+ interrupter_thread_function, (void *)thread);
assert (status == TM_ERROR_NONE);
- }
+ }
}
-
hymutex_unlock(&thread->mutex);
}
@@ -81,7 +81,7 @@ static IDATA HYTHREAD_PROC interrupter_t
hymutex_unlock(&thread->mutex);
hythread_monitor_enter(monitor);
- hythread_monitor_notify_all(monitor);
+ hythread_monitor_interrupt_wait(monitor, thread);
hythread_exit(monitor);
return 0;
diff --git a/vm/thread/src/thread_native_iterator.c b/vm/thread/src/thread_native_iterator.c
index 38d2660..bbdda5b 100644
--- a/vm/thread/src/thread_native_iterator.c
+++ b/vm/thread/src/thread_native_iterator.c
@@ -28,7 +28,8 @@ #include
/**
- * Creates the iterator that can be used to retrieve all threads in the specific group.
+ * Creates the iterator that can be used to retrieve all threads in the specific group
+ * and acquires the thread lock.
*
* @param[in] group thread group number
*/
@@ -42,7 +43,8 @@ hythread_iterator_t VMCALL hythread_iter
}
/**
- * Releases the iterator over the specific thread group.
+ * Releases the iterator over the specific thread group and releases the thread
+ * lock.
*
* @param[in] it thread group iterator
*/
diff --git a/vm/thread/src/thread_native_thin_monitor.c b/vm/thread/src/thread_native_thin_monitor.c
index fcc4273..8cf328d 100644
--- a/vm/thread/src/thread_native_thin_monitor.c
+++ b/vm/thread/src/thread_native_thin_monitor.c
@@ -125,7 +125,6 @@ int unreserve_count=0;
int inflate_contended=0;
int inflate_waited=0;
int unreserve_count_self=0;
-int inflate_count=0;
int fat_lock2_count = 0;
int init_reserve_cout = 0;
int cas_cout = 0;
@@ -622,7 +621,6 @@ hythread_monitor_t VMCALL hythread_infla
// however this invariant is true because we hold monitor->mutex during this function
// so it cannot be called twice for the signle monitor concurrently
- TRACE(("inflate tmj%d\n", ++inflate_count));
lockword = *lockword_ptr;
if (IS_FAT_LOCK (lockword)) {
return locktable_get_fat_monitor(FAT_LOCK_ID(lockword));
@@ -657,8 +655,6 @@ #endif
TRACE(("hythread_inflate_lock %d thread: %d\n", FAT_LOCK_ID(*lockword_ptr), tm_self_tls->thread_id));
//assert(FAT_LOCK_ID(*lockword_ptr) != 2);
TRACE(("FAT ID : 0x%x", *lockword_ptr));
- fat_monitor->inflate_count++;
- fat_monitor->inflate_owner=tm_self_tls;
#ifdef LOCK_RESERVATION
assert(!IS_RESERVED(*lockword_ptr));
#endif
diff --git a/vm/thread/src/thread_private.h b/vm/thread/src/thread_private.h
index 3d6b8d3..cb44ba0 100644
--- a/vm/thread/src/thread_private.h
+++ b/vm/thread/src/thread_private.h
@@ -46,7 +46,7 @@ #define TRACE(a) //printf a; printf("\n"
#define DIE(A) //exit(55);
#endif
-// FIXME move to the global header, add error converter
+// FIXME move to the global header, add error converter
#define RET_ON_ERROR(stat) if (stat) { return -1; }
#define CONVERT_ERROR(stat) (stat)
@@ -151,12 +151,12 @@ #endif
int16 disable_count;
/**
- * Group for this thread. Different groups are needed in order
+ * Group for this thread. Different groups are needed in order
* to be able to quickly iterate over the specific group.
* Examples are: Java threads, GC private threads.
* Equal to the address of the head of the list of threads for this group.
*/
- hythread_group_t group;
+ hythread_group_t group;
/**
* Array representing thread local storage
@@ -171,8 +171,8 @@ #endif
*/
HyThreadLibrary * library;
-// Suspension
-
+// Suspension
+
/**
* Number of suspend requests made for this thread.
* The field is modified by atomic operations.
@@ -181,7 +181,7 @@ #endif
* should be incremented/decremented too.
*/
uint32 suspend_count;
-
+
/**
* Function to be executed at safepoint upon thread resume.
*
@@ -199,22 +199,21 @@ #endif
hysem_t resume_event;
// Basic manipulation fields
-
+
/**
* Points to the next thread within the group.
- */
+ */
hythread_t next;
/**
* Points to the last thread within the group.
*/
hythread_t prev;
-
+
/**
* Handle to OS thread.
*/
osthread_t os_handle;
-
// Synchronization stuff
@@ -232,7 +231,7 @@ #endif
* Event reserved for threads that invoke join.
*/
hylatch_t join_event;
-
+
/**
* Current conditional variable thread is waiting on (used for interrupting)
*/
@@ -242,7 +241,7 @@ #endif
/**
* Thread state. Holds thread state flags as defined in JVMTI specification, plus some additional
- * flags. See
+ * flags. See
* JVMTI Specification for more details.
*/
IDATA state;
@@ -253,7 +252,7 @@ #endif
/**
* Hint for scheduler about thread priority
*/
- IDATA priority;
+ IDATA priority;
/**
* Size of thread's stack, set on creation
@@ -262,7 +261,7 @@ #endif
UDATA stacksize;
// Monitors
-
+
/**
* Monitor this thread is waiting on now.
*/
@@ -275,24 +274,24 @@ #endif
} HyThread;
-/**
+/**
* hythread_group_t pointer to the first element in the thread group
*/
typedef struct HyThreadGroup {
-
+
/**
- * Pointer to the first thread in the list of threads
+ * Pointer to the first thread in the list of threads
* contained in this group
*/
hythread_t thread_list;
/**
- * Pointer to the first thread in the list of threads
+ * Pointer to the first thread in the list of threads
* contained in this group
*/
hythread_t thread_list_tail;
-
+
/**
* Number of threads in this group
*/
@@ -302,7 +301,7 @@ typedef struct HyThreadGroup {
* Group index or key for search purposes
*/
int group_index;
-
+
/**
* Memory pool to place created threads into.
*/
@@ -327,31 +326,28 @@ typedef struct HyThreadGroup {
* A simple combination of conditional variable and fat lock.
*/
typedef struct HyThreadMonitor {
-
- /**
- * Mutex
- */
+
+ /// Monitor mutex.
hymutex_t mutex;
- /**
- * Condition variable
- */
+ /// Monitor condition varibale.
hycond_t condition;
-
- /**
- * Recursion count
- */
+
+ /// Mutex recurtion count.
IDATA recursion_count;
- hythread_t owner;
- hythread_t inflate_owner;
- hythread_t last_wait;
- int inflate_count;
+
+ /// Current mutex owner.
+ hythread_t owner;
+
+ /// Number of threads waiting on a condition variable
+ /// or queued to acquire a monitor mutex after wakeup
int wait_count;
- int notify_flag;
- /**
- * Owner thread ID.
- */
+ /// Number of notify events sent by the user,
+ /// it is bounded by the wait_count
+ int notify_count;
+
+ /// Owner thread ID.
IDATA thread_id;
UDATA flags;
@@ -364,7 +360,7 @@ typedef struct HyThreadMonitor {
* Count down latch
*/
typedef struct HyLatch {
-
+
/**
* Latch count
*/
@@ -373,18 +369,18 @@ typedef struct HyLatch {
/**
* Condition event used to signal threads which are waiting on the latch.
*/
- hycond_t condition;
-
+ hycond_t condition;
+
/**
* Mutex associated with the latch data.
*/
- hymutex_t mutex;
+ hymutex_t mutex;
/**
* latch sub pool
* will be destroyed by latch_destroy()
*/
- apr_pool_t *pool;
-
+ apr_pool_t *pool;
+
} HyLatch;
@@ -392,7 +388,7 @@ typedef struct HyLatch {
* Semaphore
*/
typedef struct HySemaphore {
-
+
/**
* Semaphore count
*/
@@ -406,56 +402,56 @@ typedef struct HySemaphore {
/**
* Condition event used to signal threads which are waiting on the semaphore.
*/
- hycond_t condition;
-
+ hycond_t condition;
+
/**
* Mutex associated with the semaphore data.
*/
- hymutex_t mutex;
+ hymutex_t mutex;
} HySemaphore;
-
+
/*
- * Lock table which holds the mapping between LockID and fat lock
+ * Lock table which holds the mapping between LockID and fat lock
* (OS fat_monitor) pointer.
*/
-typedef enum hythread_locktable_state {
- HYTHREAD_LOCKTABLE_IDLE,
- HYTHREAD_LOCKTABLE_READING,
- HYTHREAD_LOCKTABLE_WRITING
+typedef enum hythread_locktable_state {
+ HYTHREAD_LOCKTABLE_IDLE,
+ HYTHREAD_LOCKTABLE_READING,
+ HYTHREAD_LOCKTABLE_WRITING
} hythread_locktable_state_t;
-
+
typedef struct HyFatLockTable {
// locktable itself
hythread_monitor_t* tables[HY_MAX_FAT_TABLES];
-
+
// mutex guarding locktable
hymutex_t mutex;
hycond_t read;
hycond_t write;
-
+
int readers_reading;
int readers_waiting;
int writers_waiting;
-
+
hythread_locktable_state_t state;
-
+
U_32 read_count;
-
+
// table of live objects (updated during each major GC)
unsigned char *live_objs;
-
+
// size of locktable
U_32 size;
// used to scan the lock table for the next available entry
U_32 array_cursor;
-
+
} HyFatLockTable;
-// Global variables
+// Global variables
extern hythread_group_t group_list; // list of thread groups
extern IDATA groups_count; // number of thread groups
@@ -486,7 +482,7 @@ hythread_group_t get_java_thread_group(
/**
* Thread cancellation, being used at VM shutdown through
- * tmj_cancel_all_threads() method call to terminate all java
+ * tmj_cancel_all_threads() method call to terminate all java
* threads at shutdown.
*/
@@ -510,7 +506,6 @@ int os_thread_create(osthread_t* phandle
int os_thread_set_priority(osthread_t thread, int priority);
osthread_t os_thread_current();
int os_thread_cancel(osthread_t);
-int os_thread_join(osthread_t);
void os_thread_exit(IDATA status);
void os_thread_yield_other(osthread_t);
int os_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser);
diff --git a/vm/vmcore/src/init/finalizer_thread.cpp b/vm/vmcore/src/init/finalizer_thread.cpp
index 0f129e5..4da68c8 100644
--- a/vm/vmcore/src/init/finalizer_thread.cpp
+++ b/vm/vmcore/src/init/finalizer_thread.cpp
@@ -109,8 +109,9 @@ void finalizer_threads_init(JavaVM *java
void **args = (void **)STD_MALLOC(sizeof(void *) * 2);
args[0] = (void*)java_vm;
args[1] = (void*)get_system_thread_group(jni_env);
- fin_thread_info->thread_ids[i] = NULL;
- status = hythread_create(&fin_thread_info->thread_ids[i], 0, FINALIZER_THREAD_PRIORITY, 0, (hythread_entrypoint_t)finalizer_thread_func, args);
+ fin_thread_info->thread_ids[i] = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ status = hythread_create_with_group(fin_thread_info->thread_ids[i], NULL, 0,
+ FINALIZER_THREAD_PRIORITY, (hythread_entrypoint_t)finalizer_thread_func, args);
assert(status == TM_ERROR_NONE);
hysem_wait(fin_thread_info->attached_sem);
}
diff --git a/vm/vmcore/src/init/ref_enqueue_thread.cpp b/vm/vmcore/src/init/ref_enqueue_thread.cpp
index c9eb033..39ba8af 100644
--- a/vm/vmcore/src/init/ref_enqueue_thread.cpp
+++ b/vm/vmcore/src/init/ref_enqueue_thread.cpp
@@ -65,7 +65,9 @@ void ref_enqueue_thread_init(JavaVM *jav
void **args = (void **)STD_MALLOC(sizeof(void *)*2);
args[0] = (void *)java_vm;
args[1] = (void*)get_system_thread_group(jni_env);
- status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args);
+ hythread_t thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ status = hythread_create_with_group(thread, NULL, 0, REF_ENQUEUE_THREAD_PRIORITY,
+ (hythread_entrypoint_t)ref_enqueue_thread_func, args);
assert(status == TM_ERROR_NONE);
hysem_wait(ref_thread_info->attached_sem);
diff --git a/vm/vmcore/src/init/vm_init.cpp b/vm/vmcore/src/init/vm_init.cpp
index 898244b..a0c9c7c 100644
--- a/vm/vmcore/src/init/vm_init.cpp
+++ b/vm/vmcore/src/init/vm_init.cpp
@@ -598,14 +598,17 @@ jint vm_attach_internal(JNIEnv ** p_jni_
native_thread = hythread_self();
if (!native_thread) {
- status = (jint)hythread_attach_to_group(&native_thread,
- ((JavaVM_Internal *)java_vm)->vm_env->hythread_lib, NULL);
- if (status != TM_ERROR_NONE) return JNI_ERR;
+ hythread_t native_thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(native_thread);
+ IDATA hy_status = hythread_attach_to_group(native_thread, NULL, NULL);
+ if (hy_status != TM_ERROR_NONE)
+ return JNI_ERR;
}
assert(native_thread);
status = vm_attach(java_vm, &jni_env);
- if (status != JNI_OK) return status;
+ if (status != JNI_OK)
+ return status;
*p_jni_env = jni_env;
@@ -630,7 +633,9 @@ int vm_init1(JavaVM_Internal * java_vm,
vm_env = java_vm->vm_env;
- if (hythread_attach_ex(NULL, vm_env->hythread_lib) != TM_ERROR_NONE) {
+ hythread_t main_thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(main_thread);
+ if (hythread_attach_to_group(main_thread, NULL, NULL) != TM_ERROR_NONE) {
return JNI_ERR;
}
diff --git a/vm/vmcore/src/init/vm_shutdown.cpp b/vm/vmcore/src/init/vm_shutdown.cpp
index c4f353b..4f0a744 100644
--- a/vm/vmcore/src/init/vm_shutdown.cpp
+++ b/vm/vmcore/src/init/vm_shutdown.cpp
@@ -309,28 +309,36 @@ void vm_interrupt_handler(int UNREF x) {
status = JNI_GetCreatedJavaVMs(NULL, 0, &nVMs);
assert(nVMs <= 1);
- if (status != JNI_OK) return;
+ if (status != JNI_OK)
+ return;
vmBuf = (JavaVM **) STD_MALLOC(nVMs * sizeof(JavaVM *));
status = JNI_GetCreatedJavaVMs(vmBuf, nVMs, &nVMs);
assert(nVMs <= 1);
- if (status != JNI_OK) goto cleanup;
-
- status = hythread_attach(NULL);
- if (status != TM_ERROR_NONE) goto cleanup;
-
+ if (status != JNI_OK)
+ goto cleanup;
threadBuf = (hythread_t *) STD_MALLOC((nVMs + 1) * sizeof(hythread_t));
- threadBuf[nVMs] = NULL;
+ assert(threadBuf);
// Create a new thread for each VM to avoid scalability and deadlock problems.
for (int i = 0; i < nVMs; i++) {
- threadBuf[i] = NULL;
- hythread_create((threadBuf + i), 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_interrupt_entry_point, (void *)vmBuf[i]);
+ threadBuf[i] = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(threadBuf[i]);
+ status = hythread_create_with_group(threadBuf[i], NULL, 0,
+ HYTHREAD_PRIORITY_NORMAL, vm_interrupt_entry_point, (void *)vmBuf[i]);
+ assert(status == TM_ERROR_NONE);
}
// spawn a new thread which will terminate the process.
- hythread_create(NULL, 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_interrupt_process, (void *)threadBuf);
+ threadBuf[nVMs] = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(threadBuf[nVMs]);
+ status = hythread_create_with_group(threadBuf[nVMs], NULL, 0,
+ HYTHREAD_PRIORITY_NORMAL, vm_interrupt_process, (void *)threadBuf);
+ assert(status == TM_ERROR_NONE);
+
+ // set a NULL terminator
+ threadBuf[nVMs] = NULL;
cleanup:
STD_FREE(vmBuf);
@@ -347,21 +355,22 @@ void vm_dump_handler(int UNREF x) {
status = JNI_GetCreatedJavaVMs(NULL, 0, &nVMs);
assert(nVMs <= 1);
- if (status != JNI_OK) return;
+ if (status != JNI_OK)
+ return;
vmBuf = (JavaVM **) STD_MALLOC(nVMs * sizeof(JavaVM *));
status = JNI_GetCreatedJavaVMs(vmBuf, nVMs, &nVMs);
assert(nVMs <= 1);
-
- IDATA htstatus;
- if (status != JNI_OK) goto cleanup;
-
- htstatus = hythread_attach(NULL);
- if (htstatus != TM_ERROR_NONE) goto cleanup;
+ if (status != JNI_OK)
+ goto cleanup;
// Create a new thread for each VM to avoid scalability and deadlock problems.
for (int i = 0; i < nVMs; i++) {
- hythread_create(NULL, 0, HYTHREAD_PRIORITY_NORMAL, 0, vm_dump_entry_point, (void *)vmBuf[i]);
+ hythread_t thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(thread);
+ IDATA hy_status = hythread_create_with_group(thread, NULL, 0,
+ HYTHREAD_PRIORITY_NORMAL, vm_dump_entry_point, (void *)vmBuf[i]);
+ assert(hy_status == TM_ERROR_NONE);
}
cleanup:
diff --git a/vm/vmcore/src/jvmti/jvmti_event.cpp b/vm/vmcore/src/jvmti/jvmti_event.cpp
index 78b4554..060b614 100644
--- a/vm/vmcore/src/jvmti/jvmti_event.cpp
+++ b/vm/vmcore/src/jvmti/jvmti_event.cpp
@@ -2313,7 +2313,9 @@ jvmti_create_event_thread()
// create TI event thread
JNIEnv *jni_env = p_TLS_vmthread->jni_env;
- IDATA status = hythread_create(&ti->event_thread, 0, 0, 0,
+ ti->event_thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(ti->event_thread);
+ IDATA status = hythread_create_with_group(ti->event_thread, NULL, 0, 0,
jvmti_event_thread_function, jni_env);
if( status != TM_ERROR_NONE ) {
DIE("jvmti_create_event_thread: creating thread is failed!");
diff --git a/vm/vmcore/src/thread/thread_java_basic.cpp b/vm/vmcore/src/thread/thread_java_basic.cpp
index b5ef29a..842304b 100644
--- a/vm/vmcore/src/thread/thread_java_basic.cpp
+++ b/vm/vmcore/src/thread/thread_java_basic.cpp
@@ -124,16 +124,7 @@ IDATA jthread_create_with_function(JNIEn
return TM_ERROR_NULL_POINTER;
}
hythread_t native_thread = vm_jthread_get_tm_data(java_thread);
-
- // This is for irregular use. In ordinary live valid jthread instance
- // contains weak reference associated with it and native thread to reuse.
- if (native_thread == NULL) {
- assert(0);
- if (!jthread_thread_init(jni_env, java_thread, NULL, 0)) {
- return TM_ERROR_OUT_OF_MEMORY;
- }
- native_thread = vm_jthread_get_tm_data(java_thread);
- }
+ assert(native_thread);
vm_thread_t vm_thread =
(vm_thread_t) hythread_tls_get(native_thread, TM_THREAD_VM_TLS_KEY);
@@ -164,9 +155,8 @@ IDATA jthread_create_with_function(JNIEn
attrs->stacksize = default_stacksize;
}
- status =
- hythread_create(&native_thread, attrs->stacksize,
- attrs->priority, 0, jthread_wrapper_proc, attrs);
+ status = hythread_create_with_group(native_thread, NULL, attrs->stacksize,
+ attrs->priority, jthread_wrapper_proc, attrs);
TRACE(("TM: Created thread: id=%d", hythread_get_id(native_thread)));
@@ -242,9 +232,12 @@ jlong jthread_thread_init(JNIEnv *env,
// delete used weak reference
env->DeleteGlobalRef(vm_thread->weak_ref);
}
+ } else {
+ native_thread = (hythread_t)STD_CALLOC(1, hythread_get_struct_size());
+ assert(native_thread);
}
- IDATA status = hythread_struct_init(&native_thread);
+ IDATA status = hythread_struct_init(native_thread);
if (status != TM_ERROR_NONE) {
return 0;
}
@@ -403,11 +396,31 @@ IDATA jthread_yield()
*/
static void stop_callback(void)
{
- vm_thread_t vm_thread = p_TLS_vmthread;
+ hythread_t native_thread = hythread_self();
+ assert(native_thread);
+ vm_thread_t vm_thread =
+ (vm_thread_t) hythread_tls_get(native_thread, TM_THREAD_VM_TLS_KEY);
assert(vm_thread);
jobject excn = vm_thread->stop_exception;
+ // Does not return if the exception could be thrown straight away
jthread_throw_exception_object(excn);
+
+ // getting here means top stack frame is non-unwindable.
+ if (hythread_get_state(native_thread) &
+ (TM_THREAD_STATE_SLEEPING | TM_THREAD_STATE_WAITING_WITH_TIMEOUT
+ | TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT
+ | TM_THREAD_STATE_WAITING_INDEFINITELY | TM_THREAD_STATE_PARKED))
+ {
+ // This is needed for correct stopping of a thread blocked on monitor_wait.
+ // The thread needs some flag to exit its waiting loop.
+ // We piggy-back on interrupted status. A correct exception from TLS
+ // will be thrown because the check of exception status on leaving
+ // JNI frame comes before checking return status in Object.wait().
+ // Interrupted status will be cleared by function returning TM_ERROR_INTERRUPT.
+ // (though, in case of parked thread, it will not be cleared)
+ hythread_interrupt(native_thread);
+ }
} // stop_callback
/**
diff --git a/vm/vmcore/src/thread/thread_manager.cpp b/vm/vmcore/src/thread/thread_manager.cpp
index bf1069b..eb86a1f 100644
--- a/vm/vmcore/src/thread/thread_manager.cpp
+++ b/vm/vmcore/src/thread/thread_manager.cpp
@@ -117,11 +117,10 @@ #ifdef _DEBUG
#endif // _DEBUG
// allocate VM thread
- vm_thread = (vm_thread_t)STD_MALLOC(sizeof(VM_thread));
+ vm_thread = (vm_thread_t)STD_CALLOC(1, sizeof(VM_thread));
if (!vm_thread) {
return NULL;
}
- memset(vm_thread, 0, sizeof(VM_thread));
// set VM thread to thread local storage
IDATA status =
diff --git a/vm/vmcore/src/thread/thread_private.h b/vm/vmcore/src/thread/thread_private.h
deleted file mode 100644
index 008a83b..0000000
--- a/vm/vmcore/src/thread/thread_private.h
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef THREAD_PRIVATE_H
-#define THREAD_PRIVATE_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include "apr_thread_ext.h"
-
-#ifdef __linux__
-#include
-#endif // __linux__
-
-// temporary remove logging
-//#define TRACE(a) //printf a; printf("\n")
-
-#ifdef __linux__
-#include "clog.h"
-#else
-#define TRACE(a) //printf a; printf("\n")
-#define DIE(A) //exit(55);
-#endif
-
-// FIXME move to the global header, add error converter
-#define RET_ON_ERROR(stat) if (stat) { return -1; }
-#define CONVERT_ERROR(stat) (stat)
-
-#define MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize
-#define FAST_LOCAL_STORAGE_SIZE 10
-
-#define INITIAL_FAT_TABLE_ENTRIES 16*1024 //make this table exapandible if workloads show it is necessary
-
-#define HY_DEFAULT_STACKSIZE 512 * 1024 // if default stack size is not through -Xss parameter, it is 256kb
-
-
-#if !defined (_IPF_)
-//use lock reservation
-#define LOCK_RESERVATION
-// spin with try_lock SPIN_COUNT times
-#define SPIN_COUNT 5
-
-#endif // !defined (_IPF_)
-
-#if defined(_WIN32) && !defined (_EM64T_)
-//use optimized asm monitor enter and exit helpers
-#define ASM_MONITOR_HELPER
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-
-#ifdef __linux__
-#define osthread_t pthread_t
-#elif _WIN32
-#define osthread_t HANDLE
-#else // !_WIN32 && !__linux__
-#error "threading is only supported on __linux__ or _WIN32"
-#endif // !_WIN32 && !__linux__
-
-
-extern hythread_group_t TM_DEFAULT_GROUP;
-/**
- * current capacity of the thread local storage
- */
-extern int16 tm_tls_capacity;
-
-/**
- * current capacity of the thread local storage
- */
-extern int16 tm_tls_size;
-
-
-typedef struct HyThreadLibrary {
- IDATA a;
- hymutex_t TM_LOCK;
- IDATA nondaemon_thread_count;
- hycond_t nondaemon_thread_cond;
-} HyThreadLibrary;
-
-/**
- * Native thread control structure.
- */
-typedef struct HyThread {
-
-#ifndef POSIX
- // This is dummy pointer for Microsoft Visual Studio debugging
- // If this is removed, Visual Studio, when attached to VM, will show
- // no symbolic information
- void* reserved;
-#endif
-
-// Public fields exported by HyThread_public. If you change these fields,
-// please, check fields in hythread.h/HyThread_public
-
- /**
- * Number of requests made for this thread, it includes both
- * suspend requests and safe point callback requests.
- * The field is modified by atomic operations.
- *
- * Increment in functions:
- * 1. send_suspend_request()
- * - sets suspend request for a given thread
- * 2. hythread_set_safepoint_callback()
- * - sets safe point callback request for a given thread
- *
- * Decrement in functions:
- * 1. hythread_resume()
- * - removes suspend request for a given thread
- * 2. hythread_exception_safe_point()
- * - removes safe point callback request for current thread
- */
- int32 request;
-
- /**
- * Field indicating that thread can safely be suspended.
- * Safe suspension is enabled on value 0.
- *
- * The disable_count is increased/decreaded in
- * hythread_suspend_disable()/hythread_suspend_enable() function
- * for current thread only.
- *
- * Also disable_count could be reset to value 0 and restored in
- * reset_suspend_disable()/set_suspend_disable() function
- * for current thread only.
- *
- * Function hythread_exception_safe_point() sets disable_count to
- * value 1 before safe point callback function calling and restores
- * it after the call.
- *
- * Function thread_safe_point_impl() sets disable_count to
- * value 0 before entering to the safe point and restores it
- * after exitting.
- */
- int16 disable_count;
-
-
- /**
- * Group for this thread. Different groups are needed in order
- * to be able to quickly iterate over the specific group.
- * Examples are: Java threads, GC private threads.
- * Equal to the address of the head of the list of threads for this group.
- */
- hythread_group_t group;
-
- /**
- * Array representing thread local storage
- */
- void *thread_local_storage[10];
-
-
-// Private fields
-
- /**
- * Each thread keeps a pointer to the library it belongs to.
- */
- HyThreadLibrary * library;
-
-// Suspension
-
- /**
- * Number of suspend requests made for this thread.
- * The field is modified by atomic operations.
- *
- * After increment/decrement of suspend_count, request field
- * should be incremented/decremented too.
- */
- int32 suspend_count;
-
-
- /**
- * Function to be executed at safepoint upon thread resume.
- *
- * Field is set in hythread_set_safepoint_callback() function
- * and reset hythread_exception_safe_point() function.
- *
- * After set/reset of safepoint_callback, request field
- * should be incremented/decremented too.
- */
- hythread_event_callback_proc safepoint_callback;
-
- /**
- * Event used to notify suspended thread that it needs to wake up.
- */
- hysem_t resume_event;
-
-// Basic manipulation fields
-
- /**
- * Points to the next thread within the group.
- */
- hythread_t next;
-
- /**
- * Points to the last thread within the group.
- */
- hythread_t prev;
-
- /**
- * Handle to OS thread.
- */
- osthread_t os_handle;
-
- /**
- * Placeholder for any data to be associated with this thread.
- * Java layer is using it to keep java-specific context.
- */
- void *private_data;
-
- /**
- * Flag indicating there was request to exit
- */
- Boolean exit_request;
-
- /**
- * Exit value of this thread
- */
- IDATA exit_value;
-
-
-// Synchronization stuff
-
- /*
- * Thread local lock, used to serialize thread state;
- */
- hymutex_t mutex;
-
- /*
- * Conditional variable used to implement wait function for sleep/park;
- */
- hycond_t condition;
-
- /**
- * Event reserved for threads that invoke join.
- */
- hylatch_t join_event;
-
- /**
- * Current conditional variable thread is waiting on (used for interrupting)
- */
- hycond_t *current_condition;
-
-// State
-
- /**
- * Thread state. Holds thread state flags as defined in JVMTI specification, plus some additional
- * flags. See
- * JVMTI Specification for more details.
- */
- IDATA state;
-
-
-// Attributes
-
- /**
- * name of the thread (useful for debugging purposes)
- */
- char* name;
-
- /**
- * Hint for scheduler about thread priority
- */
- IDATA priority;
-
- /**
- * Size of thread's stack, set on creation
- */
-
- UDATA stacksize;
-
-// Monitors
-
- /**
- * Monitor this thread is waiting on now.
- **/
- hythread_monitor_t waited_monitor;
-
- /**
- * ID for this thread. The maximum number of threads is governed by the size of lockword record.
- */
- IDATA thread_id;
-
- /**
- * APR thread attributes
- */
- apr_threadattr_t *apr_attrs;
-
- /**
- * Extension to the standard local storage slot.
- */
- void **big_local_storage;
-
-} HyThread;
-
-
-/**
- * Java-specific context that is attached to tm_thread control structure by Java layer
- */
-typedef struct JVMTIThread {
-
- /**
- * JNI env associated with this Java thread
- */
- JNIEnv *jenv;
-
- /**
- * jthread object which is associated with tm_thread
- */
- jthread thread_object;
-
- /**
- * Conditional variable which is used to wait/notify on java monitors.
- */
- hycond_t monitor_condition;
-
- /**
- * Exception that has to be thrown in stopped thread
- */
- jthrowable stop_exception;
-
- /**
- * Blocked on monitor times count
- */
- jlong blocked_count;
-
- /**
- * Blocked on monitor time in nanoseconds
- */
- jlong blocked_time;
-
- /**
- * Waited on monitor times count
- */
- jlong waited_count;
-
- /**
- * Waited on monitor time in nanoseconds
- */
- jlong waited_time;
-
- /**
- * JVM TI local storage
- */
- JVMTILocalStorage jvmti_local_storage;
-
- /**
- * Monitor this thread is blocked on.
- */
- jobject contended_monitor;
-
- /**
- * Monitor this thread waits on.
- */
- jobject wait_monitor;
-
- /**
- * Monitors for which this thread is owner.
- */
- jobject *owned_monitors;
-
- /**
- * owned monitors count.
- */
- int owned_monitors_nmb;
-
- /**
- * APR pool for this structure
- */
- apr_pool_t *pool;
-
- /**
- * weak reference to corresponding java.lang.Thread instance
- */
- jobject thread_ref;
-
- /**
- * Is this thread daemon?
- */
- IDATA daemon;
-
-} JVMTIThread;
-
-
-
-/**
- * hythread_group_t pointer to the first element in the thread group
- */
-typedef struct HyThreadGroup {
-
- /**
- * Pointer to the first thread in the list of threads
- * contained in this group
- */
- hythread_t thread_list;
-
-
- /**
- * Pointer to the first thread in the list of threads
- * contained in this group
- */
- hythread_t thread_list_tail;
-
- /**
- * Number of threads in this group
- */
- int threads_count;
-
- /**
- * Group index or key for search purposes
- */
- int group_index;
-
- /**
- * Memory pool to place created threads into.
- */
- apr_pool_t* pool;
-
- /**
- *
- */
- hythread_group_t next;
-
- /**
- *
- */
- hythread_group_t prev;
-
-} HyThreadGroup;
-
-
-/**
- * Fat monitor structure.
- *
- * A simple combination of conditional variable and fat lock.
- */
-typedef struct HyThreadMonitor {
-
- /**
- * Mutex
- */
- hymutex_t mutex;
-
- /**
- * Condition variable
- */
- hycond_t condition;
-
- /**
- * Recursion count
- */
- IDATA recursion_count;
- hythread_t owner;
- hythread_t inflate_owner;
- hythread_t last_wait;
- int inflate_count;
- int wait_count;
- int notify_flag;
-
- /**
- * Owner thread ID.
- */
- IDATA thread_id;
-
- UDATA flags;
-
- char *name;
-
-} HyThreadMonitor;
-
-/**
- * Count down latch
- */
-typedef struct HyLatch {
-
- /**
- * Latch count
- */
- int count;
-
- /**
- * Condition event used to signal threads which are waiting on the latch.
- */
- hycond_t condition;
-
- /**
- * Mutex associated with the latch data.
- */
- hymutex_t mutex;
- /**
- * latch sub pool
- * will be destroyed by latch_destroy()
- */
- apr_pool_t *pool;
-
-} HyLatch;
-
-
-/**
- * Semaphore
- */
-typedef struct HySemaphore {
-
- /**
- * Semaphore count
- */
- int count;
-
- /**
- * Semaphore max count
- */
- int max_count;
-
- /**
- * Condition event used to signal threads which are waiting on the semaphore.
- */
- hycond_t condition;
-
- /**
- * Mutex associated with the semaphore data.
- */
- hymutex_t mutex;
-} HySemaphore;
-
-
-/*
- * Lock table which holds the mapping between LockID and fat lock
- * (OS fat_monitor) pointer.
- */
-
-typedef enum hythread_locktable_state {
- HYTHREAD_LOCKTABLE_IDLE,
- HYTHREAD_LOCKTABLE_READING,
- HYTHREAD_LOCKTABLE_WRITING
-} hythread_locktable_state_t;
-
-typedef struct HyFatLockTable {
- // locktable itself
- hythread_monitor_t *table;
-
- // mutex guarding locktable
- hymutex_t mutex;
- hycond_t read;
- hycond_t write;
-
- int readers_reading;
- int readers_waiting;
- int writers_waiting;
-
- hythread_locktable_state_t state;
-
- U_32 read_count;
-
- // table of live objects (updated during each major GC)
- unsigned char *live_objs;
-
- // size of locktable
- U_32 size;
-
- // used to scan the lock table for the next available entry
- U_32 array_cursor;
-
-} HyFatLockTable;
-
-
-// Global variables
-
-extern hythread_group_t group_list; // list of thread groups
-extern IDATA groups_count; // number of thread groups
-
-extern apr_pool_t *TM_POOL; //global APR pool for thread manager
-
-extern apr_threadkey_t *TM_THREAD_KEY; // Key used to store tm_thread_t structure in TLS
-
-extern int max_group_index; // max number of groups
-
-extern int total_started_thread_count; // Total started thread counter.
-
-extern HyFatLockTable *lock_table;
-
-#define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads
-
-
-
-/**
-* Internal TM functions
-*/
-
-/**
-* tm_reset_suspend_disable() reset suspend_disable to 0, and return old value.
-* It should be used with tm_set_suspend_disable() to implement safe points
-* Will be used in tm_safe_point(), tm_mutex_lock(), tm_cond_wait().
-*/
-
-int reset_suspend_disable();
-void set_suspend_disable(int count);
-
-/* thin monitor functions used java monitor
- */
-IDATA is_fat_lock(hythread_thin_monitor_t lockword);
-IDATA owns_thin_lock(hythread_t thread, I_32 lockword);
-hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr);
-IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr);
-
-IDATA VMCALL hythread_get_group(hythread_group_t *group, hythread_t thread);
-/**
- * Auxiliary function to throw java.lang.InterruptedException
- */
-
-void throw_interrupted_exception(void);
-
-hythread_group_t get_java_thread_group(void);
-
-/**
- * Thread cancellation, being used at VM shutdown through
- * tmj_cancel_all_threads() method call to terminate all java
- * threads at shutdown.
- */
-
-typedef void (*tm_thread_event_callback_proc)(void);
-IDATA VMCALL set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback);
-
-IDATA acquire_start_lock(void);
-IDATA release_start_lock(void);
-
-IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable);
-IDATA condvar_wait_impl(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano, IDATA interruptable);
-IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA interruptable);
-IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano, IDATA interruptable);
-IDATA sem_wait_impl(hysem_t sem, I_64 ms, IDATA nano, IDATA interruptable);
-
-typedef struct ResizableArrayEntry {
- void *entry;
- UDATA next_free;
-} ResizableArrayEntry;
-
-typedef struct ResizableArrayEntry *array_entry_t;
-
-typedef struct ResizableArrayType {
- UDATA size;
- UDATA capacity;
- UDATA next_index;
- array_entry_t entries;
-} ResizableArrayType;
-typedef struct ResizableArrayType *array_t;
-
-
-IDATA array_create(array_t *array);
-IDATA array_destroy(array_t array);
-UDATA array_add(array_t array, void *value);
-void *array_delete(array_t array, UDATA index);
-void *array_get(array_t array, UDATA index);
-
-/**
- * Auxiliary function to update thread count
- */
-void thread_start_count();
-void thread_end_count();
-
-/*
- * portability functions, private for thread module
- */
-int os_thread_create(osthread_t* phandle, UDATA stacksize, UDATA priority,
- int (VMAPICALL *func)(void*), void *data);
-int os_thread_set_priority(osthread_t thread, int priority);
-osthread_t os_thread_current();
-int os_thread_cancel(osthread_t);
-int os_thread_join(osthread_t);
-void os_thread_exit(int status);
-void os_thread_yield_other(osthread_t);
-int os_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser);
-
-int os_cond_timedwait(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano);
-UDATA os_get_foreign_thread_stack_size();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* THREAD_PRIVATE_H */