qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kgiu...@apache.org
Subject [qpid-dispatch] branch master updated: DISPATCH-1679: Add sys_thread_self()
Date Thu, 18 Jun 2020 13:33:34 GMT
This is an automated email from the ASF dual-hosted git repository.

kgiusti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 3389a51  DISPATCH-1679: Add sys_thread_self()
3389a51 is described below

commit 3389a516437f0e6c076c4cdd2fc48e9cf61ded89
Author: Kenneth Giusti <kgiusti@apache.org>
AuthorDate: Tue Jun 9 16:20:29 2020 -0400

    DISPATCH-1679: Add sys_thread_self()
    
    sys_thread_self() provides an interface for accessing the sys_thread_t
    pointer for the currently running thread.  This replaces the old
    sys_thread_id() function which required the thread to already have its
    sys_thread_t pointer, which basically defeats the purpose.  In
    addition the return value of sys_thread_id() was pthread specific and
    should only be compared using pthread_equal().  sys_thread_self()
    return value is a plain pointer that can be compared in line.
    
    This closes #760
---
 include/qpid/dispatch/threading.h |   4 +-
 src/posix/threading.c             |  25 +++++-
 tests/CMakeLists.txt              |   1 +
 tests/run_unit_tests.c            |   2 +
 tests/thread_test.c               | 169 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 195 insertions(+), 6 deletions(-)

diff --git a/include/qpid/dispatch/threading.h b/include/qpid/dispatch/threading.h
index b883bab..dd2b59d 100644
--- a/include/qpid/dispatch/threading.h
+++ b/include/qpid/dispatch/threading.h
@@ -54,8 +54,6 @@ typedef struct sys_thread_t sys_thread_t;
 sys_thread_t *sys_thread(void *(*run_function) (void *), void *arg);
 void          sys_thread_free(sys_thread_t *thread);
 void          sys_thread_join(sys_thread_t *thread);
-
-/** Return the OS identifier for this thread */
-long sys_thread_id(sys_thread_t *thread);
+sys_thread_t *sys_thread_self(void);
 
 #endif
diff --git a/src/posix/threading.c b/src/posix/threading.c
index 5d7969b..db367f5 100644
--- a/src/posix/threading.c
+++ b/src/posix/threading.c
@@ -150,19 +150,38 @@ void sys_rwlock_unlock(sys_rwlock_t *lock)
 
 struct sys_thread_t {
     pthread_t thread;
+    void *(*f)(void *);
+    void *arg;
 };
 
+static __thread sys_thread_t *_self;
+
+
+// bootstrap _self before calling main thread function
+//
+static void *_thread_init(void *arg)
+{
+    _self = (sys_thread_t*) arg;
+    return _self->f(_self->arg);
+}
+
+
 sys_thread_t *sys_thread(void *(*run_function) (void *), void *arg)
 {
     sys_thread_t *thread = NEW(sys_thread_t);
-    pthread_create(&(thread->thread), 0, run_function, arg);
+    thread->f = run_function;
+    thread->arg = arg;
+    pthread_create(&(thread->thread), 0, _thread_init, (void*) thread);
     return thread;
 }
 
