source: bin/varnishd/cache_shmlog.c @ 8aa1d8

Revision 8aa1d8, 6.9 KB checked in by Poul-Henning Kamp <phk@…>, 3 years ago (diff)

Eliminate nested <*.h> includes from include/*

Sort #includes according to rules which are for me to know and you
to guess.

  • Property mode set to 100644
Line 
1/*-
2 * Copyright (c) 2006 Verdens Gang AS
3 * Copyright (c) 2006-2011 Varnish Software AS
4 * All rights reserved.
5 *
6 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "config.h"
31
32#include <stdio.h>
33
34#include "cache.h"
35
36#include "vapi/vsm_int.h"
37#include "vmb.h"
38#include "vtim.h"
39
40/* These cannot be struct lock, which depends on vsm/vsl working */
41static pthread_mutex_t vsl_mtx;
42static pthread_mutex_t vsm_mtx;
43
44static uint32_t                 *vsl_start;
45static const uint32_t           *vsl_end;
46static uint32_t                 *vsl_ptr;
47
48static inline uint32_t
49vsl_w0(uint32_t type, uint32_t length)
50{
51
52        assert(length < 0x10000);
53        return (((type & 0xff) << 24) | length);
54}
55
56/*--------------------------------------------------------------------*/
57
58static inline void
59vsl_hdr(enum VSL_tag_e tag, uint32_t *p, unsigned len, unsigned id)
60{
61
62        assert(((uintptr_t)p & 0x3) == 0);
63
64        p[1] = id;
65        VMB();
66        p[0] = vsl_w0(tag, len);
67}
68
69/*--------------------------------------------------------------------*/
70
71static void
72vsl_wrap(void)
73{
74
75        assert(vsl_ptr >= vsl_start + 1);
76        assert(vsl_ptr < vsl_end);
77        vsl_start[1] = VSL_ENDMARKER;
78        do
79                vsl_start[0]++;
80        while (vsl_start[0] == 0);
81        VWMB();
82        if (vsl_ptr != vsl_start + 1) {
83                *vsl_ptr = VSL_WRAPMARKER;
84                vsl_ptr = vsl_start + 1;
85        }
86        VSC_C_main->shm_cycles++;
87}
88
89/*--------------------------------------------------------------------
90 * Reserve bytes for a record, wrap if necessary
91 */
92
93static uint32_t *
94vsl_get(unsigned len, unsigned records, unsigned flushes)
95{
96        uint32_t *p;
97
98        if (pthread_mutex_trylock(&vsl_mtx)) {
99                AZ(pthread_mutex_lock(&vsl_mtx));
100                VSC_C_main->shm_cont++;
101        }
102        assert(vsl_ptr < vsl_end);
103        assert(((uintptr_t)vsl_ptr & 0x3) == 0);
104
105        VSC_C_main->shm_writes++;
106        VSC_C_main->shm_flushes += flushes;
107        VSC_C_main->shm_records += records;
108
109        /* Wrap if necessary */
110        if (VSL_END(vsl_ptr, len) >= vsl_end)
111                vsl_wrap();
112
113        p = vsl_ptr;
114        vsl_ptr = VSL_END(vsl_ptr, len);
115
116        *vsl_ptr = VSL_ENDMARKER;
117
118        assert(vsl_ptr < vsl_end);
119        assert(((uintptr_t)vsl_ptr & 0x3) == 0);
120        AZ(pthread_mutex_unlock(&vsl_mtx));
121
122        return (p);
123}
124
125/*--------------------------------------------------------------------
126 * This variant copies a byte-range directly to the log, without
127 * taking the detour over sprintf()
128 */
129
130static void
131VSLR(enum VSL_tag_e tag, int id, const char *b, unsigned len)
132{
133        uint32_t *p;
134        unsigned mlen;
135
136        mlen = params->shm_reclen;
137
138        /* Truncate */
139        if (len > mlen)
140                len = mlen;
141
142        p = vsl_get(len, 1, 0);
143
144        memcpy(p + 2, b, len);
145        vsl_hdr(tag, p, len, id);
146}
147
148/*--------------------------------------------------------------------*/
149
150void
151VSL(enum VSL_tag_e tag, int id, const char *fmt, ...)
152{
153        va_list ap;
154        unsigned n, mlen = params->shm_reclen;
155        char buf[mlen];
156
157        /*
158         * XXX: consider formatting into a stack buffer then move into
159         * XXX: shmlog with VSLR().
160         */
161        AN(fmt);
162        va_start(ap, fmt);
163
164        if (strchr(fmt, '%') == NULL) {
165                VSLR(tag, id, fmt, strlen(fmt));
166        } else {
167                n = vsnprintf(buf, mlen, fmt, ap);
168                if (n > mlen)
169                        n = mlen;
170                VSLR(tag, id, buf, n);
171        }
172        va_end(ap);
173}
174
175/*--------------------------------------------------------------------*/
176
177void
178WSL_Flush(struct worker *w, int overflow)
179{
180        uint32_t *p;
181        unsigned l;
182
183        l = pdiff(w->wlb, w->wlp);
184        if (l == 0)
185                return;
186
187        assert(l >= 8);
188
189        p = vsl_get(l - 8, w->wlr, overflow);
190
191        memcpy(p + 1, w->wlb + 1, l - 4);
192        VWMB();
193        p[0] = w->wlb[0];
194        w->wlp = w->wlb;
195        w->wlr = 0;
196}
197
198/*--------------------------------------------------------------------*/
199
200void
201WSLR(struct worker *w, enum VSL_tag_e tag, int id, txt t)
202{
203        unsigned l, mlen;
204
205        Tcheck(t);
206        mlen = params->shm_reclen;
207
208        /* Truncate */
209        l = Tlen(t);
210        if (l > mlen) {
211                l = mlen;
212                t.e = t.b + l;
213        }
214
215        assert(w->wlp < w->wle);
216
217        /* Wrap if necessary */
218        if (VSL_END(w->wlp, l) >= w->wle)
219                WSL_Flush(w, 1);
220        assert (VSL_END(w->wlp, l) < w->wle);
221        memcpy(VSL_DATA(w->wlp), t.b, l);
222        vsl_hdr(tag, w->wlp, l, id);
223        w->wlp = VSL_END(w->wlp, l);
224        assert(w->wlp < w->wle);
225        w->wlr++;
226        if (params->diag_bitmap & 0x10000)
227                WSL_Flush(w, 0);
228}
229
230/*--------------------------------------------------------------------*/
231
232void
233WSL(struct worker *w, enum VSL_tag_e tag, int id, const char *fmt, ...)
234{
235        va_list ap;
236        char *p;
237        unsigned n, mlen;
238        txt t;
239
240        AN(fmt);
241        va_start(ap, fmt);
242        mlen = params->shm_reclen;
243
244        if (strchr(fmt, '%') == NULL) {
245                t.b = TRUST_ME(fmt);
246                t.e = strchr(t.b, '\0');
247                WSLR(w, tag, id, t);
248        } else {
249                assert(w->wlp < w->wle);
250
251                /* Wrap if we cannot fit a full size record */
252                if (VSL_END(w->wlp, mlen) >= w->wle)
253                        WSL_Flush(w, 1);
254
255                p = VSL_DATA(w->wlp);
256                n = vsnprintf(p, mlen, fmt, ap);
257                if (n > mlen)
258                        n = mlen;       /* we truncate long fields */
259                vsl_hdr(tag, w->wlp, n, id);
260                w->wlp = VSL_END(w->wlp, n);
261                assert(w->wlp < w->wle);
262                w->wlr++;
263        }
264        va_end(ap);
265        if (params->diag_bitmap & 0x10000)
266                WSL_Flush(w, 0);
267}
268
269/*--------------------------------------------------------------------*/
270
271void
272VSL_Init(void)
273{
274        struct VSM_chunk *vsc;
275
276        AZ(pthread_mutex_init(&vsl_mtx, NULL));
277        AZ(pthread_mutex_init(&vsm_mtx, NULL));
278
279        VSM__Clean();
280
281        VSM_ITER(vsc)
282                if (!strcmp(vsc->class, VSL_CLASS))
283                        break;
284        AN(vsc);
285        vsl_start = VSM_PTR(vsc);
286        vsl_end = VSM_NEXT(vsc);
287        vsl_ptr = vsl_start + 1;
288
289        vsl_wrap();
290        VSM_head->starttime = (intmax_t)VTIM_real();
291        memset(VSM_head->panicstr, '\0', sizeof *VSM_head->panicstr);
292        memset(VSC_C_main, 0, sizeof *VSC_C_main);
293        VSM_head->child_pid = getpid();
294}
295
296/*--------------------------------------------------------------------*/
297
298void *
299VSM_Alloc(unsigned size, const char *class, const char *type,
300    const char *ident)
301{
302        void *p;
303
304        AZ(pthread_mutex_lock(&vsm_mtx));
305        p = VSM__Alloc(size, class, type, ident);
306        AZ(pthread_mutex_unlock(&vsm_mtx));
307        return (p);
308}
309
310void
311VSM_Free(const void *ptr)
312{
313
314        AZ(pthread_mutex_lock(&vsm_mtx));
315        VSM__Free(ptr);
316        AZ(pthread_mutex_unlock(&vsm_mtx));
317}
Note: See TracBrowser for help on using the repository browser.