@@ -1506,6 +1506,67 @@ QuicLibrarySetGlobalParam(
15061506 return Status ;
15071507}
15081508
1509+ #ifndef _KERNEL_MODE
1510+ //
1511+ // Fills the caller's buffer with the per-worker statistics for the global
1512+ // worker pool, mapping the platform's raw statistics into the public shape.
1513+ //
1514+ _IRQL_requires_max_ (PASSIVE_LEVEL )
1515+ QUIC_STATUS
1516+ QuicLibraryGetGlobalWorkerStatistics (
1517+ _Inout_ uint32_t * BufferLength ,
1518+ _Out_writes_bytes_opt_ (* BufferLength )
1519+ void * Buffer
1520+ )
1521+ {
1522+ if (MsQuicLib .WorkerPool == NULL ) {
1523+ return QUIC_STATUS_INVALID_STATE ;
1524+ }
1525+
1526+ uint32_t WorkerCount = CxPlatWorkerPoolGetCount (MsQuicLib .WorkerPool );
1527+ uint32_t RequiredSize =
1528+ sizeof (QUIC_WORKER_STATISTICS_LIST ) +
1529+ WorkerCount * sizeof (QUIC_WORKER_STATISTICS );
1530+
1531+ if (* BufferLength < RequiredSize ) {
1532+ * BufferLength = RequiredSize ;
1533+ return QUIC_STATUS_BUFFER_TOO_SMALL ;
1534+ }
1535+
1536+ if (Buffer == NULL ) {
1537+ return QUIC_STATUS_INVALID_PARAMETER ;
1538+ }
1539+
1540+ QUIC_WORKER_STATISTICS_LIST * List = (QUIC_WORKER_STATISTICS_LIST * )Buffer ;
1541+ List -> WorkerCount = WorkerCount ;
1542+ List -> WorkerStatsSize = sizeof (QUIC_WORKER_STATISTICS );
1543+
1544+ QUIC_WORKER_STATISTICS * PublicStats =
1545+ (QUIC_WORKER_STATISTICS * )((uint8_t * )Buffer + sizeof (QUIC_WORKER_STATISTICS_LIST ));
1546+ CxPlatZeroMemory (PublicStats , WorkerCount * sizeof (QUIC_WORKER_STATISTICS ));
1547+
1548+ if (WorkerCount > 0 ) {
1549+ CXPLAT_WORKER_STATISTICS * RawStats =
1550+ CXPLAT_ALLOC_PAGED (
1551+ WorkerCount * sizeof (CXPLAT_WORKER_STATISTICS ),
1552+ QUIC_POOL_GENERIC );
1553+ if (RawStats == NULL ) {
1554+ return QUIC_STATUS_OUT_OF_MEMORY ;
1555+ }
1556+ CxPlatWorkerPoolGetStatistics (MsQuicLib .WorkerPool , RawStats , WorkerCount );
1557+ for (uint32_t i = 0 ; i < WorkerCount ; i ++ ) {
1558+ PublicStats [i ].IdealProcessor = RawStats [i ].IdealProcessor ;
1559+ PublicStats [i ].CumulativeActiveTimeUs = RawStats [i ].CumulativeActiveTimeUs ;
1560+ PublicStats [i ].CumulativeWallTimeUs = RawStats [i ].CumulativeWallTimeUs ;
1561+ }
1562+ CXPLAT_FREE (RawStats , QUIC_POOL_GENERIC );
1563+ }
1564+
1565+ * BufferLength = RequiredSize ;
1566+ return QUIC_STATUS_SUCCESS ;
1567+ }
1568+ #endif // !_KERNEL_MODE
1569+
15091570_IRQL_requires_max_ (PASSIVE_LEVEL )
15101571QUIC_STATUS
15111572QuicLibraryGetGlobalParam (
@@ -1876,43 +1937,18 @@ QuicLibraryGetGlobalParam(
18761937 break ;
18771938 }
18781939
1879- #ifndef _KERNEL_MODE
18801940 case QUIC_PARAM_GLOBAL_WORKER_STATISTICS : {
1881-
1882- if (MsQuicLib .WorkerPool == NULL ) {
1883- Status = QUIC_STATUS_INVALID_STATE ;
1884- break ;
1885- }
1886-
1887- uint32_t WorkerCount = CxPlatWorkerPoolGetCount (MsQuicLib .WorkerPool );
1888- uint32_t RequiredSize =
1889- sizeof (QUIC_WORKER_STATISTICS_LIST ) +
1890- WorkerCount * sizeof (QUIC_WORKER_STATISTICS );
1891-
1892- if (* BufferLength < RequiredSize ) {
1893- * BufferLength = RequiredSize ;
1894- Status = QUIC_STATUS_BUFFER_TOO_SMALL ;
1895- break ;
1896- }
1897-
1898- if (Buffer == NULL ) {
1899- Status = QUIC_STATUS_INVALID_PARAMETER ;
1900- break ;
1901- }
1902-
1903- QUIC_WORKER_STATISTICS_LIST * List = (QUIC_WORKER_STATISTICS_LIST * )Buffer ;
1904- List -> WorkerCount = WorkerCount ;
1905- List -> WorkerStatsSize = sizeof (QUIC_WORKER_STATISTICS );
1906-
1907- QUIC_WORKER_STATISTICS * Stats =
1908- (QUIC_WORKER_STATISTICS * )((uint8_t * )Buffer + sizeof (QUIC_WORKER_STATISTICS_LIST ));
1909- CxPlatWorkerPoolGetStatistics (MsQuicLib .WorkerPool , Stats , WorkerCount );
1910-
1911- * BufferLength = RequiredSize ;
1912- Status = QUIC_STATUS_SUCCESS ;
1941+ #ifdef _KERNEL_MODE
1942+ //
1943+ // Worker statistics are not supported in kernel mode, where the worker
1944+ // threads are not owned by the platform worker pool.
1945+ //
1946+ Status = QUIC_STATUS_NOT_SUPPORTED ;
1947+ #else
1948+ Status = QuicLibraryGetGlobalWorkerStatistics (BufferLength , Buffer );
1949+ #endif
19131950 break ;
19141951 }
1915- #endif
19161952
19171953 default :
19181954 Status = QUIC_STATUS_INVALID_PARAMETER ;
0 commit comments