Files
git/lib/trace2/tr2_ctr.h
Patrick Steinhardt 9759608622 Move libgit.a sources into separate "lib/" directory
The Git project is not exactly the easiest project to get started in:
it's written in C and POSIX shell, with bits of Perl, Rust and other
languages sprinkled into it. On top of that, the project has grown
somewhat organically over time, making the codebase hard to navigate.

These are problems that we're aware of, and there have been and still
are efforts to clean up some of the technical debt that is natural to
exist an a project that is more than 20 years old. Furthermore, we
provide resources to newcomers that help them out like our coding
guidelines, code of conduct or "MyFirstContribution.adoc".

But there is a rather practical problem: finding your way around in our
project's tree is not easy. Doing a directory listing in the top-level
directory will present you with more than 550 files, which makes it
extremely hard for a newcomer to figure out what files they are even
supposed to look at. This makes the onboarding experience somewhat
harder than it really needs to be. This isn't only a problem for
newcomers though, as I myself struggle to find the files I am looking
for because of the sheer number of files.

Besides the problem of discoverability it also creates a problem of
structure. It is not obvious at all which files are part of "libgit.a"
and which files are only linked into our final executables. So while we
have this split in our build systems, that split is not evident at all
in our tree.

Introduce a new "lib/" directory and move all of our sources for
"libgit.a" into it to fix these issues. It makes the split we have
evident and reduces the number of files in our top-level tree from 550
files to ~80 files.

This is still a lot of files, but it's significantly easier to navigate
already. Furthermore, we can further iterate after this step and think
about introducing a better structure for remaining files, as well.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-22 10:58:23 -07:00

105 lines
3.1 KiB
C

#ifndef TR2_CTR_H
#define TR2_CTR_H
#include "trace2.h"
#include "trace2/tr2_tgt.h"
/*
* Define a mechanism to allow global "counters".
*
* Counters can be used count interesting activity that does not fit
* the "region and data" model, such as code called from many
* different regions and/or where you want to count a number of items,
* but don't have control of when the last item will be processed,
* such as counter the number of calls to `lstat()`.
*
* Counters differ from Trace2 "data" events. Data events are emitted
* immediately and are appropriate for documenting loop counters at
* the end of a region, for example. Counter values are accumulated
* during the program and final counter values are emitted at program
* exit.
*
* To make this model efficient, we define a compile-time fixed set of
* counters and counter ids using a fixed size "counter block" array
* in thread-local storage. This gives us constant time, lock-free
* access to each counter within each thread. This lets us avoid the
* complexities of dynamically allocating a counter and sharing that
* definition with other threads.
*
* Each thread uses the counter block in its thread-local storage to
* increment partial sums for each counter (without locking). When a
* thread exits, those partial sums are (under lock) added to the
* global final sum.
*
* Partial sums for each counter are optionally emitted when a thread
* exits.
*
* Final sums for each counter are emitted between the "exit" and
* "atexit" events.
*
* A parallel "counter metadata" table contains the "category" and
* "name" fields for each counter. This eliminates the need to
* include those args in the various counter APIs.
*/
/*
* The definition of an individual counter as used by an individual
* thread (and later in aggregation).
*/
struct tr2_counter {
uint64_t value;
};
/*
* Metadata for a counter.
*/
struct tr2_counter_metadata {
const char *category;
const char *name;
/*
* True if we should emit per-thread events for this counter
* when individual threads exit.
*/
unsigned int want_per_thread_events:1;
};
/*
* A compile-time fixed block of counters to insert into thread-local
* storage. This wrapper is used to avoid quirks of C and the usual
* need to pass an array size argument.
*/
struct tr2_counter_block {
struct tr2_counter counter[TRACE2_NUMBER_OF_COUNTERS];
};
/*
* Private routines used by trace2.c to increment a counter for the
* current thread.
*/
void tr2_counter_increment(enum trace2_counter_id cid, uint64_t value);
/*
* Add the current thread's counter data to the global totals.
* This is called during thread-exit.
*
* Caller must be holding the tr2tls_mutex.
*/
void tr2_update_final_counters(void);
/*
* Emit per-thread counter data for the current thread.
* This is called during thread-exit.
*/
void tr2_emit_per_thread_counters(tr2_tgt_evt_counter_t *fn_apply);
/*
* Emit global counter values.
* This is called during atexit handling.
*
* Caller must be holding the tr2tls_mutex.
*/
void tr2_emit_final_counters(tr2_tgt_evt_counter_t *fn_apply);
#endif /* TR2_CTR_H */