From 1032681af07bf685737786fd1c5cc852f7c055c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 4 Jun 2025 17:54:20 +0200 Subject: [PATCH 1/2] Convert the isc/tid.h to use own signed integer isc_tid_t type Change the internal type used for isc_tid unit to isc_tid_t to hide the specific integer type being used for the 'tid'. Internally, the signed integer type is being used. This allows us to have negatively indexed arrays that works both for threads with assigned tid and the threads with unassigned tid. This should be used only in specific situations. --- lib/dns/badcache.c | 4 +- lib/dns/dispatch.c | 18 +++--- lib/dns/include/dns/qp.h | 2 +- lib/dns/include/dns/validator.h | 2 +- lib/dns/include/dns/zone.h | 2 +- lib/dns/qp.c | 3 +- lib/dns/request.c | 10 +-- lib/dns/resolver.c | 2 +- lib/dns/unreachcache.c | 6 +- lib/dns/zone.c | 6 +- lib/isc/include/isc/loop.h | 2 +- lib/isc/include/isc/netmgr.h | 2 +- lib/isc/include/isc/refcount.h | 106 +++++++++++++++++--------------- lib/isc/include/isc/tid.h | 16 +++-- lib/isc/include/isc/uv.h | 8 +-- lib/isc/loop.c | 10 +-- lib/isc/loop_p.h | 2 +- lib/isc/netmgr/http.c | 6 +- lib/isc/netmgr/netmgr-int.h | 8 +-- lib/isc/netmgr/netmgr.c | 12 ++-- lib/isc/netmgr/proxyudp.c | 2 +- lib/isc/netmgr/streamdns.c | 2 +- lib/isc/netmgr/tcp.c | 2 +- lib/isc/netmgr/tlsstream.c | 6 +- lib/isc/netmgr/udp.c | 2 +- lib/isc/tid.c | 10 +-- lib/ns/client.c | 3 +- lib/ns/include/ns/client.h | 5 +- lib/ns/interfacemgr.c | 5 +- tests/bench/qpmulti.c | 8 +-- tests/dns/dispatch_test.c | 2 +- tests/isc/async_test.c | 4 +- tests/isc/netmgr_common.h | 9 +-- tests/isc/work_test.c | 4 +- 34 files changed, 152 insertions(+), 139 deletions(-) diff --git a/lib/dns/badcache.c b/lib/dns/badcache.c index 47d3b81236..a474d182e6 100644 --- a/lib/dns/badcache.c +++ b/lib/dns/badcache.c @@ -254,7 +254,7 @@ dns_badcache_add(dns_badcache_t *bc, const dns_name_t *name, REQUIRE(name != NULL); isc_loop_t *loop = isc_loop(); - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); struct cds_list_head *lru = &bc->lru[tid]; isc_stdtime_t now = isc_stdtime_now(); @@ -320,7 +320,7 @@ dns_badcache_find(dns_badcache_t *bc, const dns_name_t *name, } } - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); struct cds_list_head *lru = &bc->lru[tid]; bcentry_purge(ht, lru, now); diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index c7e99bfb56..9f5f8a8eed 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -110,7 +110,7 @@ struct dns_dispentry { struct dns_dispatch { /* Unlocked. */ unsigned int magic; /*%< magic */ - uint32_t tid; + isc_tid_t tid; isc_socktype_t socktype; isc_refcount_t references; isc_mem_t *mctx; @@ -186,7 +186,7 @@ static void dispentry_cancel(dns_dispentry_t *resp, isc_result_t result); static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, - uint32_t tid, dns_dispatch_t **dispp); + isc_tid_t tid, dns_dispatch_t **dispp); static void udp_startrecv(isc_nmhandle_t *handle, dns_dispentry_t *resp); static void @@ -1102,7 +1102,7 @@ dns_dispatchmgr_getnetmgr(dns_dispatchmgr_t *mgr) { * Allocate and set important limits. */ static void -dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, uint32_t tid, +dispatch_allocate(dns_dispatchmgr_t *mgr, isc_socktype_t type, isc_tid_t tid, dns_dispatch_t **dispp) { dns_dispatch_t *disp = NULL; @@ -1168,7 +1168,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, dns_transport_t *transport, dns_dispatchopt_t options, dns_dispatch_t **dispp) { dns_dispatch_t *disp = NULL; - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(destaddr != NULL); @@ -1229,7 +1229,7 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *destaddr, dns_dispatch_t *disp_connected = NULL; dns_dispatch_t *disp_fallback = NULL; isc_result_t result = ISC_R_NOTFOUND; - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); REQUIRE(VALID_DISPATCHMGR(mgr)); REQUIRE(destaddr != NULL); @@ -1326,7 +1326,7 @@ dns_dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, const isc_sockaddr_t *localaddr, - uint32_t tid, dns_dispatch_t **dispp) { + isc_tid_t tid, dns_dispatch_t **dispp) { isc_result_t result = ISC_R_SUCCESS; dns_dispatch_t *disp = NULL; isc_sockaddr_t sa_any; @@ -1379,7 +1379,7 @@ dispatch_destroy_rcu(struct rcu_head *rcu_head) { static void dispatch_destroy(dns_dispatch_t *disp) { dns_dispatchmgr_t *mgr = disp->mgr; - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); disp->magic = 0; @@ -2237,14 +2237,14 @@ dns_dispentry_getlocaladdress(dns_dispentry_t *resp, isc_sockaddr_t *addrp) { dns_dispatch_t * dns_dispatchset_get(dns_dispatchset_t *dset) { - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); /* check that dispatch set is configured */ if (dset == NULL || dset->ndisp == 0) { return NULL; } - INSIST(tid < dset->ndisp); + INSIST((uint32_t)tid < dset->ndisp); return dset->dispatches[tid]; } diff --git a/lib/dns/include/dns/qp.h b/lib/dns/include/dns/qp.h index d72730c80a..bbac5ca6fb 100644 --- a/lib/dns/include/dns/qp.h +++ b/lib/dns/include/dns/qp.h @@ -150,7 +150,7 @@ typedef struct dns_qpreader { */ typedef struct dns_qpread { DNS_QPREADER_FIELDS; - uint32_t tid; + isc_tid_t tid; } dns_qpread_t; /*% diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h index 6132ad88ec..ba50a827f2 100644 --- a/lib/dns/include/dns/validator.h +++ b/lib/dns/include/dns/validator.h @@ -76,7 +76,7 @@ struct dns_validator { unsigned int magic; dns_view_t *view; isc_loop_t *loop; - uint32_t tid; + isc_tid_t tid; isc_refcount_t references; /* Name and type of the response to be validated. */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 20b5f885b1..50f65c1921 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -145,7 +145,7 @@ typedef enum { ***/ void -dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid); +dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, isc_tid_t tid); /*%< * Creates a new empty zone and attach '*zonep' to it. * diff --git a/lib/dns/qp.c b/lib/dns/qp.c index d2a8963162..e0b709338b 100644 --- a/lib/dns/qp.c +++ b/lib/dns/qp.c @@ -86,7 +86,8 @@ static atomic_uint_fast64_t rollback_time; if (isc_log_wouldlog(ISC_LOG_DEBUG(7))) { \ isc_log_write(DNS_LOGCATEGORY_DATABASE, \ DNS_LOGMODULE_QP, ISC_LOG_DEBUG(7), \ - "%s:%d:%s(qp %p uctx \"%s\"):t%u: " fmt, \ + "%s:%d:%s(qp %p uctx \"%s\"):t%" PRItid \ + ": " fmt, \ __FILE__, __LINE__, __func__, qp, \ qp ? TRIENAME(qp) : "(null)", isc_tid(), \ ##__VA_ARGS__); \ diff --git a/lib/dns/request.c b/lib/dns/request.c index 3d8da41d08..b6913a901a 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -67,7 +67,7 @@ struct dns_request { int32_t flags; isc_loop_t *loop; - unsigned int tid; + isc_tid_t tid; isc_result_t result; isc_job_cb cb; @@ -172,10 +172,10 @@ dns_requestmgr_create(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, static void requests_cancel(void *arg) { dns_requestmgr_t *requestmgr = arg; - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); ISC_LIST_FOREACH (requestmgr->requests[tid], request, link) { - req_log(ISC_LOG_DEBUG(3), "%s(%" PRIu32 ": request %p", + req_log(ISC_LOG_DEBUG(3), "%s(%" PRItid ": request %p", __func__, tid, request); if (DNS_REQUEST_COMPLETE(request)) { /* The callback has been already scheduled */ @@ -210,12 +210,12 @@ dns_requestmgr_shutdown(dns_requestmgr_t *requestmgr) { */ synchronize_rcu(); - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); uint32_t nloops = isc_loopmgr_nloops(requestmgr->loopmgr); for (size_t i = 0; i < nloops; i++) { dns_requestmgr_ref(requestmgr); - if (i == tid) { + if (i == (uint32_t)tid) { /* Run the current loop synchronously */ requests_cancel(requestmgr); continue; diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index af4be39a4b..749754a274 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -342,7 +342,7 @@ struct fetchctx { isc_stdtime_t now; isc_loop_t *loop; - unsigned int tid; + isc_tid_t tid; dns_edectx_t edectx; diff --git a/lib/dns/unreachcache.c b/lib/dns/unreachcache.c index efbfd86053..a0e852ccca 100644 --- a/lib/dns/unreachcache.c +++ b/lib/dns/unreachcache.c @@ -291,7 +291,7 @@ dns_unreachcache_add(dns_unreachcache_t *uc, const isc_sockaddr_t *remote, REQUIRE(local != NULL); isc_loop_t *loop = isc_loop(); - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); struct cds_list_head *lru = &uc->lru[tid]; isc_stdtime_t now = isc_stdtime_now(); isc_stdtime_t expire = now + uc->expire_min_s; @@ -377,7 +377,7 @@ dns_unreachcache_find(dns_unreachcache_t *uc, const isc_sockaddr_t *remote, result = ISC_R_SUCCESS; } - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); struct cds_list_head *lru = &uc->lru[tid]; ucentry_purge(ht, lru, now); @@ -410,7 +410,7 @@ dns_unreachcache_remove(dns_unreachcache_t *uc, const isc_sockaddr_t *remote, ucentry_evict(ht, found); } - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); struct cds_list_head *lru = &uc->lru[tid]; ucentry_purge(ht, lru, now); diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 86eda3409f..52c897c2a7 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -288,7 +288,7 @@ struct dns_zone { isc_rwlock_t dblock; dns_db_t *db; /* Locked by dblock */ - unsigned int tid; + isc_tid_t tid; /* Locked */ dns_zonemgr_t *zmgr; @@ -1124,7 +1124,7 @@ inc_stats(dns_zone_t *zone, isc_statscounter_t counter) { ***/ void -dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, unsigned int tid) { +dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx, isc_tid_t tid) { isc_time_t now; dns_zone_t *zone = NULL; @@ -19239,7 +19239,7 @@ isc_result_t dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) { isc_mem_t *mctx = NULL; dns_zone_t *zone = NULL; - unsigned int tid; + isc_tid_t tid; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(zonep != NULL && *zonep == NULL); diff --git a/lib/isc/include/isc/loop.h b/lib/isc/include/isc/loop.h index ae263d4e83..2552548c36 100644 --- a/lib/isc/include/isc/loop.h +++ b/lib/isc/include/isc/loop.h @@ -155,7 +155,7 @@ isc_loop_main(isc_loopmgr_t *loopmgr); */ isc_loop_t * -isc_loop_get(isc_loopmgr_t *loopmgr, uint32_t tid); +isc_loop_get(isc_loopmgr_t *loopmgr, isc_tid_t tid); /*%< * Return the loop object associated with the 'tid' threadid * diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 8825c8c77d..14987514ea 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -917,7 +917,7 @@ isc_nm_verify_tls_peer_result_string(const isc_nmhandle_t *handle); */ void -isc__nm_force_tid(int tid); +isc__nm_force_tid(isc_tid_t tid); /*%< * Force the thread ID to 'tid'. This is STRICTLY for use in unit * tests and should not be used in any production code. diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h index eb4efed401..77763ff505 100644 --- a/lib/isc/include/isc/refcount.h +++ b/lib/isc/include/isc/refcount.h @@ -133,57 +133,61 @@ typedef atomic_uint_fast32_t isc_refcount_t; #define ISC_REFCOUNT_STATIC_TRACE_DECL(name) \ ISC__REFCOUNT_TRACE_DECL(name, static inline) -#define ISC__REFCOUNT_TRACE_IMPL(name, destroy, stat) \ - stat name##_t *name##__ref(name##_t *ptr, const char *func, \ - const char *file, unsigned int line) { \ - REQUIRE(ptr != NULL); \ - uint_fast32_t refs = \ - isc_refcount_increment(&ptr->references) + 1; \ - fprintf(stderr, \ - "%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \ - __func__, func, file, line, isc_tid(), ptr, refs); \ - return (ptr); \ - } \ - \ - stat void name##__unref(name##_t *ptr, const char *func, \ - const char *file, unsigned int line) { \ - REQUIRE(ptr != NULL); \ - uint_fast32_t refs = \ - isc_refcount_decrement(&ptr->references) - 1; \ - if (refs == 0) { \ - isc_refcount_destroy(&ptr->references); \ - destroy(ptr); \ - } \ - fprintf(stderr, \ - "%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \ - __func__, func, file, line, isc_tid(), ptr, refs); \ - } \ - stat void name##__attach(name##_t *ptr, name##_t **ptrp, \ - const char *func, const char *file, \ - unsigned int line) { \ - REQUIRE(ptrp != NULL && *ptrp == NULL); \ - uint_fast32_t refs = \ - isc_refcount_increment(&ptr->references) + 1; \ - fprintf(stderr, \ - "%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \ - __func__, func, file, line, isc_tid(), ptr, refs); \ - *ptrp = ptr; \ - } \ - \ - stat void name##__detach(name##_t **ptrp, const char *func, \ - const char *file, unsigned int line) { \ - REQUIRE(ptrp != NULL && *ptrp != NULL); \ - name##_t *ptr = *ptrp; \ - *ptrp = NULL; \ - uint_fast32_t refs = \ - isc_refcount_decrement(&ptr->references) - 1; \ - if (refs == 0) { \ - isc_refcount_destroy(&ptr->references); \ - destroy(ptr); \ - } \ - fprintf(stderr, \ - "%s:%s:%s:%u:t%u:%p->references = %" PRIuFAST32 "\n", \ - __func__, func, file, line, isc_tid(), ptr, refs); \ +#define ISC__REFCOUNT_TRACE_IMPL(name, destroy, stat) \ + stat name##_t *name##__ref(name##_t *ptr, const char *func, \ + const char *file, unsigned int line) { \ + REQUIRE(ptr != NULL); \ + uint_fast32_t refs = \ + isc_refcount_increment(&ptr->references) + 1; \ + fprintf(stderr, \ + "%s:%s:%s:%u:t%" PRItid \ + ":%p->references = %" PRIuFAST32 "\n", \ + __func__, func, file, line, isc_tid(), ptr, refs); \ + return (ptr); \ + } \ + \ + stat void name##__unref(name##_t *ptr, const char *func, \ + const char *file, unsigned int line) { \ + REQUIRE(ptr != NULL); \ + uint_fast32_t refs = \ + isc_refcount_decrement(&ptr->references) - 1; \ + if (refs == 0) { \ + isc_refcount_destroy(&ptr->references); \ + destroy(ptr); \ + } \ + fprintf(stderr, \ + "%s:%s:%s:%u:t%" PRItid \ + ":%p->references = %" PRIuFAST32 "\n", \ + __func__, func, file, line, isc_tid(), ptr, refs); \ + } \ + stat void name##__attach(name##_t *ptr, name##_t **ptrp, \ + const char *func, const char *file, \ + unsigned int line) { \ + REQUIRE(ptrp != NULL && *ptrp == NULL); \ + uint_fast32_t refs = \ + isc_refcount_increment(&ptr->references) + 1; \ + fprintf(stderr, \ + "%s:%s:%s:%u:t%" PRItid \ + ":%p->references = %" PRIuFAST32 "\n", \ + __func__, func, file, line, isc_tid(), ptr, refs); \ + *ptrp = ptr; \ + } \ + \ + stat void name##__detach(name##_t **ptrp, const char *func, \ + const char *file, unsigned int line) { \ + REQUIRE(ptrp != NULL && *ptrp != NULL); \ + name##_t *ptr = *ptrp; \ + *ptrp = NULL; \ + uint_fast32_t refs = \ + isc_refcount_decrement(&ptr->references) - 1; \ + if (refs == 0) { \ + isc_refcount_destroy(&ptr->references); \ + destroy(ptr); \ + } \ + fprintf(stderr, \ + "%s:%s:%s:%u:t%" PRItid \ + ":%p->references = %" PRIuFAST32 "\n", \ + __func__, func, file, line, isc_tid(), ptr, refs); \ } #define ISC_REFCOUNT_TRACE_IMPL(name, destroy) \ diff --git a/lib/isc/include/isc/tid.h b/lib/isc/include/isc/tid.h index 318d09a6fd..b506205979 100644 --- a/lib/isc/include/isc/tid.h +++ b/lib/isc/include/isc/tid.h @@ -17,17 +17,21 @@ #include -#define ISC_TID_UNKNOWN UINT32_MAX +typedef int32_t isc_tid_t; -uint32_t +#define PRItid PRId32 + +#define ISC_TID_UNKNOWN (isc_tid_t) - 1 + +isc_tid_t isc_tid_count(void); /*%< * Returns the number of threads. */ -extern thread_local uint32_t isc__tid_local; +extern thread_local isc_tid_t isc__tid_local; -static inline uint32_t +static inline isc_tid_t isc_tid(void) { return isc__tid_local; } @@ -38,7 +42,7 @@ isc_tid(void) { /* Private */ void -isc__tid_init(uint32_t tid); +isc__tid_init(isc_tid_t tid); void -isc__tid_initcount(uint32_t count); +isc__tid_initcount(isc_tid_t count); diff --git a/lib/isc/include/isc/uv.h b/lib/isc/include/isc/uv.h index 541f697b1b..7acbc8b693 100644 --- a/lib/isc/include/isc/uv.h +++ b/lib/isc/include/isc/uv.h @@ -77,7 +77,7 @@ isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, #define uv_idle_init(loop, idle) \ ({ \ int __r = uv_idle_init(loop, idle); \ - fprintf(stderr, "%" PRIu32 ":%s_:uv_idle_init(%p, %p)\n", \ + fprintf(stderr, "%" PRItid ":%s_:uv_idle_init(%p, %p)\n", \ isc_tid(), __func__, loop, idle); \ __r; \ }) @@ -85,7 +85,7 @@ isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, #define uv_timer_init(loop, timer) \ ({ \ int __r = uv_timer_init(loop, timer); \ - fprintf(stderr, "%" PRIu32 ":%s_:uv_timer_init(%p, %p)\n", \ + fprintf(stderr, "%" PRItid ":%s_:uv_timer_init(%p, %p)\n", \ isc_tid(), __func__, loop, timer); \ __r; \ }) @@ -93,7 +93,7 @@ isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, #define uv_async_init(loop, async, async_cb) \ ({ \ int __r = uv_async_init(loop, async, async_cb); \ - fprintf(stderr, "%" PRIu32 ":%s_:uv_timer_init(%p, %p, %p)\n", \ + fprintf(stderr, "%" PRItid ":%s_:uv_timer_init(%p, %p, %p)\n", \ isc_tid(), __func__, loop, async, async_cb); \ __r; \ }) @@ -101,7 +101,7 @@ isc__uverr2result(int uverr, bool dolog, const char *file, unsigned int line, #define uv_close(handle, close_cb) \ ({ \ uv_close(handle, close_cb); \ - fprintf(stderr, "%" PRIu32 ":%s_:uv_close(%p, %p)\n", \ + fprintf(stderr, "%" PRItid ":%s_:uv_close(%p, %p)\n", \ isc_tid(), __func__, handle, close_cb); \ }) diff --git a/lib/isc/loop.c b/lib/isc/loop.c index 8f5da3c859..1afbb2ef56 100644 --- a/lib/isc/loop.c +++ b/lib/isc/loop.c @@ -187,7 +187,7 @@ shutdown_cb(uv_async_t *handle) { } static void -loop_init(isc_loop_t *loop, isc_loopmgr_t *loopmgr, uint32_t tid, +loop_init(isc_loop_t *loop, isc_loopmgr_t *loopmgr, isc_tid_t tid, const char *kind) { *loop = (isc_loop_t){ .tid = tid, @@ -306,7 +306,7 @@ loop_thread(void *arg) { /* Start the helper thread */ isc_thread_create(helper_thread, helper, &helper->thread); - snprintf(name, sizeof(name), "isc-helper-%04" PRIu32, loop->tid); + snprintf(name, sizeof(name), "isc-helper-%04" PRItid, loop->tid); isc_thread_setname(helper->thread, name); int r = uv_prepare_start(&loop->quiescent, quiescent_cb); @@ -535,7 +535,7 @@ isc_loopmgr_pause(isc_loopmgr_t *loopmgr) { isc_loop_t *loop = &loopmgr->loops[i]; /* Skip current loop */ - if (i == isc_tid()) { + if (i == (size_t)isc_tid()) { continue; } @@ -645,9 +645,9 @@ isc_loop_main(isc_loopmgr_t *loopmgr) { } isc_loop_t * -isc_loop_get(isc_loopmgr_t *loopmgr, uint32_t tid) { +isc_loop_get(isc_loopmgr_t *loopmgr, isc_tid_t tid) { REQUIRE(VALID_LOOPMGR(loopmgr)); - REQUIRE(tid < loopmgr->nloops); + REQUIRE((uint32_t)tid < loopmgr->nloops); return LOOP(loopmgr, tid); } diff --git a/lib/isc/loop_p.h b/lib/isc/loop_p.h index 6bfdcdf187..f1f201ee35 100644 --- a/lib/isc/loop_p.h +++ b/lib/isc/loop_p.h @@ -46,7 +46,7 @@ struct isc_loop { isc_loopmgr_t *loopmgr; uv_loop_t loop; - uint32_t tid; + isc_tid_t tid; isc_mem_t *mctx; diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index 3a6ba66921..6d06cb4fe3 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -304,7 +304,7 @@ static void http_cleanup_listener_endpoints(isc_nmsocket_t *listener); static isc_nm_http_endpoints_t * -http_get_listener_endpoints(isc_nmsocket_t *listener, const int tid); +http_get_listener_endpoints(isc_nmsocket_t *listener, const isc_tid_t tid); static void http_initsocket(isc_nmsocket_t *sock); @@ -3385,7 +3385,7 @@ typedef struct http_endpoints_data { static void http_set_endpoints_cb(void *arg) { http_endpoints_data_t *data = arg; - const int tid = isc_tid(); + const isc_tid_t tid = isc_tid(); isc_nmsocket_t *listener = data->listener; isc_nm_http_endpoints_t *endpoints = data->endpoints; isc__networker_t *worker = &listener->worker->netmgr->workers[tid]; @@ -3470,7 +3470,7 @@ http_cleanup_listener_endpoints(isc_nmsocket_t *listener) { } static isc_nm_http_endpoints_t * -http_get_listener_endpoints(isc_nmsocket_t *listener, const int tid) { +http_get_listener_endpoints(isc_nmsocket_t *listener, const isc_tid_t tid) { isc_nm_http_endpoints_t *eps; REQUIRE(VALID_NMSOCK(listener)); REQUIRE(tid >= 0); diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 5534e7bdb4..79c60fdd60 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -151,8 +151,8 @@ STATIC_ASSERT(ISC_NETMGR_TCP_RECVBUF_SIZE <= ISC_NETMGR_RECVBUF_SIZE, #define gettid() (uint64_t)(pthread_self()) #endif -#define NETMGR_TRACE_LOG(format, ...) \ - fprintf(stderr, "%" PRIu64 ":%d:%s:%u:%s:" format, gettid(), \ +#define NETMGR_TRACE_LOG(format, ...) \ + fprintf(stderr, "%" PRIu64 ":%" PRItid ":%s:%u:%s:" format, gettid(), \ isc_tid(), file, line, func, __VA_ARGS__) #define FLARG \ @@ -496,7 +496,7 @@ typedef void (*isc_nm_closehandlecb_t)(void *arg); struct isc_nmsocket { /*% Unlocked, RO */ int magic; - uint32_t tid; + isc_tid_t tid; isc_refcount_t references; isc_nmsocket_type type; isc__networker_t *worker; @@ -1008,7 +1008,7 @@ isc__nmhandle_tls_keepalive(isc_nmhandle_t *handle, bool value); void isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx, - const int tid); + const isc_tid_t tid); void isc__nmhandle_tls_setwritetimeout(isc_nmhandle_t *handle, diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index a1ec3ab4e0..4603f3c8eb 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -118,9 +118,10 @@ networker_teardown(void *arg) { worker->shuttingdown = true; - isc__netmgr_log(worker->netmgr, ISC_LOG_DEBUG(1), - "Shutting down network manager worker on loop %p(%d)", - loop, isc_tid()); + isc__netmgr_log( + worker->netmgr, ISC_LOG_DEBUG(1), + "Shutting down network manager worker on loop %p(%" PRItid ")", + loop, isc_tid()); uv_walk(&loop->loop, shutdown_walk_cb, NULL); @@ -2558,7 +2559,7 @@ typedef struct settlsctx_data { static void settlsctx_cb(void *arg) { settlsctx_data_t *data = arg; - const uint32_t tid = isc_tid(); + const isc_tid_t tid = isc_tid(); isc_nmsocket_t *listener = data->listener; isc_tlsctx_t *tlsctx = data->tlsctx; isc__networker_t *worker = &listener->worker->netmgr->workers[tid]; @@ -2666,7 +2667,8 @@ isc__networker_destroy(isc__networker_t *worker) { worker->netmgr = NULL; isc__netmgr_log(netmgr, ISC_LOG_DEBUG(1), - "Destroying network manager worker on loop %p(%d)", + "Destroying network manager worker on loop %p(%" PRItid + ")", worker->loop, isc_tid()); isc_loop_detach(&worker->loop); diff --git a/lib/isc/netmgr/proxyudp.c b/lib/isc/netmgr/proxyudp.c index a4d038c641..27f40fea9e 100644 --- a/lib/isc/netmgr/proxyudp.c +++ b/lib/isc/netmgr/proxyudp.c @@ -491,7 +491,7 @@ static void stop_proxyudp_child_job(void *arg) { isc_nmsocket_t *listener = NULL; isc_nmsocket_t *sock = arg; - uint32_t tid = 0; + isc_tid_t tid = 0; if (sock == NULL) { return; diff --git a/lib/isc/netmgr/streamdns.c b/lib/isc/netmgr/streamdns.c index a0bc22ed53..82b6beb9a8 100644 --- a/lib/isc/netmgr/streamdns.c +++ b/lib/isc/netmgr/streamdns.c @@ -700,7 +700,7 @@ streamdns_accept_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { isc_nmsocket_t *listensock = (isc_nmsocket_t *)cbarg; isc_nmsocket_t *nsock; isc_sockaddr_t iface; - int tid = isc_tid(); + isc_tid_t tid = isc_tid(); REQUIRE(VALID_NMHANDLE(handle)); REQUIRE(VALID_NMSOCK(handle->sock)); diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 76dd0c8a78..327b345ec3 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -442,7 +442,7 @@ done_result: static void start_tcp_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock, - uv_os_sock_t fd, int tid) { + uv_os_sock_t fd, isc_tid_t tid) { isc_nmsocket_t *csock = &sock->children[tid]; isc__networker_t *worker = &mgr->workers[tid]; diff --git a/lib/isc/netmgr/tlsstream.c b/lib/isc/netmgr/tlsstream.c index b928842e29..df94724431 100644 --- a/lib/isc/netmgr/tlsstream.c +++ b/lib/isc/netmgr/tlsstream.c @@ -126,7 +126,7 @@ static void tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener); static isc_tlsctx_t * -tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid); +tls_get_listener_tlsctx(isc_nmsocket_t *listener, const isc_tid_t tid); static void tls_keep_client_tls_session(isc_nmsocket_t *sock); @@ -1548,7 +1548,7 @@ tls_cleanup_listener_tlsctx(isc_nmsocket_t *listener) { } static isc_tlsctx_t * -tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid) { +tls_get_listener_tlsctx(isc_nmsocket_t *listener, const isc_tid_t tid) { REQUIRE(VALID_NMSOCK(listener)); REQUIRE(tid >= 0); @@ -1561,7 +1561,7 @@ tls_get_listener_tlsctx(isc_nmsocket_t *listener, const int tid) { void isc__nm_async_tls_set_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx, - const int tid) { + const isc_tid_t tid) { REQUIRE(tid >= 0); isc_tlsctx_free(&listener->tlsstream.listener_tls_ctx[tid]); diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index e8106c1b13..9ea9af5958 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -180,7 +180,7 @@ done: static void start_udp_child(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nmsocket_t *sock, - uv_os_sock_t fd, int tid) { + uv_os_sock_t fd, isc_tid_t tid) { isc__networker_t *worker = &mgr->workers[tid]; isc_nmsocket_t *csock = &sock->children[tid]; diff --git a/lib/isc/tid.c b/lib/isc/tid.c index 2f4788189e..e8416a733c 100644 --- a/lib/isc/tid.c +++ b/lib/isc/tid.c @@ -22,26 +22,26 @@ /** * Private */ -thread_local uint32_t isc__tid_local = ISC_TID_UNKNOWN; +thread_local isc_tid_t isc__tid_local = ISC_TID_UNKNOWN; /* * Zero is a better nonsense value in this case than ISC_TID_UNKNOWN; * avoids things like trying to allocate 32GB of per-thread counters. */ -static uint32_t tid_count = 0; +static isc_tid_t tid_count = 0; /** * Protected */ void -isc__tid_init(uint32_t tid) { +isc__tid_init(isc_tid_t tid) { REQUIRE(isc__tid_local == ISC_TID_UNKNOWN || isc__tid_local == tid); isc__tid_local = tid; } void -isc__tid_initcount(uint32_t count) { +isc__tid_initcount(isc_tid_t count) { REQUIRE(tid_count == 0 || tid_count == count); tid_count = count; } @@ -50,7 +50,7 @@ isc__tid_initcount(uint32_t count) { * Public */ -uint32_t +isc_tid_t isc_tid_count(void) { return tid_count; } diff --git a/lib/ns/client.c b/lib/ns/client.c index 6696bd15f2..bafd51f306 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2644,7 +2644,8 @@ ISC_REFCOUNT_IMPL(ns_clientmgr, clientmgr_destroy); isc_result_t ns_clientmgr_create(ns_server_t *sctx, isc_loopmgr_t *loopmgr, - dns_aclenv_t *aclenv, int tid, ns_clientmgr_t **managerp) { + dns_aclenv_t *aclenv, isc_tid_t tid, + ns_clientmgr_t **managerp) { ns_clientmgr_t *manager = NULL; isc_mem_t *mctx = NULL; diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h index 773647a2ea..8d17118c4d 100644 --- a/lib/ns/include/ns/client.h +++ b/lib/ns/include/ns/client.h @@ -149,7 +149,7 @@ struct ns_clientmgr { ns_server_t *sctx; isc_refcount_t references; - uint32_t tid; + isc_tid_t tid; isc_loop_t *loop; dns_aclenv_t *aclenv; @@ -331,7 +331,8 @@ ns_client_settimeout(ns_client_t *client, unsigned int seconds); isc_result_t ns_clientmgr_create(ns_server_t *sctx, isc_loopmgr_t *loopmgr, - dns_aclenv_t *aclenv, int tid, ns_clientmgr_t **managerp); + dns_aclenv_t *aclenv, isc_tid_t tid, + ns_clientmgr_t **managerp); /*%< * Create a client manager. */ diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 118f3113e4..03a42c0c0d 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -1358,11 +1358,10 @@ ns_interfacemgr_getserver(ns_interfacemgr_t *mgr) { ns_clientmgr_t * ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr) { - int tid = isc_tid(); + isc_tid_t tid = isc_tid(); REQUIRE(NS_INTERFACEMGR_VALID(mgr)); - REQUIRE(tid >= 0); - REQUIRE((uint32_t)tid < mgr->ncpus); + REQUIRE(tid >= 0 && (uint32_t)tid < mgr->ncpus); return mgr->clientmgrs[tid]; } diff --git a/tests/bench/qpmulti.c b/tests/bench/qpmulti.c index ac1c10b3d6..783bf37f51 100644 --- a/tests/bench/qpmulti.c +++ b/tests/bench/qpmulti.c @@ -55,10 +55,10 @@ #define ZIPF 0 #if VERBOSE -#define TRACE(fmt, ...) \ - isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_QP, \ - ISC_LOG_DEBUG(7), "%s:%d:%s():t%d: " fmt, __FILE__, \ - __LINE__, __func__, isc_tid(), ##__VA_ARGS__) +#define TRACE(fmt, ...) \ + isc_log_write(DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_QP, \ + ISC_LOG_DEBUG(7), "%s:%d:%s():t%" PRItid ": " fmt, \ + __FILE__, __LINE__, __func__, isc_tid(), ##__VA_ARGS__) #else #define TRACE(...) #endif diff --git a/tests/dns/dispatch_test.c b/tests/dns/dispatch_test.c index 685d6a11c9..343f4416bc 100644 --- a/tests/dns/dispatch_test.c +++ b/tests/dns/dispatch_test.c @@ -303,7 +303,7 @@ ISC_LOOP_TEST_IMPL(dispatchset_get) { dns_dispatchmgr_t *dispatchmgr = NULL; dns_dispatchset_t *dset = NULL; dns_dispatch_t *d1, *d2, *d3, *d4, *d5; - uint32_t tid_saved; + isc_tid_t tid_saved; UNUSED(arg); diff --git a/tests/isc/async_test.c b/tests/isc/async_test.c index ea8d543919..f9b32f4387 100644 --- a/tests/isc/async_test.c +++ b/tests/isc/async_test.c @@ -41,7 +41,7 @@ static atomic_uint scheduled = 0; static void async_cb(void *arg) { - uint32_t tid = isc_tid(); + isc_tid_t tid = isc_tid(); UNUSED(arg); @@ -57,7 +57,7 @@ async_cb(void *arg) { static void async_setup_cb(void *arg) { - uint32_t tid = isc_loopmgr_nloops(loopmgr) - 1; + isc_tid_t tid = isc_loopmgr_nloops(loopmgr) - 1; isc_loop_t *loop = isc_loop_get(loopmgr, tid); UNUSED(arg); diff --git a/tests/isc/netmgr_common.h b/tests/isc/netmgr_common.h index d5cf4b34c9..b1c784adf9 100644 --- a/tests/isc/netmgr_common.h +++ b/tests/isc/netmgr_common.h @@ -211,13 +211,14 @@ extern isc_nm_recv_cb_t connect_readcb; fprintf(stderr, "%s:%s:%d:%s = %" PRId64 "\n", __func__, __FILE__, \ __LINE__, #v, atomic_load(&v)) #define P(v) fprintf(stderr, #v " = %" PRId64 "\n", v) -#define F() \ - fprintf(stderr, "%u:%s(%p, %s, %p)\n", isc_tid(), __func__, handle, \ - isc_result_totext(eresult), cbarg) +#define F() \ + fprintf(stderr, "%" PRItid ":%s(%p, %s, %p)\n", isc_tid(), __func__, \ + handle, isc_result_totext(eresult), cbarg) #define isc_loopmgr_shutdown(loopmgr) \ { \ - fprintf(stderr, "%u:%s:%s:%d:isc_loopmgr_shutdown(%p)\n", \ + fprintf(stderr, \ + "%" PRItid ":%s:%s:%d:isc_loopmgr_shutdown(%p)\n", \ isc_tid(), __func__, __FILE__, __LINE__, loopmgr); \ isc_loopmgr_shutdown(loopmgr); \ } diff --git a/tests/isc/work_test.c b/tests/isc/work_test.c index 046cccb1b9..39f3ba1d17 100644 --- a/tests/isc/work_test.c +++ b/tests/isc/work_test.c @@ -45,7 +45,7 @@ work_cb(void *arg) { atomic_fetch_add(&scheduled, 1); - assert_int_equal(isc_tid(), UINT32_MAX); + assert_int_equal(isc_tid(), ISC_TID_UNKNOWN); } static void @@ -59,7 +59,7 @@ after_work_cb(void *arg) { static void work_enqueue_cb(void *arg) { UNUSED(arg); - uint32_t tid = isc_loopmgr_nloops(loopmgr) - 1; + isc_tid_t tid = isc_loopmgr_nloops(loopmgr) - 1; isc_loop_t *loop = isc_loop_get(loopmgr, tid); From dd37fd6a49b41b12a0f9582bc72ae171aae29e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 4 Jun 2025 18:00:01 +0200 Subject: [PATCH 2/2] Add ISC_TID_MAX with default being 512 threads The ISC_TID_MAX variable allows other units to declare static arrays with this as size for per-thread/per-loop variables. --- bin/named/main.c | 20 +++++++++++++++----- lib/isc/include/isc/tid.h | 4 ++++ lib/isc/tid.c | 2 ++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/bin/named/main.c b/bin/named/main.c index 14dee08c86..ae6f4fcc49 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -946,6 +946,8 @@ parse_command_line(int argc, char *argv[]) { static isc_result_t create_managers(void) { + bool capped = false; + /* * Set the default named_g_cpus if it was not set from the command line */ @@ -954,11 +956,19 @@ create_managers(void) { named_g_cpus = named_g_cpus_detected; } - isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, - ISC_LOG_INFO, "found %u CPU%s, using %u worker thread%s", - named_g_cpus_detected, - named_g_cpus_detected == 1 ? "" : "s", named_g_cpus, - named_g_cpus == 1 ? "" : "s"); + if (named_g_cpus > ISC_TID_MAX) { + capped = true; + named_g_cpus = ISC_TID_MAX; + } + + isc_log_write( + NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER, ISC_LOG_INFO, + "found %u CPU%s, using %u worker thread%s%s", + named_g_cpus_detected, named_g_cpus_detected == 1 ? "" : "s", + named_g_cpus, named_g_cpus == 1 ? "" : "s", + capped ? " (recompile with -DISC_TID_MAX= to raise the " + "thread count limit)" + : ""); isc_managers_create(&named_g_mctx, named_g_cpus, &named_g_loopmgr, &named_g_netmgr); diff --git a/lib/isc/include/isc/tid.h b/lib/isc/include/isc/tid.h index b506205979..123e14092f 100644 --- a/lib/isc/include/isc/tid.h +++ b/lib/isc/include/isc/tid.h @@ -23,6 +23,10 @@ typedef int32_t isc_tid_t; #define ISC_TID_UNKNOWN (isc_tid_t) - 1 +#ifndef ISC_TID_MAX +#define ISC_TID_MAX 512 +#endif /* ISC_TID_MAX */ + isc_tid_t isc_tid_count(void); /*%< diff --git a/lib/isc/tid.c b/lib/isc/tid.c index e8416a733c..909b4a949f 100644 --- a/lib/isc/tid.c +++ b/lib/isc/tid.c @@ -37,12 +37,14 @@ static isc_tid_t tid_count = 0; void isc__tid_init(isc_tid_t tid) { REQUIRE(isc__tid_local == ISC_TID_UNKNOWN || isc__tid_local == tid); + REQUIRE(tid < ISC_TID_MAX); isc__tid_local = tid; } void isc__tid_initcount(isc_tid_t count) { REQUIRE(tid_count == 0 || tid_count == count); + REQUIRE(tid_count < ISC_TID_MAX); tid_count = count; }