From ad541c67761b8aa6da1566802c347cac4018d0c2 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 2 Nov 2026 20:50:24 +0100 Subject: Move the build sources into src/ --- src/ot_mutex.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/ot_mutex.c (limited to 'src/ot_mutex.c') diff --git a/src/ot_mutex.c b/src/ot_mutex.c new file mode 100644 index 0000000..884b74c --- /dev/null +++ b/src/ot_mutex.c @@ -0,0 +1,70 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. */ + +/* System */ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Opentracker */ +#include "ot_iovec.h" +#include "ot_mutex.h" +#include "ot_stats.h" +#include "trackerlogic.h" + +/* #define MTX_DBG( STRING ) fprintf( stderr, STRING ) */ +#define MTX_DBG(STRING) + +/* Our global all torrents list */ +static ot_vector all_torrents[OT_BUCKET_COUNT]; +static pthread_mutex_t bucket_mutex[OT_BUCKET_COUNT]; +/* Every bucket's unlock adjusts this, and a bucket lock only keeps other + threads out of that one bucket, so the counter needs its own protection */ +static _Atomic size_t g_torrent_count; + +ot_vector *mutex_bucket_lock(int bucket) { + pthread_mutex_lock(bucket_mutex + bucket); + return all_torrents + bucket; +} + +/* Torrents are spread over buckets by the first four bytes of their info_hash, + which may sit at any alignment, hence the memcpy */ +static int bucket_from_hash(ot_hash const hash) { + uint32_t bucket; + memcpy(&bucket, hash, sizeof(bucket)); + return ntohl(bucket) >> OT_BUCKET_COUNT_SHIFT; +} + +ot_vector *mutex_bucket_lock_by_hash(ot_hash const hash) { return mutex_bucket_lock(bucket_from_hash(hash)); } + +void mutex_bucket_unlock(int bucket, int delta_torrentcount) { + pthread_mutex_unlock(bucket_mutex + bucket); + if (delta_torrentcount) + atomic_fetch_add_explicit(&g_torrent_count, (size_t)delta_torrentcount, memory_order_relaxed); +} + +void mutex_bucket_unlock_by_hash(ot_hash const hash, int delta_torrentcount) { + mutex_bucket_unlock(bucket_from_hash(hash), delta_torrentcount); +} + +size_t mutex_get_torrent_count(void) { return atomic_load_explicit(&g_torrent_count, memory_order_relaxed); } + +void mutex_init(void) { + size_t i; + for (i = 0; i < OT_BUCKET_COUNT; ++i) + pthread_mutex_init(bucket_mutex + i, NULL); + memset(all_torrents, 0, sizeof(all_torrents)); +} + +void mutex_deinit(void) { + size_t i; + for (i = 0; i < OT_BUCKET_COUNT; ++i) + pthread_mutex_destroy(bucket_mutex + i); + memset(all_torrents, 0, sizeof(all_torrents)); +} -- cgit v1.3