2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/configuration.h>
11 #include <openssl/e_os2.h>
12 #include <openssl/types.h>
13 #include <openssl/crypto.h>
14 #include <internal/thread.h>
15 #include <internal/thread_arch.h>
17 #if !defined(OPENSSL_NO_DEFAULT_THREAD_POOL)
19 static ossl_inline
uint64_t _ossl_get_avail_threads(OSSL_LIB_CTX_THREADS
*tdata
)
21 /* assumes that tdata->lock is taken */
22 return tdata
->max_threads
- tdata
->active_threads
;
25 uint64_t ossl_get_avail_threads(OSSL_LIB_CTX
*ctx
)
28 OSSL_LIB_CTX_THREADS
*tdata
= OSSL_LIB_CTX_GET_THREADS(ctx
);
33 ossl_crypto_mutex_lock(tdata
->lock
);
34 retval
= _ossl_get_avail_threads(tdata
);
35 ossl_crypto_mutex_unlock(tdata
->lock
);
40 void *ossl_crypto_thread_start(OSSL_LIB_CTX
*ctx
, CRYPTO_THREAD_ROUTINE start
,
43 CRYPTO_THREAD
*thread
;
44 OSSL_LIB_CTX_THREADS
*tdata
= OSSL_LIB_CTX_GET_THREADS(ctx
);
49 ossl_crypto_mutex_lock(tdata
->lock
);
50 if (tdata
== NULL
|| tdata
->max_threads
== 0) {
51 ossl_crypto_mutex_unlock(tdata
->lock
);
55 while (_ossl_get_avail_threads(tdata
) == 0)
56 ossl_crypto_condvar_wait(tdata
->cond_finished
, tdata
->lock
);
57 tdata
->active_threads
++;
58 ossl_crypto_mutex_unlock(tdata
->lock
);
60 thread
= ossl_crypto_thread_native_start(start
, data
, 1);
62 ossl_crypto_mutex_lock(tdata
->lock
);
63 tdata
->active_threads
--;
64 ossl_crypto_mutex_unlock(tdata
->lock
);
70 return (void *) thread
;
73 int ossl_crypto_thread_join(void *vhandle
, CRYPTO_THREAD_RETVAL
*retval
)
75 CRYPTO_THREAD
*handle
= vhandle
;
76 OSSL_LIB_CTX_THREADS
*tdata
;
81 tdata
= OSSL_LIB_CTX_GET_THREADS(handle
->ctx
);
85 if (ossl_crypto_thread_native_join(handle
, retval
) == 0)
88 ossl_crypto_mutex_lock(tdata
->lock
);
89 tdata
->active_threads
--;
90 ossl_crypto_condvar_broadcast(tdata
->cond_finished
);
91 ossl_crypto_mutex_unlock(tdata
->lock
);
95 int ossl_crypto_thread_clean(void *vhandle
)
97 CRYPTO_THREAD
*handle
= vhandle
;
99 return ossl_crypto_thread_native_clean(handle
);
104 ossl_inline
uint64_t ossl_get_avail_threads(OSSL_LIB_CTX
*ctx
)
109 void *ossl_crypto_thread_start(OSSL_LIB_CTX
*ctx
, CRYPTO_THREAD_ROUTINE start
,
115 int ossl_crypto_thread_join(void *vhandle
, CRYPTO_THREAD_RETVAL
*retval
)
120 int ossl_crypto_thread_clean(void *vhandle
)
127 #if defined(OPENSSL_THREADS)
129 void *ossl_threads_ctx_new(OSSL_LIB_CTX
*ctx
)
131 struct openssl_threads_st
*t
= OPENSSL_zalloc(sizeof(*t
));
136 t
->lock
= ossl_crypto_mutex_new();
137 t
->cond_finished
= ossl_crypto_condvar_new();
139 if (t
->lock
== NULL
|| t
->cond_finished
== NULL
)
145 ossl_threads_ctx_free((void *)t
);
149 void ossl_threads_ctx_free(void *vdata
)
151 OSSL_LIB_CTX_THREADS
*t
= (OSSL_LIB_CTX_THREADS
*) vdata
;
156 ossl_crypto_mutex_free(&t
->lock
);
157 ossl_crypto_condvar_free(&t
->cond_finished
);