blob: d3377549e1cf987c50039ad31d848a4440a60958 [file] [log] [blame]
Willy Tarreauc7e42382012-08-24 19:22:53 +02001/*
Willy Tarreau2741c8c2020-06-02 11:28:02 +02002 * include/haproxy/dynbuf.h
3 * Buffer management functions.
Willy Tarreauc7e42382012-08-24 19:22:53 +02004 *
Willy Tarreau2741c8c2020-06-02 11:28:02 +02005 * Copyright (C) 2000-2020 Willy Tarreau - w@1wt.eu
Willy Tarreauc7e42382012-08-24 19:22:53 +02006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
Willy Tarreau2741c8c2020-06-02 11:28:02 +020022#ifndef _HAPROXY_DYNBUF_H
23#define _HAPROXY_DYNBUF_H
Willy Tarreauc7e42382012-08-24 19:22:53 +020024
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
Willy Tarreau2741c8c2020-06-02 11:28:02 +020029#include <import/ist.h>
30#include <haproxy/activity.h>
Willy Tarreau4c7e4b72020-05-27 12:58:42 +020031#include <haproxy/api.h>
Willy Tarreau8dabda72020-05-27 17:22:10 +020032#include <haproxy/buf.h>
Willy Tarreauc13ed532020-06-02 10:22:45 +020033#include <haproxy/chunk.h>
Willy Tarreau2741c8c2020-06-02 11:28:02 +020034#include <haproxy/dynbuf-t.h>
Willy Tarreaud0ef4392020-06-02 09:38:52 +020035#include <haproxy/pool.h>
Willy Tarreauc7e42382012-08-24 19:22:53 +020036
Willy Tarreaubafbe012017-11-24 17:34:44 +010037extern struct pool_head *pool_head_buffer;
Willy Tarreauc7e42382012-08-24 19:22:53 +020038
Willy Tarreau9b28e032012-10-12 23:49:43 +020039int init_buffer();
Willy Tarreauc7e42382012-08-24 19:22:53 +020040void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreauc7e42382012-08-24 19:22:53 +020041
42/*****************************************************************/
43/* These functions are used to compute various buffer area sizes */
44/*****************************************************************/
45
Willy Tarreauc7e42382012-08-24 19:22:53 +020046/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
47static inline int buffer_almost_full(const struct buffer *buf)
48{
Willy Tarreauc9fa0482018-07-10 17:43:27 +020049 if (b_is_null(buf))
Willy Tarreau4428a292014-11-28 20:54:13 +010050 return 0;
51
Willy Tarreaubbc68df2018-06-06 14:30:50 +020052 return b_almost_full(buf);
Willy Tarreauc7e42382012-08-24 19:22:53 +020053}
54
Willy Tarreau7b04cc42018-07-10 10:35:02 +020055/**************************************************/
56/* Functions below are used for buffer allocation */
57/**************************************************/
Willy Tarreauaf819352012-08-27 22:08:00 +020058
Willy Tarreau766b6cf2021-03-22 16:10:22 +010059/* Ensures that <buf> is allocated, or allocates it. If no memory is available,
60 * ((char *)1) is assigned instead with a zero size. The allocated buffer is
Willy Tarreauc9fa0482018-07-10 17:43:27 +020061 * returned, or NULL in case no memory is available.
Willy Tarreaue583ea52014-11-24 11:30:16 +010062 */
Willy Tarreauc9fa0482018-07-10 17:43:27 +020063static inline struct buffer *b_alloc(struct buffer *buf)
Willy Tarreaue583ea52014-11-24 11:30:16 +010064{
Willy Tarreauc9fa0482018-07-10 17:43:27 +020065 char *area;
Willy Tarreauf2f7d6b2014-11-24 11:55:08 +010066
Willy Tarreau766b6cf2021-03-22 16:10:22 +010067 if (buf->size)
68 return buf;
69
Willy Tarreauc9fa0482018-07-10 17:43:27 +020070 *buf = BUF_WANTED;
Willy Tarreaude749a92021-03-22 20:54:15 +010071 area = __pool_alloc(pool_head_buffer, POOL_F_NO_POISON);
Willy Tarreaua8b2ce02019-05-28 17:04:16 +020072 if (unlikely(!area)) {
73 activity[tid].buf_wait++;
Willy Tarreauc9fa0482018-07-10 17:43:27 +020074 return NULL;
Willy Tarreaua8b2ce02019-05-28 17:04:16 +020075 }
Willy Tarreauc9fa0482018-07-10 17:43:27 +020076
77 buf->area = area;
78 buf->size = pool_head_buffer->size;
79 return buf;
Willy Tarreaue583ea52014-11-24 11:30:16 +010080}
81
Willy Tarreau3b091f82019-08-08 07:53:20 +020082/* Releases buffer <buf> (no check of emptiness). The buffer's head is marked
83 * empty.
84 */
Willy Tarreaue0d0b402019-08-08 08:06:27 +020085static inline void __b_free(struct buffer *buf)
Willy Tarreau7dfca9d2014-11-25 19:45:11 +010086{
Willy Tarreau3b091f82019-08-08 07:53:20 +020087 char *area = buf->area;
88
89 /* let's first clear the area to save an occasional "show sess all"
90 * glancing over our shoulder from getting a dangling pointer.
91 */
92 *buf = BUF_NULL;
93 __ha_barrier_store();
94 pool_free(pool_head_buffer, area);
Willy Tarreau7dfca9d2014-11-25 19:45:11 +010095}
96
Willy Tarreau3b091f82019-08-08 07:53:20 +020097/* Releases buffer <buf> if allocated, and marks it empty. */
Willy Tarreauc9fa0482018-07-10 17:43:27 +020098static inline void b_free(struct buffer *buf)
Willy Tarreau2a4b5432014-11-24 11:39:34 +010099{
Willy Tarreaue0d0b402019-08-08 08:06:27 +0200100 if (buf->size)
101 __b_free(buf);
Willy Tarreau2a4b5432014-11-24 11:39:34 +0100102}
103
Willy Tarreau4d77bbf2021-02-20 12:02:46 +0100104/* Offer one or multiple buffer currently belonging to target <from> to whoever
105 * needs one. Any pointer is valid for <from>, including NULL. Its purpose is
106 * to avoid passing a buffer to oneself in case of failed allocations (e.g.
107 * need two buffers, get one, fail, release it and wake up self again). In case
108 * of normal buffer release where it is expected that the caller is not waiting
Willy Tarreaue8e50912021-02-20 11:38:56 +0100109 * for a buffer, NULL is fine. It will wake waiters on the current thread only.
Willy Tarreauc41b3e82018-03-02 10:27:12 +0100110 */
Willy Tarreau4d77bbf2021-02-20 12:02:46 +0100111void __offer_buffers(void *from, unsigned int count);
Christopher Fauleta73e59b2016-12-09 17:30:18 +0100112
Willy Tarreau4d77bbf2021-02-20 12:02:46 +0100113static inline void offer_buffers(void *from, unsigned int count)
Christopher Fauleta73e59b2016-12-09 17:30:18 +0100114{
Willy Tarreau90f366b2021-02-20 11:49:49 +0100115 if (!LIST_ISEMPTY(&ti->buffer_wq))
Willy Tarreau4d77bbf2021-02-20 12:02:46 +0100116 __offer_buffers(from, count);
Christopher Fauleta73e59b2016-12-09 17:30:18 +0100117}
118
Willy Tarreaue5676e72017-09-22 15:47:51 +0200119
Willy Tarreau2741c8c2020-06-02 11:28:02 +0200120#endif /* _HAPROXY_DYNBUF_H */
Willy Tarreauc7e42382012-08-24 19:22:53 +0200121
122/*
123 * Local variables:
124 * c-indent-level: 8
125 * c-basic-offset: 8
126 * End:
127 */