blob: 594a81d52a6ea996fbadcc869ff2d3b4bb5b9f80 [file] [log] [blame]
Emeric Brun3e541d12012-09-03 11:14:36 +02001/*
2 * shctx.h - shared context management functions for SSL
3 *
4 * Copyright (C) 2011-2012 EXCELIANCE
5 *
6 * Author: Emeric Brun - emeric@exceliance.fr
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#ifndef SHCTX_H
15#define SHCTX_H
William Lallemand24a7a752017-10-09 14:17:39 +020016
William Lallemand4f45bb92017-10-30 20:08:51 +010017#include <common/mini-clist.h>
William Lallemand24a7a752017-10-09 14:17:39 +020018#include <types/shctx.h>
19
Emeric Brun3e541d12012-09-03 11:14:36 +020020#include <stdint.h>
21
William Lallemand24a7a752017-10-09 14:17:39 +020022#ifndef USE_PRIVATE_CACHE
23#ifdef USE_PTHREAD_PSHARED
24#include <pthread.h>
25#else
26#ifdef USE_SYSCALL_FUTEX
27#include <unistd.h>
28#include <linux/futex.h>
29#include <sys/syscall.h>
Emeric Brun3e541d12012-09-03 11:14:36 +020030#endif
Emeric Brun3e541d12012-09-03 11:14:36 +020031#endif
Emeric Brun786991e2012-11-26 18:37:12 +010032#endif
33
Frédéric Lécailleb7838af2018-10-22 16:21:39 +020034int shctx_init(struct shared_context **orig_shctx,
35 int maxblocks, int blocksize, int maxobjsz, int extra, int shared);
Frédéric Lécaille0bec8072018-10-22 17:55:57 +020036struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
37 struct shared_block *last, int data_len);
William Lallemand4f45bb92017-10-30 20:08:51 +010038void shctx_row_inc_hot(struct shared_context *shctx, struct shared_block *first);
39void shctx_row_dec_hot(struct shared_context *shctx, struct shared_block *first);
40int shctx_row_data_append(struct shared_context *shctx,
Frédéric Lécaille0bec8072018-10-22 17:55:57 +020041 struct shared_block *first, struct shared_block *from,
42 unsigned char *data, int len);
William Lallemand4f45bb92017-10-30 20:08:51 +010043int shctx_row_data_get(struct shared_context *shctx, struct shared_block *first,
44 unsigned char *dst, int offset, int len);
Emeric Bruncaa19cc2014-05-07 16:10:18 +020045
William Lallemanded0b5ad2017-10-30 19:36:36 +010046
William Lallemand24a7a752017-10-09 14:17:39 +020047/* Lock functions */
48
49#if defined (USE_PRIVATE_CACHE)
50
William Lallemanda3c77cf2017-10-30 23:44:40 +010051#define shctx_lock(shctx)
52#define shctx_unlock(shctx)
William Lallemand24a7a752017-10-09 14:17:39 +020053
54#elif defined (USE_PTHREAD_PSHARED)
55extern int use_shared_mem;
56
William Lallemanda3c77cf2017-10-30 23:44:40 +010057#define shctx_lock(shctx) if (use_shared_mem) pthread_mutex_lock(&shctx->mutex)
58#define shctx_unlock(shctx) if (use_shared_mem) pthread_mutex_unlock(&shctx->mutex)
William Lallemand24a7a752017-10-09 14:17:39 +020059
60#else
61extern int use_shared_mem;
62
63#ifdef USE_SYSCALL_FUTEX
William Lallemanda3c77cf2017-10-30 23:44:40 +010064static inline void _shctx_wait4lock(unsigned int *count, unsigned int *uaddr, int value)
William Lallemand24a7a752017-10-09 14:17:39 +020065{
66 syscall(SYS_futex, uaddr, FUTEX_WAIT, value, NULL, 0, 0);
67}
68
William Lallemanda3c77cf2017-10-30 23:44:40 +010069static inline void _shctx_awakelocker(unsigned int *uaddr)
William Lallemand24a7a752017-10-09 14:17:39 +020070{
71 syscall(SYS_futex, uaddr, FUTEX_WAKE, 1, NULL, 0, 0);
72}
73
74#else /* internal spin lock */
75
76#if defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__)
77static inline void relax()
78{
79 __asm volatile("rep;nop\n" ::: "memory");
80}
81#else /* if no x86_64 or i586 arch: use less optimized but generic asm */
82static inline void relax()
83{
84 __asm volatile("" ::: "memory");
85}
86#endif
87
William Lallemanda3c77cf2017-10-30 23:44:40 +010088static inline void _shctx_wait4lock(unsigned int *count, unsigned int *uaddr, int value)
William Lallemand24a7a752017-10-09 14:17:39 +020089{
90 int i;
91
92 for (i = 0; i < *count; i++) {
93 relax();
94 relax();
95 }
96 *count = *count << 1;
97}
98
William Lallemanda3c77cf2017-10-30 23:44:40 +010099#define _shctx_awakelocker(a)
William Lallemand24a7a752017-10-09 14:17:39 +0200100
101#endif
102
103#if defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__)
104static inline unsigned int xchg(unsigned int *ptr, unsigned int x)
105{
106 __asm volatile("lock xchgl %0,%1"
107 : "=r" (x), "+m" (*ptr)
108 : "0" (x)
109 : "memory");
110 return x;
111}
112
113static inline unsigned int cmpxchg(unsigned int *ptr, unsigned int old, unsigned int new)
114{
115 unsigned int ret;
116
117 __asm volatile("lock cmpxchgl %2,%1"
118 : "=a" (ret), "+m" (*ptr)
119 : "r" (new), "0" (old)
120 : "memory");
121 return ret;
122}
123
124static inline unsigned char atomic_dec(unsigned int *ptr)
125{
126 unsigned char ret;
127 __asm volatile("lock decl %0\n"
128 "setne %1\n"
129 : "+m" (*ptr), "=qm" (ret)
130 :
131 : "memory");
132 return ret;
133}
134
135#else /* if no x86_64 or i586 arch: use less optimized gcc >= 4.1 built-ins */
136static inline unsigned int xchg(unsigned int *ptr, unsigned int x)
137{
138 return __sync_lock_test_and_set(ptr, x);
139}
140
141static inline unsigned int cmpxchg(unsigned int *ptr, unsigned int old, unsigned int new)
142{
143 return __sync_val_compare_and_swap(ptr, old, new);
144}
145
146static inline unsigned char atomic_dec(unsigned int *ptr)
147{
148 return __sync_sub_and_fetch(ptr, 1) ? 1 : 0;
149}
150
151#endif
152
William Lallemanda3c77cf2017-10-30 23:44:40 +0100153static inline void _shctx_lock(struct shared_context *shctx)
William Lallemand24a7a752017-10-09 14:17:39 +0200154{
155 unsigned int x;
156 unsigned int count = 4;
157
158 x = cmpxchg(&shctx->waiters, 0, 1);
159 if (x) {
160 if (x != 2)
161 x = xchg(&shctx->waiters, 2);
162
163 while (x) {
William Lallemanda3c77cf2017-10-30 23:44:40 +0100164 _shctx_wait4lock(&count, &shctx->waiters, 2);
William Lallemand24a7a752017-10-09 14:17:39 +0200165 x = xchg(&shctx->waiters, 2);
166 }
167 }
168}
169
William Lallemanda3c77cf2017-10-30 23:44:40 +0100170static inline void _shctx_unlock(struct shared_context *shctx)
William Lallemand24a7a752017-10-09 14:17:39 +0200171{
172 if (atomic_dec(&shctx->waiters)) {
173 shctx->waiters = 0;
William Lallemanda3c77cf2017-10-30 23:44:40 +0100174 _shctx_awakelocker(&shctx->waiters);
William Lallemand24a7a752017-10-09 14:17:39 +0200175 }
176}
177
William Lallemanda3c77cf2017-10-30 23:44:40 +0100178#define shctx_lock(shctx) if (use_shared_mem) _shctx_lock(shctx)
William Lallemand24a7a752017-10-09 14:17:39 +0200179
William Lallemanda3c77cf2017-10-30 23:44:40 +0100180#define shctx_unlock(shctx) if (use_shared_mem) _shctx_unlock(shctx)
William Lallemand24a7a752017-10-09 14:17:39 +0200181
182#endif
183
William Lallemanded0b5ad2017-10-30 19:36:36 +0100184/* List Macros */
185
Frédéric Lécaille0bec8072018-10-22 17:55:57 +0200186/*
187 * Insert <s> block after <head> which is not necessarily the head of a list,
188 * so between <head> and the next element after <head>.
189 */
190static inline void shctx_block_append_hot(struct shared_context *shctx,
191 struct list *head,
192 struct shared_block *s)
193{
194 shctx->nbav--;
195 LIST_DEL(&s->list);
196 LIST_ADD(head, &s->list);
197}
198
William Lallemand4f45bb92017-10-30 20:08:51 +0100199static inline void shctx_block_set_hot(struct shared_context *shctx,
William Lallemanded0b5ad2017-10-30 19:36:36 +0100200 struct shared_block *s)
201{
William Lallemand4f45bb92017-10-30 20:08:51 +0100202 shctx->nbav--;
203 LIST_DEL(&s->list);
204 LIST_ADDQ(&shctx->hot, &s->list);
William Lallemanded0b5ad2017-10-30 19:36:36 +0100205}
206
William Lallemand4f45bb92017-10-30 20:08:51 +0100207static inline void shctx_block_set_avail(struct shared_context *shctx,
William Lallemanded0b5ad2017-10-30 19:36:36 +0100208 struct shared_block *s)
209{
William Lallemand4f45bb92017-10-30 20:08:51 +0100210 shctx->nbav++;
211 LIST_DEL(&s->list);
212 LIST_ADDQ(&shctx->avail, &s->list);
William Lallemanded0b5ad2017-10-30 19:36:36 +0100213}
William Lallemand24a7a752017-10-09 14:17:39 +0200214
Emeric Brun3e541d12012-09-03 11:14:36 +0200215#endif /* SHCTX_H */
216