mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 02:23:51 +08:00
Split out thread pool tests into threadpool_test
Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19695)
This commit is contained in:
parent
f5a3669c8b
commit
c48c32807f
@ -52,7 +52,7 @@ IF[{- !$disabled{tests} -}]
|
||||
bio_callback_test bio_memleak_test bio_core_test bio_dgram_test param_build_test \
|
||||
bioprinttest sslapitest dtlstest sslcorrupttest \
|
||||
bio_enc_test pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \
|
||||
cipherbytes_test threadstest_fips \
|
||||
cipherbytes_test threadstest_fips threadpool_test \
|
||||
asn1_encode_test asn1_decode_test asn1_string_table_test \
|
||||
x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \
|
||||
recordlentest drbgtest rand_status_test sslbuffertest \
|
||||
@ -360,6 +360,10 @@ IF[{- !$disabled{tests} -}]
|
||||
INCLUDE[ct_test]=../include ../apps/include
|
||||
DEPEND[ct_test]=../libcrypto libtestutil.a
|
||||
|
||||
SOURCE[threadpool_test]=threadpool_test.c
|
||||
INCLUDE[threadpool_test]=.. ../include ../apps/include
|
||||
DEPEND[threadpool_test]=../libcrypto.a libtestutil.a
|
||||
|
||||
SOURCE[threadstest]=threadstest.c
|
||||
INCLUDE[threadstest]=.. ../include ../apps/include
|
||||
DEPEND[threadstest]=../libcrypto.a libtestutil.a
|
||||
|
@ -23,7 +23,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
|
||||
my $config_path = abs_path(srctop_file("test", $no_fips ? "default.cnf"
|
||||
: "default-and-fips.cnf"));
|
||||
|
||||
plan tests => 2;
|
||||
plan tests => 3;
|
||||
|
||||
if ($no_fips) {
|
||||
ok(run(test(["threadstest", "-config", $config_path, data_dir()])),
|
||||
@ -33,6 +33,8 @@ if ($no_fips) {
|
||||
"running test_threads with FIPS");
|
||||
}
|
||||
|
||||
ok(run(test(["threadpool_test"])), "running threadpool_test");
|
||||
|
||||
# Merge the configuration files into one filtering the contents so the failure
|
||||
# condition is reproducible. A working FIPS configuration without the install
|
||||
# status is required.
|
||||
@ -53,4 +55,4 @@ close CFGINC;
|
||||
close CFGOUT;
|
||||
|
||||
$ENV{OPENSSL_CONF} = 'thread.cnf';
|
||||
ok(run(test(["threadstest_fips"])), "running test_threads_fips");
|
||||
ok(run(test(["threadstest_fips"])), "running threadstest_fips");
|
||||
|
303
test/threadpool_test.c
Normal file
303
test/threadpool_test.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <internal/cryptlib.h>
|
||||
#include <internal/thread_arch.h>
|
||||
#include <internal/thread.h>
|
||||
#include <openssl/thread.h>
|
||||
#include "testutil.h"
|
||||
|
||||
static int test_thread_reported_flags(void)
|
||||
{
|
||||
uint32_t flags = OSSL_get_thread_support_flags();
|
||||
|
||||
#if !defined(OPENSSL_THREADS)
|
||||
if (!TEST_int_eq(flags, 0))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_THREAD_POOL)
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL, 0))
|
||||
return 0;
|
||||
#else
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL,
|
||||
OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN, 0))
|
||||
return 0;
|
||||
#else
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN,
|
||||
OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_THREAD_POOL
|
||||
|
||||
# define TEST_THREAD_NATIVE_FN_SET_VALUE 1
|
||||
static uint32_t test_thread_native_fn(void *data)
|
||||
{
|
||||
uint32_t *ldata = (uint32_t*) data;
|
||||
*ldata = *ldata + 1;
|
||||
return *ldata - 1;
|
||||
}
|
||||
/* Tests of native threads */
|
||||
|
||||
static int test_thread_native(void)
|
||||
{
|
||||
uint32_t retval;
|
||||
uint32_t local;
|
||||
CRYPTO_THREAD *t;
|
||||
|
||||
/* thread spawn, join */
|
||||
|
||||
local = 1;
|
||||
t = ossl_crypto_thread_native_start(test_thread_native_fn, &local, 1);
|
||||
if (!TEST_ptr(t))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* pthread_join results in undefined behaviour if called on a joined
|
||||
* thread. We do not impose such restrictions, so it's up to us to
|
||||
* ensure that this does not happen (thread sanitizer will warn us
|
||||
* if we do).
|
||||
*/
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(retval, 1) || !TEST_int_eq(local, 2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
|
||||
return 0;
|
||||
t = NULL;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 0))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
static int test_thread_internal(void)
|
||||
{
|
||||
uint32_t retval[3];
|
||||
uint32_t local[3] = { 0 };
|
||||
uint32_t threads_supported;
|
||||
size_t i;
|
||||
void *t[3];
|
||||
OSSL_LIB_CTX *cust_ctx = OSSL_LIB_CTX_new();
|
||||
|
||||
threads_supported = OSSL_get_thread_support_flags();
|
||||
threads_supported &= OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN;
|
||||
|
||||
if (threads_supported == 0) {
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 0))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 0))
|
||||
return 0;
|
||||
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fail when not allowed to use threads */
|
||||
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
|
||||
/* fail when enabled on a different context */
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 1))
|
||||
return 0;
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 0), 1))
|
||||
return 0;
|
||||
|
||||
/* sequential startup */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[0] = i + 1;
|
||||
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* pthread_join results in undefined behaviour if called on a joined
|
||||
* thread. We do not impose such restrictions, so it's up to us to
|
||||
* ensure that this does not happen (thread sanitizer will warn us
|
||||
* if we do).
|
||||
*/
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(retval[0], i + 1) || !TEST_int_eq(local[0], i + 2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
t[i] = NULL;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parallel startup */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t)), 1))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[i] = i + 1;
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parallel startup, bottleneck */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t) - 1), 1))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[i] = i + 1;
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 0), 1))
|
||||
return 0;
|
||||
|
||||
OSSL_LIB_CTX_free(cust_ctx);
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn1(void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn2(void *data)
|
||||
{
|
||||
ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn3(void *data)
|
||||
{
|
||||
ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_thread_native_multiple_joins(void)
|
||||
{
|
||||
CRYPTO_THREAD *t, *t1, *t2;
|
||||
|
||||
t = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn1, NULL, 1);
|
||||
t1 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn2, t, 1);
|
||||
t2 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn3, t, 1);
|
||||
|
||||
if (!TEST_ptr(t) || !TEST_ptr(t1) || !TEST_ptr(t2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t2, NULL), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t1, NULL), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t2), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t1), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int setup_tests(void)
|
||||
{
|
||||
ADD_TEST(test_thread_reported_flags);
|
||||
#if !defined(OPENSSL_NO_THREAD_POOL)
|
||||
ADD_TEST(test_thread_native);
|
||||
ADD_TEST(test_thread_native_multiple_joins);
|
||||
# if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
ADD_TEST(test_thread_internal);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
@ -20,15 +20,11 @@
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <internal/cryptlib.h>
|
||||
#include <internal/thread_arch.h>
|
||||
#include <internal/thread.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/thread.h>
|
||||
#include "internal/tsan_assist.h"
|
||||
#include "internal/nelem.h"
|
||||
#include "testutil.h"
|
||||
@ -745,280 +741,6 @@ err:
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_thread_reported_flags(void)
|
||||
{
|
||||
uint32_t flags = OSSL_get_thread_support_flags();
|
||||
|
||||
#if !defined(OPENSSL_THREADS)
|
||||
if (!TEST_int_eq(flags, 0))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_THREAD_POOL)
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL, 0))
|
||||
return 0;
|
||||
#else
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL,
|
||||
OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN, 0))
|
||||
return 0;
|
||||
#else
|
||||
if (!TEST_int_eq(flags & OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN,
|
||||
OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_THREADS)
|
||||
|
||||
# define TEST_THREAD_NATIVE_FN_SET_VALUE 1
|
||||
static uint32_t test_thread_native_fn(void *data)
|
||||
{
|
||||
uint32_t *ldata = (uint32_t*) data;
|
||||
*ldata = *ldata + 1;
|
||||
return *ldata - 1;
|
||||
}
|
||||
/* Tests of native threads */
|
||||
|
||||
static int test_thread_native(void)
|
||||
{
|
||||
uint32_t retval;
|
||||
uint32_t local;
|
||||
CRYPTO_THREAD *t;
|
||||
|
||||
/* thread spawn, join */
|
||||
|
||||
local = 1;
|
||||
t = ossl_crypto_thread_native_start(test_thread_native_fn, &local, 1);
|
||||
if (!TEST_ptr(t))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* pthread_join results in undefined behaviour if called on a joined
|
||||
* thread. We do not impose such restrictions, so it's up to us to
|
||||
* ensure that this does not happen (thread sanitizer will warn us
|
||||
* if we do).
|
||||
*/
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t, &retval), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(retval, 1) || !TEST_int_eq(local, 2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
|
||||
return 0;
|
||||
t = NULL;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 0))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
static int test_thread_internal(void)
|
||||
{
|
||||
uint32_t retval[3];
|
||||
uint32_t local[3] = { 0 };
|
||||
uint32_t threads_supported;
|
||||
size_t i;
|
||||
void *t[3];
|
||||
OSSL_LIB_CTX *cust_ctx = OSSL_LIB_CTX_new();
|
||||
|
||||
threads_supported = OSSL_get_thread_support_flags();
|
||||
threads_supported &= OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN;
|
||||
|
||||
if (threads_supported == 0) {
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 0))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 0))
|
||||
return 0;
|
||||
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* fail when not allowed to use threads */
|
||||
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
|
||||
/* fail when enabled on a different context */
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 1), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 0))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 1))
|
||||
return 0;
|
||||
t[0] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr_null(t[0]))
|
||||
return 0;
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(cust_ctx, 0), 1))
|
||||
return 0;
|
||||
|
||||
/* sequential startup */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 1), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(NULL), 1))
|
||||
return 0;
|
||||
if (!TEST_uint64_t_eq(OSSL_get_max_threads(cust_ctx), 0))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[0] = i + 1;
|
||||
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[0]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* pthread_join results in undefined behaviour if called on a joined
|
||||
* thread. We do not impose such restrictions, so it's up to us to
|
||||
* ensure that this does not happen (thread sanitizer will warn us
|
||||
* if we do).
|
||||
*/
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[0]), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(retval[0], i + 1) || !TEST_int_eq(local[0], i + 2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
t[i] = NULL;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parallel startup */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t)), 1))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[i] = i + 1;
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parallel startup, bottleneck */
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, OSSL_NELEM(t) - 1), 1))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
local[i] = i + 1;
|
||||
t[i] = ossl_crypto_thread_start(NULL, test_thread_native_fn, &local[i]);
|
||||
if (!TEST_ptr(t[i]))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(ossl_crypto_thread_join(t[i], &retval[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < OSSL_NELEM(t); ++i) {
|
||||
if (!TEST_int_eq(retval[i], i + 1) || !TEST_int_eq(local[i], i + 2))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_clean(t[i]), 1))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!TEST_int_eq(OSSL_set_max_threads(NULL, 0), 1))
|
||||
return 0;
|
||||
|
||||
OSSL_LIB_CTX_free(cust_ctx);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn1(void *data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn2(void *data)
|
||||
{
|
||||
ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t test_thread_native_multiple_joins_fn3(void *data)
|
||||
{
|
||||
ossl_crypto_thread_native_join((CRYPTO_THREAD *)data, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_thread_native_multiple_joins(void)
|
||||
{
|
||||
CRYPTO_THREAD *t, *t1, *t2;
|
||||
|
||||
t = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn1, NULL, 1);
|
||||
t1 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn2, t, 1);
|
||||
t2 = ossl_crypto_thread_native_start(test_thread_native_multiple_joins_fn3, t, 1);
|
||||
|
||||
if (!TEST_ptr(t) || !TEST_ptr(t1) || !TEST_ptr(t2))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t2, NULL), 1))
|
||||
return 0;
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_join(t1, NULL), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t2), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t1), 1))
|
||||
return 0;
|
||||
|
||||
if (!TEST_int_eq(ossl_crypto_thread_native_clean(t), 1))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1,
|
||||
OPT_EOF = 0,
|
||||
@ -1094,15 +816,6 @@ int setup_tests(void)
|
||||
#if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK)
|
||||
ADD_TEST(test_bio_dgram_pair);
|
||||
#endif
|
||||
ADD_TEST(test_thread_reported_flags);
|
||||
#if defined(OPENSSL_THREADS)
|
||||
ADD_TEST(test_thread_native);
|
||||
ADD_TEST(test_thread_native_multiple_joins);
|
||||
#if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
|
||||
ADD_TEST(test_thread_internal);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user