一. 哈希表
定义文件路径:quic_hashtable.h
QUIC_STREAM_SET哈希表指针:CXPLAT_HASHTABLE* StreamTable;
QUIC_STREAM定义元素:CXPLAT_HASHTABLE_ENTRY TableEntry;
1. initialize
if (StreamSet->StreamTable == NULL) {
//
// Lazily initialize the hash table.
//
if (!CxPlatHashtableInitialize(&StreamSet->StreamTable, CXPLAT_HASH_MIN_SIZE)) {
QuicTraceEvent(
AllocFailure,
"Allocation of '%s' failed. (%llu bytes)",
"streamset hash table",
0);
return FALSE;
}
}
2. uninitialize
if (StreamSet->StreamTable != NULL) {
CxPlatHashtableUninitialize(StreamSet->StreamTable);
}
3. insert
CxPlatHashtableInsert(StreamSet->StreamTable, &Stream->TableEntry, (uint32_t)Stream->ID, NULL);
4. remove
CxPlatHashtableRemove(StreamSet->StreamTable, &Stream->TableEntry, NULL);
5. lookup
if (StreamSet->StreamTable == NULL) {
return NULL; // No streams have been created yet.
}
CXPLAT_HASHTABLE_LOOKUP_CONTEXT Context;
CXPLAT_HASHTABLE_ENTRY* Entry =
CxPlatHashtableLookup(StreamSet->StreamTable, (uint32_t)ID, &Context);
while (Entry != NULL) {
QUIC_STREAM* Stream =
CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, TableEntry);
if (Stream->ID == ID) {
return Stream;
}
Entry = CxPlatHashtableLookupNext(StreamSet->StreamTable, &Context);
}
return NULL;
6. for_each
if (StreamSet->StreamTable == NULL) {
return; // No streams have been created yet.
}
CXPLAT_HASHTABLE_ENUMERATOR Enumerator;
CXPLAT_HASHTABLE_ENTRY* Entry;
CxPlatHashtableEnumerateBegin(StreamSet->StreamTable, &Enumerator);
while ((Entry = CxPlatHashtableEnumerateNext(StreamSet->StreamTable, &Enumerator)) != NULL) {
QuicStreamTraceRundown(
CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, TableEntry));
}
CxPlatHashtableEnumerateEnd(StreamSet->StreamTable, &Enumerator);
二. 链表
定义文件路径:quic_platform.h
QUIC_SEND定义链表:CXPLAT_LIST_ENTRY SendStreams;
QUIC_STREAM元素指针:CXPLAT_LIST_ENTRY SendLink;
1. insert/for
CxPlatListInsertTail(&Connection->DestCids, &Path->DestCid->Link);
for (CXPLAT_LIST_ENTRY* Entry = Connection->DestCids.Flink;
Entry != &Connection->DestCids;
Entry = Entry->Flink) {
const QUIC_CID_LIST_ENTRY* DestCid =
CXPLAT_CONTAINING_RECORD(
Entry,
QUIC_CID_LIST_ENTRY,
Link);
UNREFERENCED_PARAMETER(DestCid);
QuicTraceEvent(
ConnDestCidAdded,
"[conn][%p] (SeqNum=%llu) New Destination CID: %!CID!",
Connection,
DestCid->CID.SequenceNumber,
CASTED_CLOG_BYTEARRAY(DestCid->CID.Length, DestCid->CID.Data));
}
CXPLAT_DBG_ASSERT(Stream->SendLink.Flink == NULL);
CXPLAT_LIST_ENTRY* Entry = Send->SendStreams.Blink;
while (Entry != &Send->SendStreams) {
//
// Search back to front for the right place (based on priority) to
// insert the stream.
//
if (Stream->SendPriority <=
CXPLAT_CONTAINING_RECORD(Entry, QUIC_STREAM, SendLink)->SendPriority) {
break;
}
Entry = Entry->Blink;
}
CxPlatListInsertHead(Entry, &Stream->SendLink); // Insert after current Entry
2. remove
CxPlatListEntryRemove(&Stream->SendLink);
Stream->SendLink.Flink = NULL;
QuicStreamRelease(Stream, QUIC_STREAM_REF_SEND);
Stream = NULL;
三. 锁
定义文件路径:quic_platform_posix.h (实际实现是pthread_mutex_t)
QUIC_LIBRARY链表指针:CXPLAT_LOCK Lock;
1. init
CxPlatLockInitialize(&MsQuicLib.Lock);
2. uninit
CxPlatLockUninitialize(&MsQuicLib.Lock);
3. lock
CxPlatLockAcquire(&MsQuicLib.Lock);
4. unlock
CxPlatLockRelease(&MsQuicLib.Lock);
四. 线程
# 当前线程 (9993423)
CXPLAT_THREAD_ID ThreadID = CxPlatCurThreadID();
# 线程索引 (0、1、2、3)
uint32_t CurProcIndex = CxPlatProcCurrentNumber();
实现方式:
(uint32_t)sched_getcpu() % CxPlatProcessorCount;
# 所有worker线程数 (cpu核心数)
MsQuicLib.ProcessorCount = (uint16_t)CxPlatProcActiveCount();
MsQuicLib.ProcessorCount = (uint16_t)sysconf(_SC_NPROCESSORS_ONLN);
五. 时间
# 毫秒ms
int64_t Now = CxPlatTimeEpochMs64();
六. 内存池
- 接口
定义文件路径:quic_platform_posix.h
QUIC_WORKER指针:CXPLAT_POOL StreamPool;
1. init
inline
void
CxPlatPoolInitialize(
_In_ BOOLEAN IsPaged,
_In_ uint32_t Size,
_In_ uint32_t Tag,
_Inout_ CXPLAT_POOL* Pool
)
#define QUIC_POOL_STREAM '30cQ' // Qc03 - QUIC stream
CxPlatPoolInitialize(FALSE, sizeof(QUIC_STREAM), QUIC_POOL_STREAM, &Worker->StreamPool);
2. uninit
CxPlatPoolUninitialize(&Worker->StreamPool);
3. alloc
Stream = CxPlatPoolAlloc(&Worker->StreamPool);
if (Stream == NULL) {
Status = QUIC_STATUS_OUT_OF_MEMORY;
goto Exit;
}
CxPlatZeroMemory(Stream, sizeof(QUIC_STREAM));
4. free
CxPlatPoolFree(&Worker->StreamPool, Stream);
从StreamPool中获取stream
QuicStreamInitialize QuicStreamFree
<a name="semW4"></a>
# 七. 引用计数
定义文件路径:quic_platform_posix.h<br />QUIC_STREAM定义:CXPLAT_REF_COUNT RefCount;
```c
# init
Stream->RefCount = 1;
CxPlatRefInitialize(&Stream->RefCount);
# uninit
CxPlatRefUninitialize(&Stream->RefCount);
# inc
CxPlatRefIncrement(&Stream->RefCount);
# dec
if (CxPlatRefDecrement(&Stream->RefCount)) {
QuicStreamFree(Stream);
return TRUE;
}
return FALSE;
八. 随机数
CxPlatRandom(sizeof(uint32_t), &Binding->RandomReservedVersion);
九. 宏定义
在frame.h、connection.c(QuicErrorCodeToStatus)、msquic_posix.h、/usr/include/asm-generic/error.h
十. 信号
定义文件路径:quic_platform_posix.h,实现是 pthread_cond_wait 和 pthread_cond_broadcast
#define CxPlatEventWaitForever(Event) CxPlatInternalEventWaitForever(&Event)
#define CxPlatEventSet(Event) CxPlatInternalEventSet(&Event)