crypto: add preemptive threading support
[openssl.git] / include / internal / thread_arch.h
1 /*
2  * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 #ifndef OSSL_INTERNAL_THREAD_ARCH_H
11 # define OSSL_INTERNAL_THREAD_ARCH_H
12 # include <openssl/configuration.h>
13 # include <openssl/e_os2.h>
14
15 # if defined(_WIN32)
16 #  include <windows.h>
17 # endif
18
19 # if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_UNIX)
20 #  define OPENSSL_THREADS_POSIX
21 # elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_WINDOWS) && \
22     defined(_WIN32_WINNT)
23 #  if _WIN32_WINNT >= 0x0600
24 #   define OPENSSL_THREADS_WINNT
25 #  else
26 #   define OPENSSL_THREADS_NONE
27 #  endif
28 # else
29 #  define OPENSSL_THREADS_NONE
30 # endif
31
32 # include <openssl/crypto.h>
33
34 typedef void CRYPTO_MUTEX;
35 typedef void CRYPTO_CONDVAR;
36
37 CRYPTO_MUTEX *ossl_crypto_mutex_new(void);
38 void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex);
39 int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex);
40 void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex);
41 void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex);
42
43 CRYPTO_CONDVAR *ossl_crypto_condvar_new(void);
44 void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex);
45 void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv);
46 void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv);
47
48 typedef uint32_t CRYPTO_THREAD_RETVAL;
49 typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE)(void *);
50 typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE_CB)(void *,
51                                                          void (**)(void *),
52                                                          void **);
53
54 # define CRYPTO_THREAD_NO_STATE   0UL
55 # define CRYPTO_THREAD_FINISHED   (1UL << 1)
56 # define CRYPTO_THREAD_JOINED     (1UL << 2)
57 # define CRYPTO_THREAD_TERMINATED (1UL << 3)
58
59 # define CRYPTO_THREAD_GET_STATE(THREAD, FLAG) ((THREAD)->state & (FLAG))
60 # define CRYPTO_THREAD_GET_ERROR(THREAD, FLAG) (((THREAD)->state >> 16) & (FLAG))
61
62 typedef struct crypto_thread_st {
63     uint32_t state;
64     void *data;
65     CRYPTO_THREAD_ROUTINE routine;
66     CRYPTO_THREAD_RETVAL retval;
67     void *handle;
68     CRYPTO_MUTEX *lock;
69     CRYPTO_MUTEX *statelock;
70     CRYPTO_CONDVAR *condvar;
71     unsigned long thread_id;
72     int joinable;
73     OSSL_LIB_CTX *ctx;
74 } CRYPTO_THREAD;
75
76 # if defined(OPENSSL_THREADS)
77
78 #  define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG)                       \
79     do {                                                                \
80         (THREAD)->state &= ~(FLAG);                                     \
81     } while ((void)0, 0)
82
83 #  define CRYPTO_THREAD_SET_STATE(THREAD, FLAG)                         \
84     do {                                                                \
85         (THREAD)->state |= (FLAG);                                      \
86     } while ((void)0, 0)
87
88 #  define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG)                         \
89     do {                                                                \
90         (THREAD)->state |= ((FLAG) << 16);                              \
91     } while ((void)0, 0)
92
93 #  define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG)                       \
94     do {                                                                \
95         (THREAD)->state &= ~((FLAG) << 16);                             \
96     } while ((void)0, 0)
97
98 # else
99
100 #  define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG)
101 #  define CRYPTO_THREAD_SET_STATE(THREAD, FLAG)
102 #  define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG)
103 #  define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG)
104
105 # endif /* defined(OPENSSL_THREADS) */
106
107 CRYPTO_THREAD * ossl_crypto_thread_native_start(CRYPTO_THREAD_ROUTINE routine,
108                                            void *data, int joinable);
109 int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread);
110 int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread,
111                               CRYPTO_THREAD_RETVAL *retval);
112 int ossl_crypto_thread_native_terminate(CRYPTO_THREAD *thread);
113 int ossl_crypto_thread_native_exit(void);
114 int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread);
115 int ossl_crypto_thread_native_clean(CRYPTO_THREAD *thread);
116
117 void ossl_crypto_mem_barrier(void);
118
119 #endif /* OSSL_INTERNAL_THREAD_ARCH_H */