[PATCH 1/4] libfrog: enhance ptvar to support initializer functions

Darrick J. Wong
2023-12-31T22:44:16Z

Modify the per-thread variable code to support passing in an initializer
function that will set up each thread's variable space when it is
claimed.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
libfrog/ptvar.c | 9 ++++++++-
libfrog/ptvar.h | 4 +++-
scrub/counter.c | 2 +-
scrub/descr.c | 2 +-
scrub/phase7.c | 2 +-
scrub/read_verify.c | 2 +-
6 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/libfrog/ptvar.c b/libfrog/ptvar.c
index 7ac8c541862..9d5ae6bc8e3 100644
--- a/libfrog/ptvar.c
+++ b/libfrog/ptvar.c
@@ -26,6 +26,7 @@
struct ptvar {
pthread_key_t key;
pthread_mutex_t lock;
+ ptvar_init_fn init_fn;
size_t nr_used;
size_t nr_counters;
size_t data_size;
@@ -38,6 +39,7 @@ int
ptvar_alloc(
size_t nr,
size_t size,
+ ptvar_init_fn init_fn,
struct ptvar **pptv)
{
struct ptvar *ptv;
@@ -58,6 +60,7 @@ ptvar_alloc(
ptv->data_size = size;
ptv->nr_counters = nr;
ptv->nr_used = 0;
+ ptv->init_fn = init_fn;
memset(ptv->data, 0, nr * size);
ret = -pthread_mutex_init(&ptv->lock, NULL);
if (ret)
@@ -98,11 +101,15 @@ ptvar_get(
if (!p) {
pthread_mutex_lock(&ptv->lock);
assert(ptv->nr_used < ptv->nr_counters);
- p = &ptv->data[(ptv->nr_used++) * ptv->data_size];
+ p = &ptv->data[ptv->nr_used * ptv->data_size];
ret = -pthread_setspecific(ptv->key, p);
if (ret)
goto out_unlock;
+ ptv->nr_used++;
pthread_mutex_unlock(&ptv->lock);
+
+ if (ptv->init_fn)
+ ptv->init_fn(p);
}
*retp = 0;
return p;
diff --git a/libfrog/ptvar.h b/libfrog/ptvar.h
index b7d02d6269e..e4a181ffe76 100644
--- a/libfrog/ptvar.h
+++ b/libfrog/ptvar.h
@@ -8,7 +8,9 @@

struct ptvar;

-int ptvar_alloc(size_t nr, size_t size, struct ptvar **pptv);
+typedef void (*ptvar_init_fn)(void *data);
+int ptvar_alloc(size_t nr, size_t size, ptvar_init_fn init_fn,
+ struct ptvar **pptv);
void ptvar_free(struct ptvar *ptv);
void *ptvar_get(struct ptvar *ptv, int *ret);

diff --git a/scrub/counter.c b/scrub/counter.c
index 2ee357f3a76..c903454c0dc 100644
--- a/scrub/counter.c
+++ b/scrub/counter.c
@@ -38,7 +38,7 @@ ptcounter_alloc(
p = malloc(sizeof(struct ptcounter));
if (!p)
return errno;
- ret = -ptvar_alloc(nr, sizeof(uint64_t), &p->var);
+ ret = -ptvar_alloc(nr, sizeof(uint64_t), NULL, &p->var);
if (ret) {
free(p);
return ret;
diff --git a/scrub/descr.c b/scrub/descr.c
index 77d5378ec3f..88ca5d95a78 100644
--- a/scrub/descr.c
+++ b/scrub/descr.c
@@ -89,7 +89,7 @@ descr_init_phase(
int ret;

assert(descr_ptvar == NULL);
- ret = -ptvar_alloc(nr_threads, DESCR_BUFSZ, &descr_ptvar);
+ ret = -ptvar_alloc(nr_threads, DESCR_BUFSZ, NULL, &descr_ptvar);
if (ret)
str_liberror(ctx, ret, _("creating description buffer"));

diff --git a/scrub/phase7.c b/scrub/phase7.c
index cd4501f72b7..cce5ede0012 100644
--- a/scrub/phase7.c
+++ b/scrub/phase7.c
@@ -136,7 +136,7 @@ phase7_func(
}

error = -ptvar_alloc(scrub_nproc(ctx), sizeof(struct summary_counts),
- &ptvar);
+ NULL, &ptvar);
if (error) {
str_liberror(ctx, error, _("setting up block counter"));
return error;
diff --git a/scrub/read_verify.c b/scrub/read_verify.c
index 29d7939549f..52348274be2 100644
--- a/scrub/read_verify.c
+++ b/scrub/read_verify.c
@@ -120,7 +120,7 @@ read_verify_pool_alloc(
rvp->disk = disk;
rvp->ioerr_fn = ioerr_fn;
ret = -ptvar_alloc(submitter_threads, sizeof(struct read_verify),
- &rvp->rvstate);
+ NULL, &rvp->rvstate);
if (ret)
goto out_counter;
ret = -workqueue_create(&rvp->wq, (struct xfs_mount *)rvp,