]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - scrub/counter.c
xfsprogs: Release v6.7.0
[thirdparty/xfsprogs-dev.git] / scrub / counter.c
CommitLineData
8d318d62 1// SPDX-License-Identifier: GPL-2.0-or-later
d11cc69e 2/*
52520522 3 * Copyright (C) 2018-2024 Oracle. All Rights Reserved.
8d318d62 4 * Author: Darrick J. Wong <djwong@kernel.org>
d11cc69e 5 */
a440f877 6#include "xfs.h"
d11cc69e
DW
7#include <stdint.h>
8#include <stdlib.h>
d11cc69e
DW
9#include <string.h>
10#include <assert.h>
11#include <pthread.h>
14051909 12#include "libfrog/ptvar.h"
d11cc69e
DW
13#include "counter.h"
14
15/*
16 * Per-Thread Counters
17 *
18 * This is a global counter object that uses per-thread counters to
19 * count things without having to content for a single shared lock.
20 * Provided we know the number of threads that will be accessing the
21 * counter, each thread gets its own thread-specific counter variable.
22 * Changing the value is fast, though retrieving the value is expensive
23 * and approximate.
24 */
25struct ptcounter {
26 struct ptvar *var;
27};
28
da3dd6c0
DW
29/* Allocate per-thread counter. */
30int
31ptcounter_alloc(
32 size_t nr,
33 struct ptcounter **pp)
d11cc69e
DW
34{
35 struct ptcounter *p;
cb321a39 36 int ret;
d11cc69e
DW
37
38 p = malloc(sizeof(struct ptcounter));
39 if (!p)
da3dd6c0 40 return errno;
2f4422f4 41 ret = -ptvar_alloc(nr, sizeof(uint64_t), &p->var);
cb321a39 42 if (ret) {
d11cc69e 43 free(p);
da3dd6c0 44 return ret;
d11cc69e 45 }
da3dd6c0
DW
46 *pp = p;
47 return 0;
d11cc69e
DW
48}
49
50/* Free per-thread counter. */
51void
52ptcounter_free(
53 struct ptcounter *ptc)
54{
55 ptvar_free(ptc->var);
56 free(ptc);
57}
58
59/* Add a quantity to the counter. */
da3dd6c0 60int
d11cc69e
DW
61ptcounter_add(
62 struct ptcounter *ptc,
63 int64_t nr)
64{
65 uint64_t *p;
cb321a39 66 int ret;
d11cc69e 67
cb321a39 68 p = ptvar_get(ptc->var, &ret);
da3dd6c0 69 if (ret)
2f4422f4 70 return -ret;
d11cc69e 71 *p += nr;
da3dd6c0 72 return 0;
d11cc69e
DW
73}
74
cb321a39 75static int
d11cc69e
DW
76ptcounter_val_helper(
77 struct ptvar *ptv,
78 void *data,
79 void *foreach_arg)
80{
81 uint64_t *sum = foreach_arg;
82 uint64_t *count = data;
83
84 *sum += *count;
cb321a39 85 return 0;
d11cc69e
DW
86}
87
88/* Return the approximate value of this counter. */
da3dd6c0 89int
d11cc69e 90ptcounter_value(
da3dd6c0
DW
91 struct ptcounter *ptc,
92 uint64_t *sum)
d11cc69e 93{
da3dd6c0 94 *sum = 0;
2f4422f4 95 return -ptvar_foreach(ptc->var, ptcounter_val_helper, sum);
d11cc69e 96}