-long sys_thread_id(sys_thread_t *thread) {
-    return (long) thread->thread;
+
+sys_thread_t *sys_thread_self()
+{
+    return _self;
 }
 
+
 void sys_thread_free(sys_thread_t *thread)
 {
     free(thread);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b7bd2c2..81e22f8 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -38,6 +38,7 @@ set(unit_test_SOURCES
     alloc_test.c
     version_test.c
     hash_test.c
+    thread_test.c
     )
 
 add_executable(unit_tests ${unit_test_SOURCES})
diff --git a/tests/run_unit_tests.c b/tests/run_unit_tests.c
index cbd0e3a..be4c1b7 100644
--- a/tests/run_unit_tests.c
+++ b/tests/run_unit_tests.c
@@ -33,6 +33,7 @@ int parse_tree_tests(void);
 int proton_utils_tests(void);
 int version_tests(void);
 int hash_tests(void);
+int thread_tests(void);
 
 
 int main(int argc, char** argv)
@@ -68,6 +69,7 @@ int main(int argc, char** argv)
     result += core_timer_tests();
     result += version_tests();
     result += hash_tests();
+    result += thread_tests();
 
     qd_dispatch_free(qd);       // dispatch_free last.
 
diff --git a/tests/thread_test.c b/tests/thread_test.c
new file mode 100644
index 0000000..9a59d0c
--- /dev/null
+++ b/tests/thread_test.c
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdint.h>
+#include <unistd.h>
+#include "test_case.h"
+#include <qpid/dispatch/threading.h>
+
+
+
+#define thread_count 10
+static sys_thread_t *threads[thread_count] = {0};
+
+static sys_mutex_t  *mutex = 0;
+static sys_cond_t   *cond = 0;
+
+static char         *result;
+
+
+// for test_thread_id
+//
+void *thread_id_thread(void *arg)
+{
+    intptr_t index = (intptr_t) arg;
+    assert(index < thread_count);
+
+    sys_mutex_lock(mutex);
+
+    // check if self corresponds to my index in threads[]
+    if (!sys_thread_self()) {
+        result = "sys_thread_self returned zero!";
+    } else if (threads[index] != sys_thread_self()) {
+        result = "sys_thread_self mismatch";
+    }
+
+    sys_mutex_unlock(mutex);
+
+    return 0;
+}
+
+
+// ensure sys_thread_self is correct
+//
+static char *test_thread_id(void *context)
+{
+    mutex = sys_mutex();
+    sys_mutex_lock(mutex);
+
+    // start threads and retain their addresses
+    //
+    result = 0;
+    memset(threads, 0, sizeof(threads));
+    for (intptr_t i = 0; i < thread_count; ++i) {
+        threads[i] = sys_thread(thread_id_thread, (void *)i);
+    }
+
+    sys_mutex_unlock(mutex);
+
+    for (int i = 0; i < thread_count; ++i) {
+        sys_thread_join(threads[i]);
+        sys_thread_free(threads[i]);
+        threads[i] = 0;
+    }
+
+    sys_mutex_free(mutex);
+    return result;
+}
+
+
+
+static int cond_count;
+
+
+// run by test_condition
+//
+void *test_condition_thread(void *arg)
+{
+    int *test = (int *)arg;
+
+    sys_mutex_lock(mutex);
+    while (*test == 0) {
+        // it is expected that cond_count will never be > 1 since the condition
+        // is triggered only once
+        cond_count += 1;
+        sys_cond_wait(cond, mutex);
+    }
+    if (*test != 1) {
+        result = "error expected *test to be 1";
+    } else {
+        *test += 1;
+    }
+    sys_mutex_unlock(mutex);
+
+    return 0;
+}
+
+
+static char *test_condition(void *context)
+{
+    mutex = sys_mutex();
+    cond = sys_cond();
+
+    sys_mutex_lock(mutex);
+
+    int test = 0;
+    cond_count = 0;
+    result = 0;
+    sys_thread_t *thread = sys_thread(test_condition_thread, &test);
+
+    sys_mutex_unlock(mutex);
+
+    // let thread run and block on condition
+    sleep(1);
+
+    sys_mutex_lock(mutex);
+
+    if (cond_count != 1) {
+        result = "expected thread to wait on condition";
+    }
+
+    test = 1;
+
+    sys_cond_signal(cond);
+    sys_mutex_unlock(mutex);
+
+    sys_thread_join(thread);
+    sys_thread_free(thread);
+
+    if (!result && test != 2) {
+        result = "expected thread to increment test variable";
+    }
+
+    sys_cond_free(cond);
+    sys_mutex_free(mutex);
+    return result;
+}
+
+
+int thread_tests()
+{
+    int result = 0;
+    char *test_group = "thread_tests";
+
+    TEST_CASE(test_thread_id, 0);
+    TEST_CASE(test_condition, 0);
+
+    return result;
+}
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message