source: bin/varnishd/cache_lck.c @ ac393c

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

Revamp the code which rides herd on the thread pools:

Make one single thread, which creates thread pools, and since that
is not particularly ardous work, also have it maintain the stats
gauge of number of sessions queued.

(Removing pools should now be possible, but the code is not there yet.)

Each pool has its own herder thread, which creates and destroys
threads as required, and updates stats for dropped and queued
sessions.

Sanitize VSC fields associated with this area.

  • Property mode set to 100644
RevLine 
[cf3f54d]1/*-
[c11726]2 * Copyright (c) 2008-2010 Varnish Software AS
[cf3f54d]3 * All rights reserved.
4 *
5 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * The geniuses who came up with pthreads did not think operations like
29 * pthread_assert_mutex_held() were important enough to include them in
30 * the API.
31 *
32 * Build our own locks on top of pthread mutexes and hope that the next
33 * civilization is better at such crucial details than this one.
34 */
35
36#include "config.h"
37
38#include <stdio.h>
39
40#include <stdlib.h>
41
42#include "cache.h"
43
[c5980b]44/*The constability of lck depends on platform pthreads implementation */
45
[cf3f54d]46struct ilck {
47        unsigned                magic;
48#define ILCK_MAGIC              0x7b86c8a5
49        pthread_mutex_t         mtx;
[df54a2]50        int                     held;
[cf3f54d]51        pthread_t               owner;
52        VTAILQ_ENTRY(ilck)      list;
53        const char              *w;
[9c86e0]54        struct VSC_C_lck        *stat;
[cf3f54d]55};
56
57static VTAILQ_HEAD(, ilck)      ilck_head =
58    VTAILQ_HEAD_INITIALIZER(ilck_head);
59
60static pthread_mutex_t          lck_mtx;
61
[302dca7]62void __match_proto__()
[cf3f54d]63Lck__Lock(struct lock *lck, const char *p, const char *f, int l)
64{
65        struct ilck *ilck;
66        int r;
67
68        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
69        if (!(params->diag_bitmap & 0x18)) {
70                AZ(pthread_mutex_lock(&ilck->mtx));
[df54a2]71                AZ(ilck->held);
[7b3607]72                ilck->stat->locks++;
[cf3f54d]73                ilck->owner = pthread_self();
[df54a2]74                ilck->held = 1;
[cf3f54d]75                return;
76        }
77        r = pthread_mutex_trylock(&ilck->mtx);
[535cc8]78        assert(r == 0 || r == EBUSY);
[cf3f54d]79        if (r) {
[7b3607]80                ilck->stat->colls++;
81                if (params->diag_bitmap & 0x8)
82                        VSL(SLT_Debug, 0, "MTX_CONTEST(%s,%s,%d,%s)",
83                            p, f, l, ilck->w);
[cf3f54d]84                AZ(pthread_mutex_lock(&ilck->mtx));
85        } else if (params->diag_bitmap & 0x8) {
86                VSL(SLT_Debug, 0, "MTX_LOCK(%s,%s,%d,%s)", p, f, l, ilck->w);
87        }
[df54a2]88        AZ(ilck->held);
[7b3607]89        ilck->stat->locks++;
[cf3f54d]90        ilck->owner = pthread_self();
[df54a2]91        ilck->held = 1;
[cf3f54d]92}
93
[302dca7]94void __match_proto__()
[cf3f54d]95Lck__Unlock(struct lock *lck, const char *p, const char *f, int l)
96{
97        struct ilck *ilck;
98
99        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
[df54a2]100        assert(pthread_equal(ilck->owner, pthread_self()));
101        AN(ilck->held);
102        ilck->held = 0;
[cf3f54d]103        AZ(pthread_mutex_unlock(&ilck->mtx));
104        if (params->diag_bitmap & 0x8)
105                VSL(SLT_Debug, 0, "MTX_UNLOCK(%s,%s,%d,%s)", p, f, l, ilck->w);
106}
107
[302dca7]108int __match_proto__()
[cf3f54d]109Lck__Trylock(struct lock *lck, const char *p, const char *f, int l)
110{
111        struct ilck *ilck;
112        int r;
113
114        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
[1840220]115        r = pthread_mutex_trylock(&ilck->mtx);
116        assert(r == 0 || r == EBUSY);
[cf3f54d]117        if (params->diag_bitmap & 0x8)
118                VSL(SLT_Debug, 0,
119                    "MTX_TRYLOCK(%s,%s,%d,%s) = %d", p, f, l, ilck->w);
120        if (r == 0) {
[df54a2]121                AZ(ilck->held);
122                ilck->held = 1;
[cf3f54d]123                ilck->owner = pthread_self();
124        }
125        return (r);
126}
127
128void
[f1bccf]129Lck__Assert(const struct lock *lck, int held)
[cf3f54d]130{
131        struct ilck *ilck;
132
133        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
134        if (held)
[df54a2]135                assert(ilck->held &&
136                    pthread_equal(ilck->owner, pthread_self()));
[cf3f54d]137        else
[df54a2]138                assert(!ilck->held ||
139                    !pthread_equal(ilck->owner, pthread_self()));
[cf3f54d]140}
141
[ac393c]142int __match_proto__()
143Lck_CondWait(pthread_cond_t *cond, struct lock *lck, struct timespec *ts)
[cf3f54d]144{
145        struct ilck *ilck;
[ac393c]146        int retval = 0;
[cf3f54d]147
148        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
[df54a2]149        AN(ilck->held);
150        assert(pthread_equal(ilck->owner, pthread_self()));
151        ilck->held = 0;
[ac393c]152        if (ts == NULL) {
153                AZ(pthread_cond_wait(cond, &ilck->mtx));
154        } else {
155                retval = pthread_cond_timedwait(cond, &ilck->mtx, ts);
156                assert(retval == 0 || retval == ETIMEDOUT);
157        }
[df54a2]158        AZ(ilck->held);
[2a1c6b]159        ilck->held = 1;
[cf3f54d]160        ilck->owner = pthread_self();
[ac393c]161        return (retval);
[cf3f54d]162}
163
164void
[9c86e0]165Lck__New(struct lock *lck, struct VSC_C_lck *st, const char *w)
[cf3f54d]166{
167        struct ilck *ilck;
168
[195fa5]169        AN(st);
[cf3f54d]170        AZ(lck->priv);
171        ALLOC_OBJ(ilck, ILCK_MAGIC);
172        AN(ilck);
173        ilck->w = w;
[7b3607]174        ilck->stat = st;
175        ilck->stat->creat++;
[cf3f54d]176        AZ(pthread_mutex_init(&ilck->mtx, NULL));
177        AZ(pthread_mutex_lock(&lck_mtx));
178        VTAILQ_INSERT_TAIL(&ilck_head, ilck, list);
179        AZ(pthread_mutex_unlock(&lck_mtx));
180        lck->priv = ilck;
181}
182
183void
184Lck_Delete(struct lock *lck)
185{
186        struct ilck *ilck;
187
188        CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
[7b3607]189        ilck->stat->destroy++;
[cf3f54d]190        lck->priv = NULL;
191        AZ(pthread_mutex_lock(&lck_mtx));
192        VTAILQ_REMOVE(&ilck_head, ilck, list);
193        AZ(pthread_mutex_unlock(&lck_mtx));
194        AZ(pthread_mutex_destroy(&ilck->mtx));
195        FREE_OBJ(ilck);
196}
197
[9c86e0]198#define LOCK(nam) struct VSC_C_lck *lck_##nam;
[7b3607]199#include "locks.h"
200#undef LOCK
[cf3f54d]201
202void
203LCK_Init(void)
204{
205
206        AZ(pthread_mutex_init(&lck_mtx, NULL));
[769477]207#define LOCK(nam)                                               \
[9c86e0]208        lck_##nam = VSM_Alloc(sizeof(struct VSC_C_lck),         \
[7b3607]209           VSC_CLASS, VSC_TYPE_LCK, #nam);
210#include "locks.h"
211#undef LOCK
[cf3f54d]212}
Note: See TracBrowser for help on using the repository browser.