]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - scrub/counter.c
4344492763c13f02aeec81436af0a7a046f9d556
[thirdparty/xfsprogs-dev.git] / scrub / counter.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2018 Oracle. All Rights Reserved.
4 * Author: Darrick J. Wong <darrick.wong@oracle.com>
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 /* Initialize per-thread counter. */
30 struct ptcounter *
31 ptcounter_init(
32 size_t nr)
33 {
34 struct ptcounter *p;
35
36 p = malloc(sizeof(struct ptcounter));
37 if (!p)
38 return NULL;
39 p->var = ptvar_init(nr, sizeof(uint64_t));
40 if (!p->var) {
41 free(p);
42 return NULL;
43 }
44 return p;
45 }
46
47 /* Free per-thread counter. */
48 void
49 ptcounter_free(
50 struct ptcounter *ptc)
51 {
52 ptvar_free(ptc->var);
53 free(ptc);
54 }
55
56 /* Add a quantity to the counter. */
57 void
58 ptcounter_add(
59 struct ptcounter *ptc,
60 int64_t nr)
61 {
62 uint64_t *p;
63
64 p = ptvar_get(ptc->var);
65 *p += nr;
66 }
67
68 static bool
69 ptcounter_val_helper(
70 struct ptvar *ptv,
71 void *data,
72 void *foreach_arg)
73 {
74 uint64_t *sum = foreach_arg;
75 uint64_t *count = data;
76
77 *sum += *count;
78 return true;
79 }
80
81 /* Return the approximate value of this counter. */
82 uint64_t
83 ptcounter_value(
84 struct ptcounter *ptc)
85 {
86 uint64_t sum = 0;
87
88 ptvar_foreach(ptc->var, ptcounter_val_helper, &sum);
89 return sum;
90 }