]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/counter.c
Remove use of LFS64 interfaces
[thirdparty/xfsprogs-dev.git] / scrub / counter.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2018-2024 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <djwong@kernel.org>
5 */
6 #include "xfs.h"
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <assert.h>
11 #include <pthread.h>
12 #include "libfrog/ptvar.h"
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 */
25 struct ptcounter {
26 struct ptvar *var;
27 };
28
29 /* Allocate per-thread counter. */
30 int
31 ptcounter_alloc(
32 size_t nr,
33 struct ptcounter **pp)
34 {
35 struct ptcounter *p;
36 int ret;
37
38 p = malloc(sizeof(struct ptcounter));
39 if (!p)
40 return errno;
41 ret = -ptvar_alloc(nr, sizeof(uint64_t), &p->var);
42 if (ret) {
43 free(p);
44 return ret;
45 }
46 *pp = p;
47 return 0;
48 }
49
50 /* Free per-thread counter. */
51 void
52 ptcounter_free(
53 struct ptcounter *ptc)
54 {
55 ptvar_free(ptc->var);
56 free(ptc);
57 }
58
59 /* Add a quantity to the counter. */
60 int
61 ptcounter_add(
62 struct ptcounter *ptc,
63 int64_t nr)
64 {
65 uint64_t *p;
66 int ret;
67
68 p = ptvar_get(ptc->var, &ret);
69 if (ret)
70 return -ret;
71 *p += nr;
72 return 0;
73 }
74
75 static int
76 ptcounter_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;
85 return 0;
86 }
87
88 /* Return the approximate value of this counter. */
89 int
90 ptcounter_value(
91 struct ptcounter *ptc,
92 uint64_t *sum)
93 {
94 *sum = 0;
95 return -ptvar_foreach(ptc->var, ptcounter_val_helper, sum);
96 }