1/*
2 This file is part of Mtproto-proxy Library.
3
4 Mtproto-proxy Library is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 Mtproto-proxy Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with Mtproto-proxy Library. If not, see <http://www.gnu.org/licenses/>.
16
17 Copyright 2012-2013 Vkontakte Ltd
18 2012-2013 Nikolai Durov
19 2012-2013 Andrey Lopatin
20
21 Copyright 2014-2016 Telegram Messenger Inc
22 2015-2016 Vitaly Valtman
23*/
24
25#pragma once
26
27#include <assert.h>
28#include "common/mp-queue.h"
29
30#define MSG_STD_BUFFER 2048
31#define MSG_SMALL_BUFFER 512
32#define MSG_TINY_BUFFER 48
33
34#define MSG_BUFFERS_CHUNK_SIZE ((1L << 21) - 64)
35
36#define MSG_DEFAULT_MAX_ALLOCATED_BYTES (1L << 28)
37
38#ifdef _LP64
39#define MSG_MAX_ALLOCATED_BYTES (1L << 40)
40#else
41#define MSG_MAX_ALLOCATED_BYTES (1L << 30)
42#endif
43
44#define MSG_BUFFER_FREE_MAGIC 0x4abdc351
45#define MSG_BUFFER_USED_MAGIC 0x72e39317
46#define MSG_BUFFER_SPECIAL_MAGIC 0x683caad3
47
48#define MSG_CHUNK_USED_MAGIC 0x5c75e681
49#define MSG_CHUNK_USED_LOCKED_MAGIC (~MSG_CHUNK_USED_MAGIC)
50#define MSG_CHUNK_HEAD_MAGIC 0x2dfecca3
51#define MSG_CHUNK_HEAD_LOCKED_MAGIC (~MSG_CHUNK_HEAD_MAGIC)
52
53#define MAX_BUFFER_SIZE_VALUES 16
54
55#define BUFF_HD_BYTES (offsetof (struct msg_buffer, data))
56
57struct msg_buffer {
58 struct msg_buffers_chunk *chunk;
59#ifndef _LP64
60 int resvd;
61#endif
62 int refcnt;
63 int magic;
64 char data[0];
65};
66
67struct msg_buffers_chunk {
68 int magic;
69 int buffer_size;
70 int (*free_buffer)(struct msg_buffers_chunk *C, struct msg_buffer *B);
71 struct msg_buffers_chunk *ch_next, *ch_prev;
72 struct msg_buffers_chunk *ch_head;
73 struct msg_buffer *first_buffer;
74 int two_power; /* least two-power >= tot_buffers */
75 int tot_buffers;
76 int bs_inverse;
77 int bs_shift;
78 struct mp_queue *free_block_queue;
79 int thread_class;
80 int thread_subclass;
81 int refcnt;
82 union {
83 struct {
84 int tot_chunks;
85 int free_buffers;
86 };
87 unsigned short free_cnt[0];
88 };
89};
90
91struct buffers_stat {
92 long long total_used_buffers_size;
93 long long allocated_buffer_bytes;
94 long long buffer_chunk_alloc_ops;
95 int total_used_buffers;
96 int allocated_buffer_chunks, max_allocated_buffer_chunks, max_buffer_chunks;
97 long long max_allocated_buffer_bytes;
98};
99
100void fetch_buffers_stat (struct buffers_stat *bs);
101
102int free_msg_buffer (struct msg_buffer *X);
103static inline void msg_buffer_decref (struct msg_buffer *buffer) {
104 if (buffer->refcnt == 1 || __sync_fetch_and_add (&buffer->refcnt, -1) == 1) {
105 buffer->refcnt = 0;
106 free_msg_buffer (buffer);
107 }
108}
109
110
111int init_msg_buffers (long max_buffer_bytes);
112
113struct msg_buffer *alloc_msg_buffer (struct msg_buffer *neighbor, int size_hint);
114
115int free_msg_buffer (struct msg_buffer *buffer);
116int msg_buffer_reach_limit (double ratio);
117double msg_buffer_usage (void);
118
119extern long long max_allocated_buffer_bytes;
120extern int allocated_buffer_chunks, max_allocated_buffer_chunks;
121