aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/tier0
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /sp/src/public/tier0
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/public/tier0')
-rw-r--r--sp/src/public/tier0/EventMasks.h960
-rw-r--r--sp/src/public/tier0/EventModes.h3574
-rw-r--r--sp/src/public/tier0/IOCTLCodes.h58
-rw-r--r--sp/src/public/tier0/K8PerformanceCounters.h4064
-rw-r--r--sp/src/public/tier0/P4PerformanceCounters.h644
-rw-r--r--sp/src/public/tier0/P5P6PerformanceCounters.h450
-rw-r--r--sp/src/public/tier0/PMELib.h382
-rw-r--r--sp/src/public/tier0/afxmem_override.cpp920
-rw-r--r--sp/src/public/tier0/annotations.h238
-rw-r--r--sp/src/public/tier0/basetypes.h796
-rw-r--r--sp/src/public/tier0/commonmacros.h346
-rw-r--r--sp/src/public/tier0/dbg.h1590
-rw-r--r--sp/src/public/tier0/dbgflag.h130
-rw-r--r--sp/src/public/tier0/dynfunction.h272
-rw-r--r--sp/src/public/tier0/etwprof.h314
-rw-r--r--sp/src/public/tier0/fasttimer.h1142
-rw-r--r--sp/src/public/tier0/ia32detect.h754
-rw-r--r--sp/src/public/tier0/icommandline.h114
-rw-r--r--sp/src/public/tier0/l2cache.h92
-rw-r--r--sp/src/public/tier0/mem.h100
-rw-r--r--sp/src/public/tier0/memalloc.h1308
-rw-r--r--sp/src/public/tier0/memdbgoff.h50
-rw-r--r--sp/src/public/tier0/memdbgon.h496
-rw-r--r--sp/src/public/tier0/memoverride.cpp3316
-rw-r--r--sp/src/public/tier0/minidump.h174
-rw-r--r--sp/src/public/tier0/platform.h3152
-rw-r--r--sp/src/public/tier0/pmc360.h144
-rw-r--r--sp/src/public/tier0/progressbar.h46
-rw-r--r--sp/src/public/tier0/protected_things.h542
-rw-r--r--sp/src/public/tier0/systeminformation.h112
-rw-r--r--sp/src/public/tier0/testthread.h120
-rw-r--r--sp/src/public/tier0/threadtools.h3428
-rw-r--r--sp/src/public/tier0/tmapi_dummy.h156
-rw-r--r--sp/src/public/tier0/tslist.h2008
-rw-r--r--sp/src/public/tier0/validator.h146
-rw-r--r--sp/src/public/tier0/valobject.h144
-rw-r--r--sp/src/public/tier0/valve_minmax_off.h14
-rw-r--r--sp/src/public/tier0/valve_minmax_on.h18
-rw-r--r--sp/src/public/tier0/valve_off.h60
-rw-r--r--sp/src/public/tier0/valve_on.h62
-rw-r--r--sp/src/public/tier0/vcr_shared.h108
-rw-r--r--sp/src/public/tier0/vcrmode.h612
-rw-r--r--sp/src/public/tier0/vprof.h2876
-rw-r--r--sp/src/public/tier0/vprof_telemetry.h2102
-rw-r--r--sp/src/public/tier0/wchartypes.h202
-rw-r--r--sp/src/public/tier0/xbox_codeline_defines.h32
46 files changed, 19184 insertions, 19184 deletions
diff --git a/sp/src/public/tier0/EventMasks.h b/sp/src/public/tier0/EventMasks.h
index 6138739b..0185567b 100644
--- a/sp/src/public/tier0/EventMasks.h
+++ b/sp/src/public/tier0/EventMasks.h
@@ -1,480 +1,480 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#pragma once
-
-typedef union EVENT_MASK(TC_deliver_mode)
-{
- struct
- {
- uint16 DD:1; // both logical processors in deliver mode },
- uint16 DB:1; // logical processor 0 in deliver mode, 1 in build mode },
- uint16 DI:1; // logical processor 0 in deliver mode, 1 is inactive },
- uint16 BD:1; // logical processor 0 in build mode, 1 in deliver mode },
- uint16 BB:1; // both logical processors in build mode },
- uint16 BI:1; // logical processor 0 in build mode, 1 is inactive },
- uint16 ID:1; // logical processor 0 is inactive, 1 in deliver mode },
- uint16 IB:1; // logical processor 0 is inactive, 1 in build mode }
- };
- uint16 flat;
-} EVENT_MASK(TC_deliver_mode);
-
-typedef union EVENT_MASK(BPU_fetch_request)
-{
-
- struct
- {
- uint16 TCMISS:1; // Trace cache lookup miss },
- };
- uint16 flat;
-} EVENT_MASK(BPU_fetch_request);
-
-
-typedef union EVENT_MASK(ITLB_reference)
-{
- struct
- {
- uint16 HIT : 1; //ITLB hit },
- uint16 MISS : 1;//ITLB miss },
- uint16 HIT_UC :1; // Uncacheable ITLB hit }
- };
- uint16 flat;
-} EVENT_MASK(ITLB_reference);
-
-typedef union EVENT_MASK(memory_cancel)
-{
- struct
- {
- uint16 dummy : 2;
-
- uint16 ST_RB_FULL:1; //Replayed because no store request buffer is available },
- uint16 _64K_CONF:1; //Conflicts due to 64K aliasing }
- };
- uint16 flat;
-}EVENT_MASK(memory_cancel);
-
-typedef union EVENT_MASK(memory_complete)
-{
- struct
- {
- uint16 LSC:1; // Load split completed, excluding UC/WC loads },
- uint16 SSC:1; //Any split stores completed } }
- };
- uint16 flat;
-} EVENT_MASK(memory_complete);
-
-typedef union EVENT_MASK(load_port_replay)
-{
- struct
- {
- uint16 dummy:1;
- uint16 SPLIT_LD:1; //Split load } }
- };
- uint16 flat;
-} EVENT_MASK(load_port_replay);
-
-typedef union EVENT_MASK(store_port_replay)
-{
- struct
- {
- uint16 dummy0:1;
- uint16 SPLIT_ST:1; //Split store } }
-
- };
- uint16 flat;
-} EVENT_MASK(store_port_replay);
-
-typedef union EVENT_MASK(MOB_load_replay)
-{
- struct
- {
- uint16 dummy0:1;
-
- uint16 NO_STA:1; //Replayed because of unknown store address },
-
- uint16 dummy2:1;
-
- uint16 NO_STD:1; //Replayed because of unknown store data },
- uint16 PARTIAL_DATA:1; //Replayed because of partially overlapped data access between the load and store operations },
- uint16 UNALGN_ADDR:1; //Replayed because the lower 4 bits of the linear address do not match between the load and store operations } }
- };
- uint16 flat;
-}EVENT_MASK(MOB_load_replay);
-
-typedef union EVENT_MASK(page_walk_type)
-{
- struct
- {
- uint16 DTMISS:1; // Page walk for a data TLB miss },
- uint16 ITMISS:1; // Page walk for an instruction TLB miss } }
- };
- uint16 flat;
-}EVENT_MASK(page_walk_type);
-
-
-typedef union EVENT_MASK(BSQ_cache_reference)
-{
- struct
- {
- uint16 RD_2ndL_HITS:1; // Read 2nd level cache hit Shared },
- uint16 RD_2ndL_HITE:1; // Read 2nd level cache hit Exclusive },
- uint16 RD_2ndL_HITM:1; // Read 2nd level cache hit Modified },
- uint16 RD_3rdL_HITS:1; // Read 3rd level cache hit Shared },
- uint16 RD_3rdL_HITE:1; // Read 3rd level cache hit Exclusive },
- uint16 RD_3rdL_HITM:1; // Read 3rd level cache hit Modified },
- uint16 dummy6:1;
- uint16 dummy7:1;
- uint16 RD_2ndL_MISS:1; // Read 2nd level cache miss },
- uint16 RD_3rdL_MISS:1; // Read 3rd level cache miss },
- uint16 WR_2ndL_MISS:1; // Writeback lookup from DAC misses the 2nd level cache } }
- };
- uint16 flat;
-} EVENT_MASK(BSQ_cache_reference) ;
-
-typedef union EVENT_MASK(IOQ)
-{
- struct
- {
- uint16 bit0:1; // bus request type (use 00001 for invalid or default)
- uint16 bit1:1; //
- uint16 bit2:1; //
- uint16 bit3:1; //
- uint16 bit4:1; //
- uint16 ALL_READ:1; // Count read entries },
- uint16 ALL_WRITE:1; // Count write entries },
- uint16 MEM_UC:1; // Count UC memory access entries },
- uint16 MEM_WC:1; // Count WC memory access entries },
- uint16 MEM_WT:1; // Count WT memory access entries },
- uint16 MEM_WP:1; // Count WP memory access entries },
- uint16 MEM_WB:1; // Count WB memory access entries },
- uint16 dummy12:1;
-
- uint16 OWN:1; // Count own store requests },
- uint16 OTHER:1; // Count other and DMA store requests },
- uint16 PREFETCH:1; // Include HW and SW prefetch requests } }
- };
- uint16 flat;
-} EVENT_MASK(IOQ) ;
-
-typedef union EVENT_MASK(FSB_data_activity)
-{
- struct
- {
- /* DRDY_OWN is mutually exclusive with DRDY_OTHER */
- /* DBSY_OWN is mutually exclusive with DBSY_OTHER */
- uint16 DRDY_DRV:1; // Count when this processor drives data onto the bus },
- uint16 DRDY_OWN:1; // Count when this processor reads data from the bus },
- uint16 DRDY_OTHER:1; // Count when data is on the bus but not being sampled by the processor },
- uint16 DBSY_DRV:1; // Count when this processor reserves the bus for driving data },
- uint16 DBSY_OWN:1; // Count when this processor reserves the bus for sampling data },
- uint16 DBSY_OTHER:1; // Count when the bus is reserved for driving data this processor will not sample } }
- };
- uint16 flat;
-}EVENT_MASK(FSB_data_activity);
-
-typedef union EVENT_MASK(BSQ)
-{
- struct
- {
- uint16 REQ_TYPE0:1; // Request type encoding bit 0 },
- uint16 REQ_TYPE1:1; // Request type encoding bit 1 },
- uint16 REQ_LEN0:1; // Request length encoding bit 0 },
- uint16 REQ_LEN1:1; // Request length encoding bit 1 },
- uint16 dummy4: 1;
- uint16 REQ_IO_TYPE:1; // Request type is input or output },
- uint16 REQ_LOCK_TYPE:1; // Request type is bus lock },
- uint16 REQ_CACHE_TYPE:1; // Request type is cacheable },
- uint16 REQ_SPLIT_TYPE:1; // Request type is a bus 8-byte chunk split across 8-byte boundary },
- uint16 REQ_DEM_TYPE:1; // Request type is a demand (1) or prefetch (0) },
- uint16 REQ_ORD_TYPE:1; // Request is an ordered type },
- uint16 MEM_TYPE0:1; // Memory type encoding bit 0 },
- uint16 MEM_TYPE1:1; // Memory type encoding bit 1 },
- uint16 MEM_TYPE2:1; // Memory type encoding bit 2 } }
- };
- uint16 flat;
-} EVENT_MASK(BSQ);
-
-typedef union EVENT_MASK(firm_uop)
-{
- struct
- {
- uint16 dummy15 : 15;
- uint16 ALL:1; // count all uops of this type } }
- };
- uint16 flat;
-} EVENT_MASK(firm_uop);
-
-
-
-typedef union EVENT_MASK(TC_misc)
-{
- struct
- {
- uint16 dymmy4 : 4;
- uint16 FLUSH:1; // Number of flushes } }
- };
- uint16 flat;
-} EVENT_MASK(TC_misc);
-
-typedef union EVENT_MASK(global_power_events)
-{
- struct
- {
- uint16 Running:1; // The processor is active } }
- };
- uint16 flat;
-} EVENT_MASK(global_power_events);
-
-typedef union EVENT_MASK(tc_ms_xfer)
-{
- struct
- {
- uint16 CISC:1; // A TC to MS transfer ocurred } }
- };
- uint16 flat;
-}EVENT_MASK(tc_ms_xfer);
-
-
-
-typedef union EVENT_MASK(uop_queue_writes)
-{
- struct
- {
- uint16 FROM_TC_BUILD:1; // uops written from TC build mode
- uint16 FROM_TC_DELIVER:1; // uops written from TC deliver mode
- uint16 FROM_ROM:1; // uops written from microcode ROM } }
- };
- uint16 flat;
-} EVENT_MASK(uop_queue_writes);
-
-typedef union EVENT_MASK(branch_type)
-{
- struct
- {
- uint16 dummy : 1;
- uint16 CONDITIONAL:1; // Conditional jumps
- uint16 CALL:1; // Direct or indirect call
- uint16 RETURN:1; // Return branches
- uint16 INDIRECT:1; // Returns, indirect calls, or indirect jumps
- };
- uint16 flat;
-} EVENT_MASK(branch_type);
-
-
-
-typedef union EVENT_MASK(resource_stall)
-{
- struct
- {
- uint16 dummy1 : 5;
- uint16 SBFULL:1; // A Stall due to lack of store buffers } }
- };
- uint16 flat;
-} EVENT_MASK(resource_stall);
-
-
-
-
-typedef union EVENT_MASK(WC_Buffer)
-{
- struct
- {
- uint16 WCB_EVICTS : 1; // all causes },
- uint16 WCB_FULL_EVICT : 1; // no WC buffer is available },
- /* XXX: 245472-011 no longer lists bit 2, but that looks like
- a table formatting error. Keeping it for now. */
- uint16 WCB_HITM_EVICT : 1; // store encountered a Hit Modified condition } }
- };
- uint16 flat;
-} EVENT_MASK(WC_Buffer);
-
-
-typedef union EVENT_MASK(b2b_cycles)
-{
- struct
- {
- uint16 dummy0 : 1;
- uint16 bit1 : 1; //
- uint16 bit2 : 1; //
- uint16 bit3 : 1; //
- uint16 bit4 : 1; //
- uint16 bit5 : 1; //
- uint16 bit6 : 1; //
-
- };
- uint16 flat;
-} EVENT_MASK(b2b_cycles);
-
-typedef union EVENT_MASK(bnr)
-{
- struct
- {
- uint16 bit0:1; //
- uint16 bit1:1; //
- uint16 bit2:1; //
- };
- uint16 flat;
-} EVENT_MASK(bnr);
-
-
-typedef union EVENT_MASK(snoop)
-{
- struct
- {
- uint16 dummy0 : 1;
- uint16 dummy1 : 1;
-
- uint16 bit2:1; //
- uint16 dummy3:1; //
- uint16 dummy4:1; //
- uint16 dummy5:1; //
- uint16 bit6:1; //
- uint16 bit7:1; //
- };
- uint16 flat;
-} EVENT_MASK(snoop);
-
-
-typedef union EVENT_MASK(response)
-{
- struct
- {
- uint16 dummy0:1; //
- uint16 bit1:1; //
- uint16 bit2:1; //
- uint16 dummy3:1; //
- uint16 dummy4:1; //
- uint16 dummy5:1; //
- uint16 dummy6:1; //
- uint16 dummy7:1; //
- uint16 bit8:1; //
- uint16 bit9:1; //
- };
- uint16 flat;
-} EVENT_MASK(response);
-
-
-typedef union EVENT_MASK(nbogus_bogus)
-{
- struct
- {
- uint16 NBOGUS:1; // The marked uops are not bogus
- uint16 BOGUS:1; // The marked uops are bogus
- };
- uint16 flat;
-} EVENT_MASK(nbogus_bogus);
-
-
-typedef union EVENT_MASK(execution_event)
-{
- struct
- {
- uint16 NBOGUS0:1; // non-bogus uops with tag bit 0 set },
- uint16 NBOGUS1:1; // non-bogus uops with tag bit 1 set },
- uint16 NBOGUS2:1; // non-bogus uops with tag bit 2 set },
- uint16 NBOGUS3:1; // non-bogus uops with tag bit 3 set },
- uint16 BOGUS0:1; // bogus uops with tag bit 0 set },
- uint16 BOGUS1:1; // bogus uops with tag bit 1 set },
- uint16 BOGUS2:1; // bogus uops with tag bit 2 set },
- uint16 BOGUS3:1; // bogus uops with tag bit 3 set } }
- };
- uint16 flat;
-}EVENT_MASK(execution_event);
-
-typedef union EVENT_MASK(instr_retired)
-{
- struct
- {
- uint16 NBOGUSNTAG:1; // Non-bogus instructions that are not tagged },
- uint16 NBOGUSTAG:1; // Non-bogus instructions that are tagged },
- uint16 BOGUSNTAG:1; // Bogus instructions that are not tagged },
- uint16 BOGUSTAG:1; // Bogus instructions that are tagged } }
- };
- uint16 flat;
-} EVENT_MASK(instr_retired);
-
-
-typedef union EVENT_MASK(uop_type)
-{
- struct
- {
- uint16 dummy0 : 1;
- uint16 TAGLOADS:1; // The uop is a load operation },
- uint16 TAGSTORES:1; // The uop is a store operation } }
- };
- uint16 flat;
-} EVENT_MASK(uop_type);
-
-typedef union EVENT_MASK(branch_retired)
-{
- struct
- {
- uint16 MMNP:1; // Branch Not-taken Predicted
- uint16 MMNM:1; // Branch Not-taken Mispredicted
- uint16 MMTP:1; // Branch Taken Predicted
- uint16 MMTM:1; // Branch Taken Mispredicted
- };
- uint16 flat;
-} EVENT_MASK(branch_retired);
-
-typedef union EVENT_MASK(mispred_branch_retired)
-{
- struct
- {
- uint16 NBOGUS:1; // The retired branch is not bogus } }
- };
- uint16 flat;
-} EVENT_MASK(mispred_branch_retired);
-
-
-typedef union EVENT_MASK(x87_assist)
-{
- struct
- {
- uint16 FPSU:1; // FP stack underflow },
- uint16 FPSO:1; // FP stack overflow },
- uint16 POAO:1; // x87 output overflow },
- uint16 POAU:1; // x87 output underflow },
- uint16 PREA:1; // x87 input assist } }
- };
- uint16 flat;
-}EVENT_MASK(x87_assist);
-
-typedef union EVENT_MASK(machine_clear)
-{
- struct
- {
- uint16 CLEAR:1; // Count a portion of the cycles when the machine is cleared },
- uint16 dummy1: 1;
- uint16 MOCLEAR:1; // Count clears due to memory ordering issues },
- uint16 dummy3: 1;
- uint16 dummy4: 1;
- uint16 dummy5: 1;
-
- uint16 SMCLEAR:1;// Count clears due to self-modifying code issues } }
- };
- uint16 flat;
-} EVENT_MASK(machine_clear);
-
-
-typedef union EVENT_MASK(x87_SIMD_moves_uop)
-{
- struct
- {
- uint16 dummy3:3;
- uint16 ALLP0:1; // Count all x87/SIMD store/move uops },
- uint16 ALLP2:1; // count all x87/SIMD load uops } }
- };
- uint16 flat;
-} EVENT_MASK(x87_SIMD_moves_uop);
-
-
-
-
-
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#pragma once
+
+typedef union EVENT_MASK(TC_deliver_mode)
+{
+ struct
+ {
+ uint16 DD:1; // both logical processors in deliver mode },
+ uint16 DB:1; // logical processor 0 in deliver mode, 1 in build mode },
+ uint16 DI:1; // logical processor 0 in deliver mode, 1 is inactive },
+ uint16 BD:1; // logical processor 0 in build mode, 1 in deliver mode },
+ uint16 BB:1; // both logical processors in build mode },
+ uint16 BI:1; // logical processor 0 in build mode, 1 is inactive },
+ uint16 ID:1; // logical processor 0 is inactive, 1 in deliver mode },
+ uint16 IB:1; // logical processor 0 is inactive, 1 in build mode }
+ };
+ uint16 flat;
+} EVENT_MASK(TC_deliver_mode);
+
+typedef union EVENT_MASK(BPU_fetch_request)
+{
+
+ struct
+ {
+ uint16 TCMISS:1; // Trace cache lookup miss },
+ };
+ uint16 flat;
+} EVENT_MASK(BPU_fetch_request);
+
+
+typedef union EVENT_MASK(ITLB_reference)
+{
+ struct
+ {
+ uint16 HIT : 1; //ITLB hit },
+ uint16 MISS : 1;//ITLB miss },
+ uint16 HIT_UC :1; // Uncacheable ITLB hit }
+ };
+ uint16 flat;
+} EVENT_MASK(ITLB_reference);
+
+typedef union EVENT_MASK(memory_cancel)
+{
+ struct
+ {
+ uint16 dummy : 2;
+
+ uint16 ST_RB_FULL:1; //Replayed because no store request buffer is available },
+ uint16 _64K_CONF:1; //Conflicts due to 64K aliasing }
+ };
+ uint16 flat;
+}EVENT_MASK(memory_cancel);
+
+typedef union EVENT_MASK(memory_complete)
+{
+ struct
+ {
+ uint16 LSC:1; // Load split completed, excluding UC/WC loads },
+ uint16 SSC:1; //Any split stores completed } }
+ };
+ uint16 flat;
+} EVENT_MASK(memory_complete);
+
+typedef union EVENT_MASK(load_port_replay)
+{
+ struct
+ {
+ uint16 dummy:1;
+ uint16 SPLIT_LD:1; //Split load } }
+ };
+ uint16 flat;
+} EVENT_MASK(load_port_replay);
+
+typedef union EVENT_MASK(store_port_replay)
+{
+ struct
+ {
+ uint16 dummy0:1;
+ uint16 SPLIT_ST:1; //Split store } }
+
+ };
+ uint16 flat;
+} EVENT_MASK(store_port_replay);
+
+typedef union EVENT_MASK(MOB_load_replay)
+{
+ struct
+ {
+ uint16 dummy0:1;
+
+ uint16 NO_STA:1; //Replayed because of unknown store address },
+
+ uint16 dummy2:1;
+
+ uint16 NO_STD:1; //Replayed because of unknown store data },
+ uint16 PARTIAL_DATA:1; //Replayed because of partially overlapped data access between the load and store operations },
+ uint16 UNALGN_ADDR:1; //Replayed because the lower 4 bits of the linear address do not match between the load and store operations } }
+ };
+ uint16 flat;
+}EVENT_MASK(MOB_load_replay);
+
+typedef union EVENT_MASK(page_walk_type)
+{
+ struct
+ {
+ uint16 DTMISS:1; // Page walk for a data TLB miss },
+ uint16 ITMISS:1; // Page walk for an instruction TLB miss } }
+ };
+ uint16 flat;
+}EVENT_MASK(page_walk_type);
+
+
+typedef union EVENT_MASK(BSQ_cache_reference)
+{
+ struct
+ {
+ uint16 RD_2ndL_HITS:1; // Read 2nd level cache hit Shared },
+ uint16 RD_2ndL_HITE:1; // Read 2nd level cache hit Exclusive },
+ uint16 RD_2ndL_HITM:1; // Read 2nd level cache hit Modified },
+ uint16 RD_3rdL_HITS:1; // Read 3rd level cache hit Shared },
+ uint16 RD_3rdL_HITE:1; // Read 3rd level cache hit Exclusive },
+ uint16 RD_3rdL_HITM:1; // Read 3rd level cache hit Modified },
+ uint16 dummy6:1;
+ uint16 dummy7:1;
+ uint16 RD_2ndL_MISS:1; // Read 2nd level cache miss },
+ uint16 RD_3rdL_MISS:1; // Read 3rd level cache miss },
+ uint16 WR_2ndL_MISS:1; // Writeback lookup from DAC misses the 2nd level cache } }
+ };
+ uint16 flat;
+} EVENT_MASK(BSQ_cache_reference) ;
+
+typedef union EVENT_MASK(IOQ)
+{
+ struct
+ {
+ uint16 bit0:1; // bus request type (use 00001 for invalid or default)
+ uint16 bit1:1; //
+ uint16 bit2:1; //
+ uint16 bit3:1; //
+ uint16 bit4:1; //
+ uint16 ALL_READ:1; // Count read entries },
+ uint16 ALL_WRITE:1; // Count write entries },
+ uint16 MEM_UC:1; // Count UC memory access entries },
+ uint16 MEM_WC:1; // Count WC memory access entries },
+ uint16 MEM_WT:1; // Count WT memory access entries },
+ uint16 MEM_WP:1; // Count WP memory access entries },
+ uint16 MEM_WB:1; // Count WB memory access entries },
+ uint16 dummy12:1;
+
+ uint16 OWN:1; // Count own store requests },
+ uint16 OTHER:1; // Count other and DMA store requests },
+ uint16 PREFETCH:1; // Include HW and SW prefetch requests } }
+ };
+ uint16 flat;
+} EVENT_MASK(IOQ) ;
+
+typedef union EVENT_MASK(FSB_data_activity)
+{
+ struct
+ {
+ /* DRDY_OWN is mutually exclusive with DRDY_OTHER */
+ /* DBSY_OWN is mutually exclusive with DBSY_OTHER */
+ uint16 DRDY_DRV:1; // Count when this processor drives data onto the bus },
+ uint16 DRDY_OWN:1; // Count when this processor reads data from the bus },
+ uint16 DRDY_OTHER:1; // Count when data is on the bus but not being sampled by the processor },
+ uint16 DBSY_DRV:1; // Count when this processor reserves the bus for driving data },
+ uint16 DBSY_OWN:1; // Count when this processor reserves the bus for sampling data },
+ uint16 DBSY_OTHER:1; // Count when the bus is reserved for driving data this processor will not sample } }
+ };
+ uint16 flat;
+}EVENT_MASK(FSB_data_activity);
+
+typedef union EVENT_MASK(BSQ)
+{
+ struct
+ {
+ uint16 REQ_TYPE0:1; // Request type encoding bit 0 },
+ uint16 REQ_TYPE1:1; // Request type encoding bit 1 },
+ uint16 REQ_LEN0:1; // Request length encoding bit 0 },
+ uint16 REQ_LEN1:1; // Request length encoding bit 1 },
+ uint16 dummy4: 1;
+ uint16 REQ_IO_TYPE:1; // Request type is input or output },
+ uint16 REQ_LOCK_TYPE:1; // Request type is bus lock },
+ uint16 REQ_CACHE_TYPE:1; // Request type is cacheable },
+ uint16 REQ_SPLIT_TYPE:1; // Request type is a bus 8-byte chunk split across 8-byte boundary },
+ uint16 REQ_DEM_TYPE:1; // Request type is a demand (1) or prefetch (0) },
+ uint16 REQ_ORD_TYPE:1; // Request is an ordered type },
+ uint16 MEM_TYPE0:1; // Memory type encoding bit 0 },
+ uint16 MEM_TYPE1:1; // Memory type encoding bit 1 },
+ uint16 MEM_TYPE2:1; // Memory type encoding bit 2 } }
+ };
+ uint16 flat;
+} EVENT_MASK(BSQ);
+
+typedef union EVENT_MASK(firm_uop)
+{
+ struct
+ {
+ uint16 dummy15 : 15;
+ uint16 ALL:1; // count all uops of this type } }
+ };
+ uint16 flat;
+} EVENT_MASK(firm_uop);
+
+
+
+typedef union EVENT_MASK(TC_misc)
+{
+ struct
+ {
+ uint16 dymmy4 : 4;
+ uint16 FLUSH:1; // Number of flushes } }
+ };
+ uint16 flat;
+} EVENT_MASK(TC_misc);
+
+typedef union EVENT_MASK(global_power_events)
+{
+ struct
+ {
+ uint16 Running:1; // The processor is active } }
+ };
+ uint16 flat;
+} EVENT_MASK(global_power_events);
+
+typedef union EVENT_MASK(tc_ms_xfer)
+{
+ struct
+ {
+ uint16 CISC:1; // A TC to MS transfer ocurred } }
+ };
+ uint16 flat;
+}EVENT_MASK(tc_ms_xfer);
+
+
+
+typedef union EVENT_MASK(uop_queue_writes)
+{
+ struct
+ {
+ uint16 FROM_TC_BUILD:1; // uops written from TC build mode
+ uint16 FROM_TC_DELIVER:1; // uops written from TC deliver mode
+ uint16 FROM_ROM:1; // uops written from microcode ROM } }
+ };
+ uint16 flat;
+} EVENT_MASK(uop_queue_writes);
+
+typedef union EVENT_MASK(branch_type)
+{
+ struct
+ {
+ uint16 dummy : 1;
+ uint16 CONDITIONAL:1; // Conditional jumps
+ uint16 CALL:1; // Direct or indirect call
+ uint16 RETURN:1; // Return branches
+ uint16 INDIRECT:1; // Returns, indirect calls, or indirect jumps
+ };
+ uint16 flat;
+} EVENT_MASK(branch_type);
+
+
+
+typedef union EVENT_MASK(resource_stall)
+{
+ struct
+ {
+ uint16 dummy1 : 5;
+ uint16 SBFULL:1; // A Stall due to lack of store buffers } }
+ };
+ uint16 flat;
+} EVENT_MASK(resource_stall);
+
+
+
+
+typedef union EVENT_MASK(WC_Buffer)
+{
+ struct
+ {
+ uint16 WCB_EVICTS : 1; // all causes },
+ uint16 WCB_FULL_EVICT : 1; // no WC buffer is available },
+ /* XXX: 245472-011 no longer lists bit 2, but that looks like
+ a table formatting error. Keeping it for now. */
+ uint16 WCB_HITM_EVICT : 1; // store encountered a Hit Modified condition } }
+ };
+ uint16 flat;
+} EVENT_MASK(WC_Buffer);
+
+
+typedef union EVENT_MASK(b2b_cycles)
+{
+ struct
+ {
+ uint16 dummy0 : 1;
+ uint16 bit1 : 1; //
+ uint16 bit2 : 1; //
+ uint16 bit3 : 1; //
+ uint16 bit4 : 1; //
+ uint16 bit5 : 1; //
+ uint16 bit6 : 1; //
+
+ };
+ uint16 flat;
+} EVENT_MASK(b2b_cycles);
+
+typedef union EVENT_MASK(bnr)
+{
+ struct
+ {
+ uint16 bit0:1; //
+ uint16 bit1:1; //
+ uint16 bit2:1; //
+ };
+ uint16 flat;
+} EVENT_MASK(bnr);
+
+
+typedef union EVENT_MASK(snoop)
+{
+ struct
+ {
+ uint16 dummy0 : 1;
+ uint16 dummy1 : 1;
+
+ uint16 bit2:1; //
+ uint16 dummy3:1; //
+ uint16 dummy4:1; //
+ uint16 dummy5:1; //
+ uint16 bit6:1; //
+ uint16 bit7:1; //
+ };
+ uint16 flat;
+} EVENT_MASK(snoop);
+
+
+typedef union EVENT_MASK(response)
+{
+ struct
+ {
+ uint16 dummy0:1; //
+ uint16 bit1:1; //
+ uint16 bit2:1; //
+ uint16 dummy3:1; //
+ uint16 dummy4:1; //
+ uint16 dummy5:1; //
+ uint16 dummy6:1; //
+ uint16 dummy7:1; //
+ uint16 bit8:1; //
+ uint16 bit9:1; //
+ };
+ uint16 flat;
+} EVENT_MASK(response);
+
+
+typedef union EVENT_MASK(nbogus_bogus)
+{
+ struct
+ {
+ uint16 NBOGUS:1; // The marked uops are not bogus
+ uint16 BOGUS:1; // The marked uops are bogus
+ };
+ uint16 flat;
+} EVENT_MASK(nbogus_bogus);
+
+
+typedef union EVENT_MASK(execution_event)
+{
+ struct
+ {
+ uint16 NBOGUS0:1; // non-bogus uops with tag bit 0 set },
+ uint16 NBOGUS1:1; // non-bogus uops with tag bit 1 set },
+ uint16 NBOGUS2:1; // non-bogus uops with tag bit 2 set },
+ uint16 NBOGUS3:1; // non-bogus uops with tag bit 3 set },
+ uint16 BOGUS0:1; // bogus uops with tag bit 0 set },
+ uint16 BOGUS1:1; // bogus uops with tag bit 1 set },
+ uint16 BOGUS2:1; // bogus uops with tag bit 2 set },
+ uint16 BOGUS3:1; // bogus uops with tag bit 3 set } }
+ };
+ uint16 flat;
+}EVENT_MASK(execution_event);
+
+typedef union EVENT_MASK(instr_retired)
+{
+ struct
+ {
+ uint16 NBOGUSNTAG:1; // Non-bogus instructions that are not tagged },
+ uint16 NBOGUSTAG:1; // Non-bogus instructions that are tagged },
+ uint16 BOGUSNTAG:1; // Bogus instructions that are not tagged },
+ uint16 BOGUSTAG:1; // Bogus instructions that are tagged } }
+ };
+ uint16 flat;
+} EVENT_MASK(instr_retired);
+
+
+typedef union EVENT_MASK(uop_type)
+{
+ struct
+ {
+ uint16 dummy0 : 1;
+ uint16 TAGLOADS:1; // The uop is a load operation },
+ uint16 TAGSTORES:1; // The uop is a store operation } }
+ };
+ uint16 flat;
+} EVENT_MASK(uop_type);
+
+typedef union EVENT_MASK(branch_retired)
+{
+ struct
+ {
+ uint16 MMNP:1; // Branch Not-taken Predicted
+ uint16 MMNM:1; // Branch Not-taken Mispredicted
+ uint16 MMTP:1; // Branch Taken Predicted
+ uint16 MMTM:1; // Branch Taken Mispredicted
+ };
+ uint16 flat;
+} EVENT_MASK(branch_retired);
+
+typedef union EVENT_MASK(mispred_branch_retired)
+{
+ struct
+ {
+ uint16 NBOGUS:1; // The retired branch is not bogus } }
+ };
+ uint16 flat;
+} EVENT_MASK(mispred_branch_retired);
+
+
+typedef union EVENT_MASK(x87_assist)
+{
+ struct
+ {
+ uint16 FPSU:1; // FP stack underflow },
+ uint16 FPSO:1; // FP stack overflow },
+ uint16 POAO:1; // x87 output overflow },
+ uint16 POAU:1; // x87 output underflow },
+ uint16 PREA:1; // x87 input assist } }
+ };
+ uint16 flat;
+}EVENT_MASK(x87_assist);
+
+typedef union EVENT_MASK(machine_clear)
+{
+ struct
+ {
+ uint16 CLEAR:1; // Count a portion of the cycles when the machine is cleared },
+ uint16 dummy1: 1;
+ uint16 MOCLEAR:1; // Count clears due to memory ordering issues },
+ uint16 dummy3: 1;
+ uint16 dummy4: 1;
+ uint16 dummy5: 1;
+
+ uint16 SMCLEAR:1;// Count clears due to self-modifying code issues } }
+ };
+ uint16 flat;
+} EVENT_MASK(machine_clear);
+
+
+typedef union EVENT_MASK(x87_SIMD_moves_uop)
+{
+ struct
+ {
+ uint16 dummy3:3;
+ uint16 ALLP0:1; // Count all x87/SIMD store/move uops },
+ uint16 ALLP2:1; // count all x87/SIMD load uops } }
+ };
+ uint16 flat;
+} EVENT_MASK(x87_SIMD_moves_uop);
+
+
+
+
+
+
+
diff --git a/sp/src/public/tier0/EventModes.h b/sp/src/public/tier0/EventModes.h
index 51647d5b..b6b97565 100644
--- a/sp/src/public/tier0/EventModes.h
+++ b/sp/src/public/tier0/EventModes.h
@@ -1,1787 +1,1787 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef EVENTMODES_H
-#define EVENTMODES_H
-
-
-#pragma once
-
-/*
-
-
-
- Event Modes to choose from:
-
- P4Event_TC_deliver_mode
-
- P4Event_BPU_fetch_request
-
- P4Event_ITLB_reference
-
- P4Event_memory_cancel
-
- P4Event_memory_complete
-
- P4Event_load_port_replay
-
- P4Event_store_port_replay
-
- P4Event_MOB_load_replay
-
- P4Event_page_walk_type
-
- P4Event_BSQ_cache_reference
-
- P4Event_IOQ_allocation
-
- P4Event_IOQ_active_entries
-
- P4Event_FSB_data_activity
-
- P4Event_BSQ_allocation
-
- P4Event_BSQ_active_entries
-
- P4Event_SSE_input_assist
-
- P4Event_packed_SP_uop
-
- P4Event_packed_DP_uop
-
- P4Event_scalar_SP_uop
-
- P4Event_scalar_DP_uop
-
- P4Event_64bit_MMX_uop
-
- P4Event_128bit_MMX_uop
-
- P4Event_x87_FP_uop
-
- P4Event_x87_SIMD_moves_uop
-
- P4Event_TC_misc
-
- P4Event_global_power_events
-
- P4Event_tc_ms_xfer
-
- P4Event_uop_queue_writes
-
- P4Event_retired_mispred_branch_type
-
- P4Event_retired_branch_type
-
- P4Event_resource_stall
-
- P4Event_WC_Buffer
-
- P4Event_b2b_cycles
-
- P4Event_bnr
-
- P4Event_snoop
-
- P4Event_response
-
- P4Event_front_end_event
-
- P4Event_execution_event
-
- P4Event_replay_event
-
- P4Event_instr_retired
-
- P4Event_uops_retired
-
- P4Event_uop_type
-
- P4Event_branch_retired
-
- P4Event_mispred_branch_retired
-
- P4Event_x87_assist
-
- P4Event_machine_clear
-
-
-*/
-
-
-
-class P4P4Event_TC_deliver_mode: public P4BaseEvent
-{
-public:
- EVENT_MASK(TC_deliver_mode) * eventMask;
-
- P4P4Event_TC_deliver_mode()
- {
- eventMask = (EVENT_MASK(TC_deliver_mode) *)&m_eventMask;
-
- escr.ESCREventSelect = 0x01;
- cccr.CCCRSelect = 0x01;
- //// eventType = EVENT_TYPE(TC_deliver_mode);
- description = _T("TC_deliver_mode");
- UseCounter4();
- }
-
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-
-class P4P4Event_BPU_fetch_request: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(BPU_fetch_request)* eventMask;
-
- P4P4Event_BPU_fetch_request()
- {
- eventMask = (EVENT_MASK(BPU_fetch_request) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x03;
- cccr.CCCRSelect= 0x00;
- // eventType = EVENT_TYPE(BPU_fetch_request);
- description=_T("BPU_fetch_request");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-
-};
-class P4P4Event_ITLB_reference: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(ITLB_reference) * eventMask;
-
- P4P4Event_ITLB_reference()
- {
- eventMask = (EVENT_MASK(ITLB_reference) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x18;
- cccr.CCCRSelect= 0x03;
- // eventType=EVENT_TYPE(ITLB_reference);
- description=_T("ITLB_reference");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_memory_cancel: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(memory_cancel) * eventMask;
-
- P4Event_memory_cancel()
- {
- eventMask = (EVENT_MASK(memory_cancel) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x02;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(memory_cancel);
- description=_T("memory_cancel");
- UseCounter8();
- }
-
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_memory_complete: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(memory_complete) * eventMask;
-
- P4Event_memory_complete()
- {
- eventMask = (EVENT_MASK(memory_complete) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x08;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(memory_complete);
- description=_T("memory_complete");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_load_port_replay: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(load_port_replay) * eventMask;
-
- P4Event_load_port_replay()
- {
- eventMask = (EVENT_MASK(load_port_replay) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x04;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(load_port_replay);
- description=_T("load_port_replay");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_store_port_replay: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(store_port_replay) * eventMask;
-
- P4Event_store_port_replay()
- {
- eventMask = (EVENT_MASK(store_port_replay) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x05;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(store_port_replay);
- description=_T("store_port_replay");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_MOB_load_replay: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(MOB_load_replay) * eventMask;
-
- P4Event_MOB_load_replay()
- {
- eventMask = (EVENT_MASK(MOB_load_replay) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x03;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(MOB_load_replay);
- description=_T("MOB_load_replay");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_page_walk_type: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(page_walk_type) * eventMask;
-
- P4Event_page_walk_type()
- {
- eventMask = (EVENT_MASK(page_walk_type) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x01;
- cccr.CCCRSelect= 0x04;
- // eventType=EVENT_TYPE(page_walk_type);
- description=_T("page_walk_type");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_BSQ_cache_reference: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(BSQ_cache_reference) * eventMask;
-
- P4Event_BSQ_cache_reference()
- {
- eventMask = (EVENT_MASK(BSQ_cache_reference) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x0C;
- cccr.CCCRSelect= 0x07;
- // eventType=EVENT_TYPE(BSQ_cache_reference);
- description=_T("BSQ_cache_reference");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_IOQ_allocation: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(IOQ) * eventMask;
-
- P4Event_IOQ_allocation()
- {
- eventMask = (EVENT_MASK(IOQ) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x03;
- cccr.CCCRSelect= 0x06;
- // eventType=EVENT_TYPE(IOQ);
- description=_T("IOQ_allocation");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_IOQ_active_entries: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(IOQ) * eventMask;
-
- P4Event_IOQ_active_entries()
- {
- eventMask = (EVENT_MASK(IOQ) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x1A;
- cccr.CCCRSelect= 0x06;
- // eventType=EVENT_TYPE(IOQ);
- description=_T("IOQ_active_entries");
- UseCounter2();
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_FSB_data_activity: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(FSB_data_activity) * eventMask;
-
- P4Event_FSB_data_activity()
- {
- eventMask = (EVENT_MASK(FSB_data_activity) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x17;
- cccr.CCCRSelect= 0x06;
- // eventType=EVENT_TYPE(FSB_data_activity);
- description=_T("FSB_data_activity");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_BSQ_allocation: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(BSQ) * eventMask;
-
- P4Event_BSQ_allocation()
- {
- eventMask = (EVENT_MASK(BSQ) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x05;
- cccr.CCCRSelect= 0x07;
- // eventType=EVENT_TYPE(BSQ);
- description=_T("BSQ_allocation");
- UseCounter0();
- }
-
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
-
- }
-};
-class P4Event_BSQ_active_entries: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(BSQ) * eventMask;
-
- P4Event_BSQ_active_entries()
- {
- eventMask = (EVENT_MASK(BSQ) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x06;
- cccr.CCCRSelect= 0x07;
- // eventType=EVENT_TYPE(BSQ);
- description=_T("bsq_active_entries");
- UseCounter2();
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_SSE_input_assist: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_SSE_input_assist()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x34;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("SSE_input_assist");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_packed_SP_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_packed_SP_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x08;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("packed_SP_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_packed_DP_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_packed_DP_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x0C;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("packed_DP_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_scalar_SP_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_scalar_SP_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x0A;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("scalar_SP_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_scalar_DP_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_scalar_DP_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x0E;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("scalar_DP_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_64bit_MMX_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_64bit_MMX_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x02;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("64bit_MMX_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_128bit_MMX_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_128bit_MMX_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x1A;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("128bit_MMX_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_x87_FP_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(firm_uop) * eventMask;
-
- P4Event_x87_FP_uop()
- {
- eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x04;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(firm_uop);
- description=_T("x87_FP_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_x87_SIMD_moves_uop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(x87_SIMD_moves_uop) * eventMask;
-
- P4Event_x87_SIMD_moves_uop()
- {
- eventMask = (EVENT_MASK(x87_SIMD_moves_uop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x2E;
- cccr.CCCRSelect= 0;
- // eventType=EVENT_TYPE(x87_SIMD_moves_uop);
- description=_T("x87_SIMD_moves_uop");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_TC_misc: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(TC_misc) * eventMask;
-
- P4Event_TC_misc()
- {
- eventMask = (EVENT_MASK(TC_misc) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x06;
- cccr.CCCRSelect= 0x01;
- // eventType=EVENT_TYPE(TC_misc);
- description=_T("TC_misc");
- UseCounter4();
- }
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-class P4Event_global_power_events: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(global_power_events) * eventMask;
-
- P4Event_global_power_events()
- {
- eventMask = (EVENT_MASK(global_power_events) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x13;
- cccr.CCCRSelect= 0x06;
- // eventType=EVENT_TYPE(global_power_events);
- description=_T("global_power_events");
- UseCounter0();
- }
-
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_tc_ms_xfer: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(tc_ms_xfer) * eventMask;
-
- P4Event_tc_ms_xfer()
- {
- eventMask = (EVENT_MASK(tc_ms_xfer) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x05;
- cccr.CCCRSelect= 0x00;
- // eventType=EVENT_TYPE(tc_ms_xfer);
- description=_T("tc_ms_xfer");
- UseCounter4();
- }
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-class P4Event_uop_queue_writes: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(uop_queue_writes) * eventMask;
-
- P4Event_uop_queue_writes()
- {
- eventMask = (EVENT_MASK(uop_queue_writes) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x09;
- cccr.CCCRSelect= 0x00;
- // eventType=EVENT_TYPE(uop_queue_writes);
- description=_T("uop_queue_writes");
- UseCounter4();
- }
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-class P4Event_retired_mispred_branch_type: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(branch_type) * eventMask;
-
- P4Event_retired_mispred_branch_type()
- {
- eventMask = (EVENT_MASK(branch_type) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x05;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(branch_type);
- description=_T("retired_mispred_branch_type");
- UseCounter4();
- }
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-class P4Event_retired_branch_type: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(branch_type) * eventMask;
-
- P4Event_retired_branch_type()
- {
- eventMask = (EVENT_MASK(branch_type) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x04;
- cccr.CCCRSelect= 0x04;
- // eventType=EVENT_TYPE(branch_type);
- description=_T("retired_branch_type");
- UseCounter4();
- }
-
- void UseCounter4()
- {
- SetCounter(4);;
- }
- void UseCounter5()
- {
- SetCounter(5);
- }
- void UseCounter6()
- {
- SetCounter(6);
- }
- void UseCounter7()
- {
- SetCounter(7);
- }
-};
-class P4Event_resource_stall: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(resource_stall) * eventMask;
-
- P4Event_resource_stall()
- {
- eventMask = (EVENT_MASK(resource_stall) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x01;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(resource_stall);
- description=_T("resource_stall");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-
-};
-class P4Event_WC_Buffer: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(WC_Buffer) * eventMask;
-
- P4Event_WC_Buffer()
- {
- eventMask = (EVENT_MASK(WC_Buffer) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x05;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(WC_Buffer);
- description=_T("WC_Buffer");
- UseCounter8();
- }
- void UseCounter8()
- {
- SetCounter(8);
- }
- void UseCounter9()
- {
- SetCounter(9);
- }
- void UseCounter10()
- {
- SetCounter(10);
- }
- void UseCounter11()
- {
- SetCounter(11);
- }
-
-};
-class P4Event_b2b_cycles: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(b2b_cycles) * eventMask;
-
- P4Event_b2b_cycles()
- {
- eventMask = (EVENT_MASK(b2b_cycles) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x16;
- cccr.CCCRSelect= 0x03;
- // eventType=EVENT_TYPE(b2b_cycles);
- description=_T("b2b_cycles");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_bnr: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(bnr) * eventMask;
-
- P4Event_bnr()
- {
- eventMask = (EVENT_MASK(bnr) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x08;
- cccr.CCCRSelect= 0x03;
- // eventType=EVENT_TYPE(bnr);
- description=_T("bnr");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_snoop: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(snoop) * eventMask;
-
- P4Event_snoop()
- {
- eventMask = (EVENT_MASK(snoop) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x06;
- cccr.CCCRSelect= 0x03;
- // eventType=EVENT_TYPE(snoop);
- description=_T("snoop");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_response: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(response) * eventMask;
-
- P4Event_response()
- {
- eventMask = (EVENT_MASK(response) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x04;
- cccr.CCCRSelect= 0x03;
- // eventType=EVENT_TYPE(response);
- description=_T("response");
- UseCounter0();
- }
- void UseCounter0()
- {
- SetCounter(0);
- }
- void UseCounter1()
- {
- SetCounter(1);
- }
- void UseCounter2()
- {
- SetCounter(2);
- }
- void UseCounter3()
- {
- SetCounter(3);
- }
-};
-class P4Event_front_end_event: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(nbogus_bogus) * eventMask;
-
- P4Event_front_end_event()
- {
- eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x08;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(nbogus_bogus);
- description=_T("front_end_event");
- UseCounter12();
- }
-
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_execution_event: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(execution_event) * eventMask;
-
- P4Event_execution_event()
- {
- eventMask = (EVENT_MASK(execution_event) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x0C;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(execution_event);
- description=_T("execution_event");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_replay_event: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(nbogus_bogus) * eventMask;
-
- P4Event_replay_event()
- {
- eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x09;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(nbogus_bogus);
- description=_T("replay_event");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_instr_retired: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(instr_retired) * eventMask;
-
- P4Event_instr_retired()
- {
- eventMask = (EVENT_MASK(instr_retired) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x02;
- cccr.CCCRSelect= 0x04;
- // eventType=EVENT_TYPE(instr_retired);
- description=_T("instr_retired");
- UseCounter12();
- }
-
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_uops_retired: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(nbogus_bogus) * eventMask;
-
- P4Event_uops_retired()
- {
- eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x01;
- cccr.CCCRSelect= 0x04;
- // eventType=EVENT_TYPE(nbogus_bogus);
- description=_T("uops_retired");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_uop_type: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(uop_type) * eventMask;
-
- P4Event_uop_type()
- {
- eventMask = (EVENT_MASK(uop_type) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x02;
- cccr.CCCRSelect= 0x02;
- // eventType=EVENT_TYPE(uop_type);
- description=_T("uop_type");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_branch_retired: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(branch_retired) * eventMask;
-
- P4Event_branch_retired()
- {
- eventMask = (EVENT_MASK(branch_retired) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x06;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(branch_retired);
- description=_T("branch_retired");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_mispred_branch_retired: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(mispred_branch_retired) * eventMask;
-
- P4Event_mispred_branch_retired()
- {
- eventMask = (EVENT_MASK(mispred_branch_retired) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x03;
- cccr.CCCRSelect= 0x04;
- // eventType=EVENT_TYPE(mispred_branch_retired);
- description=_T("mispred_branch_retired");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_x87_assist: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(x87_assist) * eventMask;
-
- P4Event_x87_assist()
- {
- eventMask = (EVENT_MASK(x87_assist) *)&m_eventMask;
-
- escr.ESCREventSelect= 0x03;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(x87_assist);
- description=_T("x87_assist");
- UseCounter12();
- }
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-};
-class P4Event_machine_clear: public P4BaseEvent
-
-{
-public:
- EVENT_MASK(machine_clear) * eventMask;
-
- P4Event_machine_clear()
- {
- eventMask = (EVENT_MASK(machine_clear) *)&m_eventMask;
- escr.ESCREventSelect= 0x02;
- cccr.CCCRSelect= 0x05;
- // eventType=EVENT_TYPE(machine_clear);
- description=_T("machine_clear");
- UseCounter12();
- }
-
-
-
- void UseCounter12()
- {
- SetCounter(12);
- }
- void UseCounter13()
- {
- SetCounter(13);
-
- }
-
- void UseCounter14()
- {
- SetCounter(14);
- }
- void UseCounter15()
- {
- SetCounter(15);
-
- }
-
- void UseCounter16()
- {
- SetCounter(16);
- }
- void UseCounter17()
- {
- SetCounter(17);
-
- }
-
-};
-
-#endif // EVENTMODES_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef EVENTMODES_H
+#define EVENTMODES_H
+
+
+#pragma once
+
+/*
+
+
+
+ Event Modes to choose from:
+
+ P4Event_TC_deliver_mode
+
+ P4Event_BPU_fetch_request
+
+ P4Event_ITLB_reference
+
+ P4Event_memory_cancel
+
+ P4Event_memory_complete
+
+ P4Event_load_port_replay
+
+ P4Event_store_port_replay
+
+ P4Event_MOB_load_replay
+
+ P4Event_page_walk_type
+
+ P4Event_BSQ_cache_reference
+
+ P4Event_IOQ_allocation
+
+ P4Event_IOQ_active_entries
+
+ P4Event_FSB_data_activity
+
+ P4Event_BSQ_allocation
+
+ P4Event_BSQ_active_entries
+
+ P4Event_SSE_input_assist
+
+ P4Event_packed_SP_uop
+
+ P4Event_packed_DP_uop
+
+ P4Event_scalar_SP_uop
+
+ P4Event_scalar_DP_uop
+
+ P4Event_64bit_MMX_uop
+
+ P4Event_128bit_MMX_uop
+
+ P4Event_x87_FP_uop
+
+ P4Event_x87_SIMD_moves_uop
+
+ P4Event_TC_misc
+
+ P4Event_global_power_events
+
+ P4Event_tc_ms_xfer
+
+ P4Event_uop_queue_writes
+
+ P4Event_retired_mispred_branch_type
+
+ P4Event_retired_branch_type
+
+ P4Event_resource_stall
+
+ P4Event_WC_Buffer
+
+ P4Event_b2b_cycles
+
+ P4Event_bnr
+
+ P4Event_snoop
+
+ P4Event_response
+
+ P4Event_front_end_event
+
+ P4Event_execution_event
+
+ P4Event_replay_event
+
+ P4Event_instr_retired
+
+ P4Event_uops_retired
+
+ P4Event_uop_type
+
+ P4Event_branch_retired
+
+ P4Event_mispred_branch_retired
+
+ P4Event_x87_assist
+
+ P4Event_machine_clear
+
+
+*/
+
+
+
+class P4P4Event_TC_deliver_mode: public P4BaseEvent
+{
+public:
+ EVENT_MASK(TC_deliver_mode) * eventMask;
+
+ P4P4Event_TC_deliver_mode()
+ {
+ eventMask = (EVENT_MASK(TC_deliver_mode) *)&m_eventMask;
+
+ escr.ESCREventSelect = 0x01;
+ cccr.CCCRSelect = 0x01;
+ //// eventType = EVENT_TYPE(TC_deliver_mode);
+ description = _T("TC_deliver_mode");
+ UseCounter4();
+ }
+
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+
+class P4P4Event_BPU_fetch_request: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(BPU_fetch_request)* eventMask;
+
+ P4P4Event_BPU_fetch_request()
+ {
+ eventMask = (EVENT_MASK(BPU_fetch_request) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x03;
+ cccr.CCCRSelect= 0x00;
+ // eventType = EVENT_TYPE(BPU_fetch_request);
+ description=_T("BPU_fetch_request");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+
+};
+class P4P4Event_ITLB_reference: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(ITLB_reference) * eventMask;
+
+ P4P4Event_ITLB_reference()
+ {
+ eventMask = (EVENT_MASK(ITLB_reference) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x18;
+ cccr.CCCRSelect= 0x03;
+ // eventType=EVENT_TYPE(ITLB_reference);
+ description=_T("ITLB_reference");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_memory_cancel: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(memory_cancel) * eventMask;
+
+ P4Event_memory_cancel()
+ {
+ eventMask = (EVENT_MASK(memory_cancel) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x02;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(memory_cancel);
+ description=_T("memory_cancel");
+ UseCounter8();
+ }
+
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_memory_complete: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(memory_complete) * eventMask;
+
+ P4Event_memory_complete()
+ {
+ eventMask = (EVENT_MASK(memory_complete) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x08;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(memory_complete);
+ description=_T("memory_complete");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_load_port_replay: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(load_port_replay) * eventMask;
+
+ P4Event_load_port_replay()
+ {
+ eventMask = (EVENT_MASK(load_port_replay) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x04;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(load_port_replay);
+ description=_T("load_port_replay");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_store_port_replay: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(store_port_replay) * eventMask;
+
+ P4Event_store_port_replay()
+ {
+ eventMask = (EVENT_MASK(store_port_replay) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x05;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(store_port_replay);
+ description=_T("store_port_replay");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_MOB_load_replay: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(MOB_load_replay) * eventMask;
+
+ P4Event_MOB_load_replay()
+ {
+ eventMask = (EVENT_MASK(MOB_load_replay) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x03;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(MOB_load_replay);
+ description=_T("MOB_load_replay");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_page_walk_type: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(page_walk_type) * eventMask;
+
+ P4Event_page_walk_type()
+ {
+ eventMask = (EVENT_MASK(page_walk_type) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x01;
+ cccr.CCCRSelect= 0x04;
+ // eventType=EVENT_TYPE(page_walk_type);
+ description=_T("page_walk_type");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_BSQ_cache_reference: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(BSQ_cache_reference) * eventMask;
+
+ P4Event_BSQ_cache_reference()
+ {
+ eventMask = (EVENT_MASK(BSQ_cache_reference) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x0C;
+ cccr.CCCRSelect= 0x07;
+ // eventType=EVENT_TYPE(BSQ_cache_reference);
+ description=_T("BSQ_cache_reference");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_IOQ_allocation: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(IOQ) * eventMask;
+
+ P4Event_IOQ_allocation()
+ {
+ eventMask = (EVENT_MASK(IOQ) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x03;
+ cccr.CCCRSelect= 0x06;
+ // eventType=EVENT_TYPE(IOQ);
+ description=_T("IOQ_allocation");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_IOQ_active_entries: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(IOQ) * eventMask;
+
+ P4Event_IOQ_active_entries()
+ {
+ eventMask = (EVENT_MASK(IOQ) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x1A;
+ cccr.CCCRSelect= 0x06;
+ // eventType=EVENT_TYPE(IOQ);
+ description=_T("IOQ_active_entries");
+ UseCounter2();
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_FSB_data_activity: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(FSB_data_activity) * eventMask;
+
+ P4Event_FSB_data_activity()
+ {
+ eventMask = (EVENT_MASK(FSB_data_activity) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x17;
+ cccr.CCCRSelect= 0x06;
+ // eventType=EVENT_TYPE(FSB_data_activity);
+ description=_T("FSB_data_activity");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_BSQ_allocation: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(BSQ) * eventMask;
+
+ P4Event_BSQ_allocation()
+ {
+ eventMask = (EVENT_MASK(BSQ) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x05;
+ cccr.CCCRSelect= 0x07;
+ // eventType=EVENT_TYPE(BSQ);
+ description=_T("BSQ_allocation");
+ UseCounter0();
+ }
+
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+
+ }
+};
+class P4Event_BSQ_active_entries: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(BSQ) * eventMask;
+
+ P4Event_BSQ_active_entries()
+ {
+ eventMask = (EVENT_MASK(BSQ) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x06;
+ cccr.CCCRSelect= 0x07;
+ // eventType=EVENT_TYPE(BSQ);
+ description=_T("bsq_active_entries");
+ UseCounter2();
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_SSE_input_assist: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_SSE_input_assist()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x34;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("SSE_input_assist");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_packed_SP_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_packed_SP_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x08;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("packed_SP_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_packed_DP_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_packed_DP_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x0C;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("packed_DP_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_scalar_SP_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_scalar_SP_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x0A;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("scalar_SP_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_scalar_DP_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_scalar_DP_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x0E;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("scalar_DP_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_64bit_MMX_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_64bit_MMX_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x02;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("64bit_MMX_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_128bit_MMX_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_128bit_MMX_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x1A;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("128bit_MMX_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_x87_FP_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(firm_uop) * eventMask;
+
+ P4Event_x87_FP_uop()
+ {
+ eventMask = (EVENT_MASK(firm_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x04;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(firm_uop);
+ description=_T("x87_FP_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_x87_SIMD_moves_uop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(x87_SIMD_moves_uop) * eventMask;
+
+ P4Event_x87_SIMD_moves_uop()
+ {
+ eventMask = (EVENT_MASK(x87_SIMD_moves_uop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x2E;
+ cccr.CCCRSelect= 0;
+ // eventType=EVENT_TYPE(x87_SIMD_moves_uop);
+ description=_T("x87_SIMD_moves_uop");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_TC_misc: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(TC_misc) * eventMask;
+
+ P4Event_TC_misc()
+ {
+ eventMask = (EVENT_MASK(TC_misc) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x06;
+ cccr.CCCRSelect= 0x01;
+ // eventType=EVENT_TYPE(TC_misc);
+ description=_T("TC_misc");
+ UseCounter4();
+ }
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+class P4Event_global_power_events: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(global_power_events) * eventMask;
+
+ P4Event_global_power_events()
+ {
+ eventMask = (EVENT_MASK(global_power_events) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x13;
+ cccr.CCCRSelect= 0x06;
+ // eventType=EVENT_TYPE(global_power_events);
+ description=_T("global_power_events");
+ UseCounter0();
+ }
+
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_tc_ms_xfer: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(tc_ms_xfer) * eventMask;
+
+ P4Event_tc_ms_xfer()
+ {
+ eventMask = (EVENT_MASK(tc_ms_xfer) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x05;
+ cccr.CCCRSelect= 0x00;
+ // eventType=EVENT_TYPE(tc_ms_xfer);
+ description=_T("tc_ms_xfer");
+ UseCounter4();
+ }
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+class P4Event_uop_queue_writes: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(uop_queue_writes) * eventMask;
+
+ P4Event_uop_queue_writes()
+ {
+ eventMask = (EVENT_MASK(uop_queue_writes) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x09;
+ cccr.CCCRSelect= 0x00;
+ // eventType=EVENT_TYPE(uop_queue_writes);
+ description=_T("uop_queue_writes");
+ UseCounter4();
+ }
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+class P4Event_retired_mispred_branch_type: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(branch_type) * eventMask;
+
+ P4Event_retired_mispred_branch_type()
+ {
+ eventMask = (EVENT_MASK(branch_type) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x05;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(branch_type);
+ description=_T("retired_mispred_branch_type");
+ UseCounter4();
+ }
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+class P4Event_retired_branch_type: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(branch_type) * eventMask;
+
+ P4Event_retired_branch_type()
+ {
+ eventMask = (EVENT_MASK(branch_type) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x04;
+ cccr.CCCRSelect= 0x04;
+ // eventType=EVENT_TYPE(branch_type);
+ description=_T("retired_branch_type");
+ UseCounter4();
+ }
+
+ void UseCounter4()
+ {
+ SetCounter(4);;
+ }
+ void UseCounter5()
+ {
+ SetCounter(5);
+ }
+ void UseCounter6()
+ {
+ SetCounter(6);
+ }
+ void UseCounter7()
+ {
+ SetCounter(7);
+ }
+};
+class P4Event_resource_stall: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(resource_stall) * eventMask;
+
+ P4Event_resource_stall()
+ {
+ eventMask = (EVENT_MASK(resource_stall) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x01;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(resource_stall);
+ description=_T("resource_stall");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+
+};
+class P4Event_WC_Buffer: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(WC_Buffer) * eventMask;
+
+ P4Event_WC_Buffer()
+ {
+ eventMask = (EVENT_MASK(WC_Buffer) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x05;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(WC_Buffer);
+ description=_T("WC_Buffer");
+ UseCounter8();
+ }
+ void UseCounter8()
+ {
+ SetCounter(8);
+ }
+ void UseCounter9()
+ {
+ SetCounter(9);
+ }
+ void UseCounter10()
+ {
+ SetCounter(10);
+ }
+ void UseCounter11()
+ {
+ SetCounter(11);
+ }
+
+};
+class P4Event_b2b_cycles: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(b2b_cycles) * eventMask;
+
+ P4Event_b2b_cycles()
+ {
+ eventMask = (EVENT_MASK(b2b_cycles) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x16;
+ cccr.CCCRSelect= 0x03;
+ // eventType=EVENT_TYPE(b2b_cycles);
+ description=_T("b2b_cycles");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_bnr: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(bnr) * eventMask;
+
+ P4Event_bnr()
+ {
+ eventMask = (EVENT_MASK(bnr) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x08;
+ cccr.CCCRSelect= 0x03;
+ // eventType=EVENT_TYPE(bnr);
+ description=_T("bnr");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_snoop: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(snoop) * eventMask;
+
+ P4Event_snoop()
+ {
+ eventMask = (EVENT_MASK(snoop) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x06;
+ cccr.CCCRSelect= 0x03;
+ // eventType=EVENT_TYPE(snoop);
+ description=_T("snoop");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_response: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(response) * eventMask;
+
+ P4Event_response()
+ {
+ eventMask = (EVENT_MASK(response) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x04;
+ cccr.CCCRSelect= 0x03;
+ // eventType=EVENT_TYPE(response);
+ description=_T("response");
+ UseCounter0();
+ }
+ void UseCounter0()
+ {
+ SetCounter(0);
+ }
+ void UseCounter1()
+ {
+ SetCounter(1);
+ }
+ void UseCounter2()
+ {
+ SetCounter(2);
+ }
+ void UseCounter3()
+ {
+ SetCounter(3);
+ }
+};
+class P4Event_front_end_event: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(nbogus_bogus) * eventMask;
+
+ P4Event_front_end_event()
+ {
+ eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x08;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(nbogus_bogus);
+ description=_T("front_end_event");
+ UseCounter12();
+ }
+
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_execution_event: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(execution_event) * eventMask;
+
+ P4Event_execution_event()
+ {
+ eventMask = (EVENT_MASK(execution_event) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x0C;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(execution_event);
+ description=_T("execution_event");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_replay_event: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(nbogus_bogus) * eventMask;
+
+ P4Event_replay_event()
+ {
+ eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x09;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(nbogus_bogus);
+ description=_T("replay_event");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_instr_retired: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(instr_retired) * eventMask;
+
+ P4Event_instr_retired()
+ {
+ eventMask = (EVENT_MASK(instr_retired) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x02;
+ cccr.CCCRSelect= 0x04;
+ // eventType=EVENT_TYPE(instr_retired);
+ description=_T("instr_retired");
+ UseCounter12();
+ }
+
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_uops_retired: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(nbogus_bogus) * eventMask;
+
+ P4Event_uops_retired()
+ {
+ eventMask = (EVENT_MASK(nbogus_bogus) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x01;
+ cccr.CCCRSelect= 0x04;
+ // eventType=EVENT_TYPE(nbogus_bogus);
+ description=_T("uops_retired");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_uop_type: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(uop_type) * eventMask;
+
+ P4Event_uop_type()
+ {
+ eventMask = (EVENT_MASK(uop_type) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x02;
+ cccr.CCCRSelect= 0x02;
+ // eventType=EVENT_TYPE(uop_type);
+ description=_T("uop_type");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_branch_retired: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(branch_retired) * eventMask;
+
+ P4Event_branch_retired()
+ {
+ eventMask = (EVENT_MASK(branch_retired) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x06;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(branch_retired);
+ description=_T("branch_retired");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_mispred_branch_retired: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(mispred_branch_retired) * eventMask;
+
+ P4Event_mispred_branch_retired()
+ {
+ eventMask = (EVENT_MASK(mispred_branch_retired) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x03;
+ cccr.CCCRSelect= 0x04;
+ // eventType=EVENT_TYPE(mispred_branch_retired);
+ description=_T("mispred_branch_retired");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_x87_assist: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(x87_assist) * eventMask;
+
+ P4Event_x87_assist()
+ {
+ eventMask = (EVENT_MASK(x87_assist) *)&m_eventMask;
+
+ escr.ESCREventSelect= 0x03;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(x87_assist);
+ description=_T("x87_assist");
+ UseCounter12();
+ }
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+};
+class P4Event_machine_clear: public P4BaseEvent
+
+{
+public:
+ EVENT_MASK(machine_clear) * eventMask;
+
+ P4Event_machine_clear()
+ {
+ eventMask = (EVENT_MASK(machine_clear) *)&m_eventMask;
+ escr.ESCREventSelect= 0x02;
+ cccr.CCCRSelect= 0x05;
+ // eventType=EVENT_TYPE(machine_clear);
+ description=_T("machine_clear");
+ UseCounter12();
+ }
+
+
+
+ void UseCounter12()
+ {
+ SetCounter(12);
+ }
+ void UseCounter13()
+ {
+ SetCounter(13);
+
+ }
+
+ void UseCounter14()
+ {
+ SetCounter(14);
+ }
+ void UseCounter15()
+ {
+ SetCounter(15);
+
+ }
+
+ void UseCounter16()
+ {
+ SetCounter(16);
+ }
+ void UseCounter17()
+ {
+ SetCounter(17);
+
+ }
+
+};
+
+#endif // EVENTMODES_H
diff --git a/sp/src/public/tier0/IOCTLCodes.h b/sp/src/public/tier0/IOCTLCodes.h
index 52dfe560..a8f50d0b 100644
--- a/sp/src/public/tier0/IOCTLCodes.h
+++ b/sp/src/public/tier0/IOCTLCodes.h
@@ -1,29 +1,29 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef IOCTLCODES_H
-#define IOCTLCODES_H
-#pragma once
-
-// Define the IOCTL codes we will use. The IOCTL code contains a command
-// identifier, plus other information about the device, the type of access
-// with which the file must have been opened, and the type of buffering.
-
-// Device type -- in the "User Defined" range."
-#define DEVICE_FILE_TYPE 40000
-
-
-// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
-
-#define IOCTL_WRITE_MSR \
- CTL_CODE( DEVICE_FILE_TYPE, 0x900, METHOD_BUFFERED, FILE_READ_ACCESS )
-
-#define IOCTL_READ_MSR \
- CTL_CODE( DEVICE_FILE_TYPE, 0x901, METHOD_BUFFERED, FILE_READ_ACCESS )
-
-
-#endif IOCTLCODES_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef IOCTLCODES_H
+#define IOCTLCODES_H
+#pragma once
+
+// Define the IOCTL codes we will use. The IOCTL code contains a command
+// identifier, plus other information about the device, the type of access
+// with which the file must have been opened, and the type of buffering.
+
+// Device type -- in the "User Defined" range."
+#define DEVICE_FILE_TYPE 40000
+
+
+// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
+
+#define IOCTL_WRITE_MSR \
+ CTL_CODE( DEVICE_FILE_TYPE, 0x900, METHOD_BUFFERED, FILE_READ_ACCESS )
+
+#define IOCTL_READ_MSR \
+ CTL_CODE( DEVICE_FILE_TYPE, 0x901, METHOD_BUFFERED, FILE_READ_ACCESS )
+
+
+#endif IOCTLCODES_H
diff --git a/sp/src/public/tier0/K8PerformanceCounters.h b/sp/src/public/tier0/K8PerformanceCounters.h
index 1c17d7ee..4367dffb 100644
--- a/sp/src/public/tier0/K8PerformanceCounters.h
+++ b/sp/src/public/tier0/K8PerformanceCounters.h
@@ -1,2032 +1,2032 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef K8PERFORMANCECOUNTERS_H
-#define K8PERFORMANCECOUNTERS_H
-
-/*
- * AMD K8 events.
- *
- */
-
-
-
-typedef union EVENT_MASK(NULL_MASK)
-{
- // no tests defined
- uint16 flat;
-} EVENT_MASK(NULL_MASK);
-
-
-#define MSR_K8_EVNTSEL0 0xC0010000 /* .. 0xC0010003 */
-#define MSR_K8_PERFCTR0 0xC0010004 /* .. 0xC0010007 */
-
-# pragma pack(push, 1)
-
-
-
-// access to these bits is through the methods
-typedef union PerfEvtSel
-{
- struct
- {
- uint64 EventMask : 8;
-
- uint64 UnitMask : 8;
- uint64 USR : 1;
- uint64 OS : 1;
- uint64 Edge : 1;
- uint64 PC : 1;
- uint64 INTAPIC : 1;
- uint64 Reserved21 : 1;
- uint64 Enable : 1;
- uint64 Complement : 1; // aka INV
- uint64 Threshold : 8; // aka CounterMask
- uint64 Reserver32 : 32;
- };
- uint64 flat;
-
-} PerfEvtSel;
-
-
-enum UnitEncode
-{
- FP,
- LS,
- DC,
- BU,
- IC,
- UE_Unknown,
- FR,
- NB
-};
-
-# pragma pack(pop)
-
-// Turn off the no return value warning in ReadCounter.
-#pragma warning( disable : 4035 )
-#define k8NUM_COUNTERS 4
-class k8BaseEvent
-{
-public:
-
- PME * pme;
-
- PerfEvtSel eventSelect[k8NUM_COUNTERS];
-
- unsigned short m_eventMask;
- int event_id;
- tchar * name;
- tchar revRequired;
- int eventSelectNum;
- UnitEncode unitEncode;
-
-
- void SetCounter(int n)
- {
- if (n < 0)
- n = 0;
- else if (n > 3)
- n = 3;
- eventSelectNum = n;
-
- }
- k8BaseEvent()
- {
- pme = PME::Instance();
-
- for(int i = 0; i< k8NUM_COUNTERS; i++)
- {
- eventSelect[i].flat = 0;
-
- }
- eventSelectNum = 0;
-
- m_eventMask = 0;
- event_id = 0;
- name = 0;
- revRequired = 'A';
-
-
- }
-
- void SetCaptureMode(PrivilegeCapture priv)
- {
- PerfEvtSel & select = eventSelect[eventSelectNum];
- StopCounter();
-
- switch (priv)
- {
- case OS_Only:
- select.USR = 0;
- select.OS = 1;
- break;
-
- case USR_Only:
- select.USR = 1;
- select.OS = 0;
- break;
-
- case OS_and_USR:
- select.USR = 1;
- select.OS = 1;
- break;
- }
-
-
- select.UnitMask = m_eventMask;
- select.EventMask = event_id;
-
-
- int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
- pme->WriteMSR(selectPort, select.flat);
- }
-
-
- void SetFiltering(CompareState compareEnable,
- CompareMethod compareMethod,
- uint8 threshold,
- EdgeState edgeEnable)
- {
-
- PerfEvtSel & select = eventSelect[eventSelectNum];
-
- StopCounter();
-
- if (compareEnable == CompareDisable)
- select.Threshold = 0;
- else
- select.Threshold = threshold;
-
- select.Complement = compareMethod;
-
- select.Edge = edgeEnable;
-
- int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
- pme->WriteMSR(selectPort, select.flat);
-
-
- }
-
-
- void StartCounter()
- {
- PerfEvtSel & select = eventSelect[eventSelectNum];
-
- select.Enable = 1;
- int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
-
- pme->WriteMSR(selectPort, select.flat);
-
- }
- void StopCounter()
- {
- PerfEvtSel & select = eventSelect[eventSelectNum];
- select.Enable = 0;
- int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
-
- pme->WriteMSR(selectPort, select.flat);
- }
-
-
-
- void ClearCounter()
- {
- PerfEvtSel & select = eventSelect[eventSelectNum];
-
- int counterPort = MSR_K8_PERFCTR0 + eventSelectNum;
-
- pme->WriteMSR(counterPort, 0ui64 ); // clear
- }
-
- void WriteCounter(int64 value)
- {
-
- PerfEvtSel & select = eventSelect[eventSelectNum];
-
- int counterPort = MSR_K8_PERFCTR0 + eventSelectNum;
- pme->WriteMSR(counterPort, value); // clear
- }
-
- int64 ReadCounter()
- {
-
-#if PME_DEBUG
- PerfEvtSel & select = eventSelect[eventSelectNum];
-
- if (select.USR == 0 && select.OS == 0)
- return -1; // no area to collect, use SetCaptureMode
-
- if (select.EventMask == 0)
- return -2; // no event mask set
-
- if (eventSelectNum < 0 || eventSelectNum > 3)
- return -3; // counter not legal
-
- // check revision
-
-#endif
-
- // ReadMSR should work here too, but RDPMC should be faster
- //ReadMSR(counterPort, int64);
-
- // we need to copy this into a temp for some reason
-#ifdef COMPILER_MSVC64
- return __readpmc((unsigned long) eventSelectNum);
-#else
- int temp = eventSelectNum;
- _asm
- {
- mov ecx, temp
- RDPMC
- }
-#endif
-
- }
-
-
-};
-#pragma warning( default : 4035 )
-
-
-
-
-typedef union EVENT_MASK(k8_dispatched_fpu_ops)
-{
- // event 0
- struct
- {
- uint16 AddPipeOps:1; // Add pipe ops excluding junk ops" },
- uint16 MulPipeOps:1; // Multiply pipe ops excluding junk ops" },,
- uint16 StoreOps:1; // Store pipe ops excluding junk ops" },
- uint16 AndPipeOpsJunk:1; // Add pipe junk ops" },,
- uint16 MulPipeOpsJunk:1; // Multiply pipe junk ops" },
- uint16 StoreOpsJunk:1; // Store pipe junk ops" } }
- };
- uint16 flat;
-} EVENT_MASK(k8_dispatched_fpu_ops);
-
-class k8Event_DISPATCHED_FPU_OPS : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCHED_FPU_OPS()
- {
- eventMask = (EVENT_MASK(k8_dispatched_fpu_ops) *)&m_eventMask;
-
- event_id = 0x00;
- unitEncode = FP;
- name = _T("Dispatched FPU ops");
- revRequired = 'B';
- }
- EVENT_MASK(k8_dispatched_fpu_ops) * eventMask;
-
-};
-
-//////////////////////////////////////////////////////////
-
-
-
-class k8Event_NO_FPU_OPS : public k8BaseEvent
-{
-public:
-
- k8Event_NO_FPU_OPS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- event_id = 0x01;
- unitEncode = FP;
-
- name = _T("Cycles with no FPU ops retired");
- revRequired = 'B';
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-//////////////////////////////////////////////////////////
-
-class k8Event_FAST_FPU_OPS : public k8BaseEvent
-{
-public:
-
- k8Event_FAST_FPU_OPS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- event_id = 0x02;
- unitEncode = FP;
-
- name = _T("Dispatched FPU ops that use the fast flag interface");
- revRequired = 'B';
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-//////////////////////////////////////////////////////////
-
-
-typedef union EVENT_MASK(k8_segment_register_load)
-{
-
- struct
- {
- uint16 ES:1;
- uint16 CS:1;
- uint16 SS:1;
- uint16 DS:1;
- uint16 FS:1;
- uint16 GS:1;
- uint16 HS:1;
- };
- uint16 flat;
-} EVENT_MASK(k8_segment_register_load);
-
-
-class k8Event_SEG_REG_LOAD : public k8BaseEvent
-{
-public:
-
- k8Event_SEG_REG_LOAD()
- {
- eventMask = (EVENT_MASK(k8_segment_register_load) *)&m_eventMask;
- name = _T("Segment register load");
- event_id = 0x20;
- unitEncode = LS;
-
- }
- EVENT_MASK(k8_segment_register_load) * eventMask;
-
-};
-
-
-class k8Event_SELF_MODIFY_RESYNC : public k8BaseEvent
-{
-public:
-
- k8Event_SELF_MODIFY_RESYNC()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Microarchitectural resync caused by self modifying code");
- event_id = 0x21;
- unitEncode = LS;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-
-};
-class k8Event_LS_RESYNC_BY_SNOOP : public k8BaseEvent
-{
-public:
-
- k8Event_LS_RESYNC_BY_SNOOP()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- event_id = 0x22;
- unitEncode = LS;
-
- name = _T("Microarchitectural resync caused by snoop");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-
-};
-class k8Event_LS_BUFFER_FULL : public k8BaseEvent
-{
-public:
-
- k8Event_LS_BUFFER_FULL()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("LS Buffer 2 Full");
- event_id = 0x23;
- unitEncode = LS;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-typedef union EVENT_MASK(k8_locked_op)
-{
-
-
- struct
- {
- uint16 NumLockInstr : 1; //Number of lock instructions executed
- uint16 NumCyclesInRequestGrant : 1; //Number of cycles spent in the lock request/grant stage
-
- uint16 NumCyclesForLock:1;
- /*Number of cycles a lock takes to complete once it is
- non-speculative and is the oldest load/store operation
- (non-speculative cycles in Ls2 entry 0)*/
-
-
- };
- uint16 flat;
-
-
-} EVENT_MASK(k8_locked_op);
-
-
-
-class k8Event_LOCKED_OP : public k8BaseEvent
-{
-public:
-
- EVENT_MASK(k8_locked_op) * eventMask;
-
- k8Event_LOCKED_OP()
- {
- eventMask = (EVENT_MASK(k8_locked_op) *)&m_eventMask;
- name = _T("Locked operation");
- event_id = 0x24;
- unitEncode = LS;
-
- revRequired = 'C';
- }
-
-
-};
-
-class k8Event_OP_LATE_CANCEL : public k8BaseEvent
-{
-public:
-
- k8Event_OP_LATE_CANCEL()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Microarchitectural late cancel of an operation");
- event_id = 0x25;
- unitEncode = LS;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("OP_LATE_CANCEL");
-
-
-};
-class k8Event_CFLUSH_RETIRED : public k8BaseEvent
-{
-public:
-
- k8Event_CFLUSH_RETIRED()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Retired CFLUSH instructions");
- event_id = 0x26;
- unitEncode = LS;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("CFLUSH_RETIRED");
-
-
-};
-class k8Event_CPUID_RETIRED : public k8BaseEvent
-{
-public:
-
- k8Event_CPUID_RETIRED()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Retired CPUID instructions");
- event_id = 0x27;
- unitEncode = LS;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("CPUID_RETIRED");
-
-
-};
-
-typedef union EVENT_MASK( k8_cache)
-{
-
- struct
- {
- uint16 Invalid:1;
- uint16 Exclusive:1;
- uint16 Shared:1;
- uint16 Owner:1;
- uint16 Modified:1;
- };
- uint16 flat;
-
-}EVENT_MASK( k8_cache);
- /* 0x40-0x47: from K7 official event set */
-
-
-class k8Event_DATA_CACHE_ACCESSES : public k8BaseEvent
-{
- k8Event_DATA_CACHE_ACCESSES()
- {
-
- event_id = 0x40;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- //_T("DATA_CACHE_ACCESSES"),
- name = _T("Data cache accesses");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-class k8Event_DATA_CACHE_MISSES : public k8BaseEvent
-{
- k8Event_DATA_CACHE_MISSES()
- {
-
- event_id = 0x41;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- //_T("DATA_CACHE_MISSES"),
- name = _T("Data cache misses");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-
-class k8Event_DATA_CACHE_REFILLS_FROM_L2 : public k8BaseEvent
-{
- k8Event_DATA_CACHE_REFILLS_FROM_L2()
- {
-
- event_id = 0x42;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
-
-
- name = _T("Data cache refills from L2");
- }
- EVENT_MASK(k8_cache) * eventMask;
-
-};
-
-class k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM : public k8BaseEvent
-{
- k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM()
- {
-
- event_id = 0x43;
- unitEncode = DC;
-
-
- eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
-
- //UM(k7_um_moesi),
- //_T("DATA_CACHE_REFILLS_FROM_SYSTEM"),
- name = _T("Data cache refills from system");
- }
- EVENT_MASK(k8_cache) * eventMask;
-
-};
-
-class k8Event_DATA_CACHE_WRITEBACKS : public k8BaseEvent
-{
- k8Event_DATA_CACHE_WRITEBACKS()
- {
-
- event_id = 0x44;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
-
- //UM(k7_um_moesi),
- //_T("DATA_CACHE_WRITEBACKS"),
- name = _T("Data cache writebacks");
- }
- EVENT_MASK(k8_cache) * eventMask;
-
-
-};
-
-class k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS : public k8BaseEvent
-{
- k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS()
- {
-
- event_id = 0x45;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- name = _T("L1 DTLB misses and L2 DTLB hits");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-
-};
-
-class k8Event_L1_AND_L2_DTLB_MISSES : public k8BaseEvent
-{
- k8Event_L1_AND_L2_DTLB_MISSES()
- {
-
- event_id = 0x46;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- name = _T("L1 and L2 DTLB misses") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-class k8Event_MISALIGNED_DATA_REFERENCES : public k8BaseEvent
-{
- k8Event_MISALIGNED_DATA_REFERENCES()
- {
-
- event_id = 0x47;
- unitEncode = DC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- //NULL, _T("MISALIGNED_DATA_REFERENCES"),
- name = _T("Misaligned data references");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-
-class k8Event_ACCESS_CANCEL_LATE : public k8BaseEvent
-{
-public:
-
- k8Event_ACCESS_CANCEL_LATE()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Microarchitectural late cancel of an access");
- event_id = 0x48;
- unitEncode = DC;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("ACCESS_CANCEL_LATE");
-
-
-};
-class k8Event_ACCESS_CANCEL_EARLY : public k8BaseEvent
-{
-public:
-
- k8Event_ACCESS_CANCEL_EARLY()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Microarchitectural early cancel of an access");
- event_id = 0x49;
- unitEncode = DC;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("ACCESS_CANCEL_EARLY");
-
-
-};
-typedef union EVENT_MASK( k8_ecc)
-{
- struct
- {
- uint16 ScrubberError : 1; // Scrubber error" },
- uint16 PiggybackScrubberErrors : 1; // Piggyback scrubber errors" } }
- };
- uint16 flat;
-
-}EVENT_MASK( k8_ecc);
-
-
-class k8Event_ECC_BIT_ERR : public k8BaseEvent
-{
-public:
-
- k8Event_ECC_BIT_ERR()
- {
- eventMask = (EVENT_MASK(k8_ecc) *)&m_eventMask;
- name = _T("One bit ECC error recorded found by scrubber");
- event_id = 0x4A;
- unitEncode = DC;
-
- }
- EVENT_MASK(k8_ecc) * eventMask;
- // name = _T("ECC_BIT_ERR");
-
-
-};
-
-// 4B
-typedef union EVENT_MASK( k8_distpatch_prefetch_instructions)
-{
- struct
- {
- uint16 Load : 1;
- uint16 Store : 1;
- uint16 NTA : 1;
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_distpatch_prefetch_instructions);
-
-class k8Event_DISPATCHED_PRE_INSTRS : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCHED_PRE_INSTRS()
- {
- eventMask = (EVENT_MASK(k8_distpatch_prefetch_instructions) *)&m_eventMask;
- name = _T("Dispatched prefetch instructions");
- event_id = 0x4B;
- unitEncode = DC;
-
- }
- EVENT_MASK(k8_distpatch_prefetch_instructions) * eventMask;
- // name = _T("DISPATCHED_PRE_INSTRS");
-
- /* 0x4C: added in Revision C */
-
-};
-
-
-
-typedef union EVENT_MASK( k8_lock_accesses)
-{
- struct
- {
- uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" },
- uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } }
- };
- uint16 flat;
-
-}EVENT_MASK( k8_lock_accesses);
-
-
-
-class k8Event_LOCK_ACCESSES : public k8BaseEvent
-{
-public:
-
- k8Event_LOCK_ACCESSES()
- {
- eventMask = (EVENT_MASK(k8_lock_accesses) *)&m_eventMask;
- name = _T("DCACHE accesses by locks") ;
- event_id = 0x4C;
- unitEncode = DC;
-
- revRequired = 'C';
- }
- EVENT_MASK(k8_lock_accesses) * eventMask;
-
-
-};
-
-
-class k8Event_CYCLES_PROCESSOR_IS_RUNNING : public k8BaseEvent
-{
-public:
-
- k8Event_CYCLES_PROCESSOR_IS_RUNNING()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Cycles processor is running (not in HLT or STPCLK)");
- event_id = 0x76;
- unitEncode = BU;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("CYCLES_PROCESSOR_IS_RUNNING"); /* undocumented *;
-
-
-};
-
-
-typedef union EVENT_MASK( k8_internal_L2_request)
-{
- struct
- {
- uint16 ICFill:1; // IC fill" },
- uint16 DCFill:1; // DC fill" },
- uint16 TLBReload:1; // TLB reload" },
- uint16 TagSnoopRequest:1; // Tag snoop request" },
- uint16 CancelledRequest:1; // Cancelled request" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_internal_L2_request);
-
-class k8Event_BU_INT_L2_REQ : public k8BaseEvent
-{
-public:
-
- k8Event_BU_INT_L2_REQ()
- {
- eventMask = (EVENT_MASK(k8_internal_L2_request) *)&m_eventMask;
- name = _T("Internal L2 request");
- unitEncode = BU;
- event_id = 0x7D;
- }
-
- EVENT_MASK(k8_internal_L2_request) * eventMask;
-} ;
-
- // name = _T("BU_INT_L2_REQ");
-
-
-
-// 7E
-typedef union EVENT_MASK( k8_fill_request_missed_L2)
-{
-
- struct
- {
- uint16 ICFill:1; // IC fill" },
- uint16 DCFill:1; // DC fill" },
- uint16 TLBReload:1; // TLB reload" },
- };
- uint16 flat;
-
-} EVENT_MASK( k8_fill_request_missed_L2);
-
-
-class k8Event_BU_FILL_REQ : public k8BaseEvent
-{
-public:
-
- k8Event_BU_FILL_REQ()
- {
- eventMask = (EVENT_MASK(k8_fill_request_missed_L2) *)&m_eventMask;
- name = _T("Fill request that missed in L2");
- event_id = 0x7E;
- unitEncode = BU;
-
- }
- EVENT_MASK(k8_fill_request_missed_L2) * eventMask;
- // name = _T("BU_FILL_REQ");
-
-
-
-};
-
-
-
-
-// 7F
-typedef union EVENT_MASK( k8_fill_into_L2)
-{
-
- struct
- {
- uint16 DirtyL2Victim:1; // Dirty L2 victim
- uint16 VictimFromL2:1; // Victim from L2
- };
- uint16 flat;
-
-}EVENT_MASK( k8_fill_into_L2);
-
-class k8Event_BU_FILL_L2 : public k8BaseEvent
-{
-public:
-
- k8Event_BU_FILL_L2()
- {
- eventMask = (EVENT_MASK(k8_fill_into_L2) *)&m_eventMask;
- name = _T("Fill into L2");
- event_id = 0x7F;
- unitEncode = BU;
-
- }
- EVENT_MASK(k8_fill_into_L2) * eventMask;
- // name = _T("BU_FILL_L2");
-
-
-};
-
-class k8Event_INSTRUCTION_CACHE_FETCHES : public k8BaseEvent
-{
-public:
- k8Event_INSTRUCTION_CACHE_FETCHES()
- {
- event_id = 0x80;
- unitEncode = IC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- name = _T("Instruction cache fetches");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-class k8Event_INSTRUCTION_CACHE_MISSES : public k8BaseEvent
-{
-public:
- k8Event_INSTRUCTION_CACHE_MISSES()
- {
- event_id = 0x81;
- unitEncode = IC;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- //0xF, NULL, _T("INSTRUCTION_CACHE_MISSES"),
- name = _T("Instruction cache misses");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-class k8Event_IC_REFILL_FROM_L2 : public k8BaseEvent
-{
-public:
-
- k8Event_IC_REFILL_FROM_L2()
- {
- eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
- name = _T("Refill from L2");
- event_id = 0x82;
- unitEncode = IC;
-
- }
- EVENT_MASK(k8_cache) * eventMask;
- // name = _T("IC_REFILL_FROM_L2");
-
-
-
-};
-class k8Event_IC_REFILL_FROM_SYS : public k8BaseEvent
-{
-public:
-
- k8Event_IC_REFILL_FROM_SYS()
- {
- eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
- name = _T("Refill from system");
- event_id = 0x83;
- unitEncode = IC;
-
- }
- EVENT_MASK(k8_cache) * eventMask;
- // name = _T("IC_REFILL_FROM_SYS");
-
-
-
-};
-class k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS : public k8BaseEvent
-{
-public:
- k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS()
- {
-
- event_id = 0x84;
- unitEncode = IC;
-
- name = _T("L1 ITLB misses (and L2 ITLB hits)");
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-
-};
-
-class k8Event_L1_AND_L2_ITLB_MISSES : public k8BaseEvent
-{
-public:
- k8Event_L1_AND_L2_ITLB_MISSES()
- {
- event_id = 0x85;
- unitEncode = IC;
-
- name = _T("(L1 and) L2 ITLB misses");
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-
-
-class k8Event_IC_RESYNC_BY_SNOOP : public k8BaseEvent
-{
-public:
-
- k8Event_IC_RESYNC_BY_SNOOP()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- event_id = 0x86;
- unitEncode = IC;
-
- name = _T("Microarchitectural resync caused by snoop");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("IC_RESYNC_BY_SNOOP");
- /* similar to 0x22; but IC unit instead of LS unit */
-
-
-
-};
-class k8Event_IC_FETCH_STALL : public k8BaseEvent
-{
-public:
-
- k8Event_IC_FETCH_STALL()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Instruction fetch stall");
- event_id = 0x87;
- unitEncode = IC;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("IC_FETCH_STALL");
-
-
-
-};
-class k8Event_IC_STACK_HIT : public k8BaseEvent
-{
-public:
-
- k8Event_IC_STACK_HIT()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Return stack hit");
- event_id = 0x88;
- unitEncode = IC;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("IC_STACK_HIT");
-
-
-
-};
-class k8Event_IC_STACK_OVERFLOW : public k8BaseEvent
-{
-public:
-
- k8Event_IC_STACK_OVERFLOW()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Return stack overflow");
- event_id = 0x89;
- unitEncode = IC;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("IC_STACK_OVERFLOW");
-
-
-
-
-};
-
- /* 0xC0-0xC7: from K7 official event set */
-class k8Event_RETIRED_INSTRUCTIONS : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_INSTRUCTIONS()
- {
- event_id = 0xC0;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- //0xF, NULL, _T("RETIRED_INSTRUCTIONS"),
- name = _T("Retired instructions (includes exceptions, interrupts, resyncs)");
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-
-class k8Event_RETIRED_OPS : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_OPS()
- {
- event_id = 0xC1;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_OPS"),
- name = _T("Retired Ops") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_BRANCHES : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_BRANCHES()
- {
- event_id = 0xC2;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_BRANCHES"),
- name = _T("Retired branches (conditional, unconditional, exceptions, interrupts)") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_BRANCHES_MISPREDICTED : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_BRANCHES_MISPREDICTED()
- {
- event_id = 0xC3;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_BRANCHES_MISPREDICTED"),
- name = _T("Retired branches mispredicted") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_TAKEN_BRANCHES : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_TAKEN_BRANCHES()
- {
- event_id = 0xC4;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES"),
- name = _T("Retired taken branches") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED()
- {
- event_id = 0xC5;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES_MISPREDICTED"),
- name = _T("Retired taken branches mispredicted") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_FAR_CONTROL_TRANSFERS : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_FAR_CONTROL_TRANSFERS()
- {
- event_id = 0xC6;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_FAR_CONTROL_TRANSFERS"),
- name = _T("Retired far control transfers") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-class k8Event_RETIRED_RESYNC_BRANCHES : public k8BaseEvent
-{
-public:
- k8Event_RETIRED_RESYNC_BRANCHES()
- {
- event_id = 0xC7;
- unitEncode = FR;
-
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- //0xF, NULL, _T("RETIRED_RESYNC_BRANCHES"),
- name = _T("Retired resync branches (only non-control transfer branches counted)") ;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-};
-
-class k8Event_RETIRED_NEAR_RETURNS : public k8BaseEvent
-{
-public:
-
- k8Event_RETIRED_NEAR_RETURNS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Retired near returns");
- event_id = 0xC8;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-
-
-};
-class k8Event_RETIRED_RETURNS_MISPREDICT : public k8BaseEvent
-{
-public:
-
- k8Event_RETIRED_RETURNS_MISPREDICT()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Retired near returns mispredicted");
- event_id = 0xC9;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("RETIRED_RETURNS_MISPREDICT");
-
-
-};
-class k8Event_RETIRED_BRANCH_MISCOMPARE : public k8BaseEvent
-{
-public:
-
- k8Event_RETIRED_BRANCH_MISCOMPARE()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Retired taken branches mispredicted due to address miscompare");
- event_id = 0xCA;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("RETIRED_BRANCH_MISCOMPARE");
-
-
-};
-
-
- /* Revision B and later */
-
-typedef union EVENT_MASK( k8_retired_fpu_instr)
-{
- struct
- {
- uint16 DirtyL2Victim:1; // x87 instructions
- uint16 CombinedMMX_3DNow:1; // Combined MMX & 3DNow! instructions" },
- uint16 CombinedPackedSSE_SSE2:1; // Combined packed SSE and SSE2 instructions" },
- uint16 CombinedScalarSSE_SSE2:1; // Combined scalar SSE and SSE2 instructions" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_retired_fpu_instr);
-
-
-class k8Event_RETIRED_FPU_INSTRS : public k8BaseEvent
-{
-public:
-
- k8Event_RETIRED_FPU_INSTRS()
- {
- eventMask = (EVENT_MASK(k8_retired_fpu_instr) *)&m_eventMask;
- event_id = 0xCB;
- unitEncode = FR;
-
- name = _T("Retired FPU instructions");
- revRequired = 'B';
- }
- EVENT_MASK(k8_retired_fpu_instr) * eventMask;
- /* Revision B and later */
-
-
-
-};
-
-// CC
-typedef union EVENT_MASK( k8_retired_fastpath_double_op_instr )
-{
-
- struct
- {
- uint16 LowOpPosition0:1; // With low op in position 0" },
- uint16 LowOpPosition1:1; // With low op in position 1" },
- uint16 LowOpPosition2:1; // With low op in position 2" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_retired_fastpath_double_op_instr);
-
-class k8Event_RETIRED_FASTPATH_INSTRS : public k8BaseEvent
-{
-public:
-
- k8Event_RETIRED_FASTPATH_INSTRS()
- {
- eventMask = (EVENT_MASK(k8_retired_fastpath_double_op_instr) *)&m_eventMask;
- event_id = 0xCC;
- unitEncode = FR;
-
- name = _T("Retired fastpath double op instructions");
- revRequired = 'B';
-
- }
- EVENT_MASK(k8_retired_fastpath_double_op_instr) * eventMask;
-
-
-};
-
-class k8Event_INTERRUPTS_MASKED_CYCLES : public k8BaseEvent
-{
-public:
- k8Event_INTERRUPTS_MASKED_CYCLES()
- {
- event_id = 0xCD;
- unitEncode = FR;
-
- //0xF, NULL, _T("INTERRUPTS_MASKED_CYCLES"),
- name = _T("Interrupts masked cycles (IF=0)") ;
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-class k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES : public k8BaseEvent
-{
-public:
- k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES()
- {
- event_id = 0xCE;
- unitEncode = FR;
-
- //0xF, NULL, _T("INTERRUPTS_MASKED_WHILE_PENDING_CYCLES"),
- name = _T("Interrupts masked while pending cycles (INTR while IF=0)") ;
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-class k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS : public k8BaseEvent
-{
-public:
- k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS()
- {
- event_id = 0xCF;
- unitEncode = FR;
-
- //0xF, NULL, _T("NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS"),
- name = _T("Number of taken hardware interrupts") ;
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- }
- EVENT_MASK(NULL_MASK) * eventMask;
-
-};
-
-
-class k8Event_DECODER_EMPTY : public k8BaseEvent
-{
-public:
-
- k8Event_DECODER_EMPTY()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Nothing to dispatch (decoder empty)");
- event_id = 0xD0;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DECODER_EMPTY");
-
-
-};
-class k8Event_DISPATCH_STALLS : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALLS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stalls (events 0xD2-0xDA combined)");
- event_id = 0xD1;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALLS");
-
-
-
-};
-class k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall from branch abort to retire");
- event_id = 0xD2;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_FROM_BRANCH_ABORT");
-
-
-
-};
-class k8Event_DISPATCH_STALL_SERIALIZATION : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_SERIALIZATION()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall for serialization");
- event_id = 0xD3;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_SERIALIZATION");
-
-
-};
-class k8Event_DISPATCH_STALL_SEG_LOAD : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_SEG_LOAD()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall for segment load");
- event_id = 0xD4;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_SEG_LOAD");
-
-
-
-};
-class k8Event_DISPATCH_STALL_REORDER_BUFFER : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_REORDER_BUFFER()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when reorder buffer is full");
- event_id = 0xD5;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_REORDER_BUFFER");
-
-
-};
-class k8Event_DISPATCH_STALL_RESERVE_STATIONS : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_RESERVE_STATIONS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when reservation stations are full");
- event_id = 0xD6;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_RESERVE_STATIONS");
-
-
-};
-class k8Event_DISPATCH_STALL_FPU : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_FPU()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when FPU is full");
- event_id = 0xD7;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_FPU");
-
-
-};
-class k8Event_DISPATCH_STALL_LS : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_LS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when LS is full");
- event_id = 0xD8;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_LS");
-
-
-};
-class k8Event_DISPATCH_STALL_QUIET_WAIT : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_QUIET_WAIT()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when waiting for all to be quiet");
- event_id = 0xD9;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_QUIET_WAIT");
-
-
-
-};
-class k8Event_DISPATCH_STALL_PENDING : public k8BaseEvent
-{
-public:
-
- k8Event_DISPATCH_STALL_PENDING()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Dispatch stall when far control transfer or resync branch is pending");
- event_id = 0xDA;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DISPATCH_STALL_PENDING");
-
-
-
-};
-
-
-typedef union EVENT_MASK( k8_fpu_exceptions)
-{
-
-
-
- struct
- {
- uint16 x87ReclassMicrofaults:1; // x87 reclass microfaults" },
- uint16 SSERetypeMicrofaults:1; // SSE retype microfaults" },
- uint16 SSEReclassMicrofaults:1; // SSE reclass microfaults" },
- uint16 SSE_x87Microtraps:1; // SSE and x87 microtraps" } }
- };
- uint16 flat;
-
-
-
-}EVENT_MASK( k8_fpu_exceptions);
-
-class k8Event_FPU_EXCEPTIONS : public k8BaseEvent
-{
-public:
-
- k8Event_FPU_EXCEPTIONS()
- {
- eventMask = (EVENT_MASK(k8_fpu_exceptions) *)&m_eventMask;
- event_id = 0xDB;
- unitEncode = FR;
-
- name = _T("FPU exceptions");
- revRequired = 'B';
-
- }
- EVENT_MASK(k8_fpu_exceptions) * eventMask;
- // name = _T("FPU_EXCEPTIONS");
- /* Revision B and later */
-
-
-
-};
-class k8Event_DR0_BREAKPOINTS : public k8BaseEvent
-{
-public:
-
- k8Event_DR0_BREAKPOINTS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Number of breakpoints for DR0");
- event_id = 0xDC;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DR0_BREAKPOINTS");
-
-
-
-};
-class k8Event_DR1_BREAKPOINTS : public k8BaseEvent
-{
-public:
-
- k8Event_DR1_BREAKPOINTS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Number of breakpoints for DR1");
- event_id = 0xDD;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DR1_BREAKPOINTS");
-
-
-
-};
-class k8Event_DR2_BREAKPOINTS : public k8BaseEvent
-{
-public:
-
- k8Event_DR2_BREAKPOINTS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Number of breakpoints for DR2");
- event_id = 0xDE;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DR2_BREAKPOINTS");
-
-
-};
-class k8Event_DR3_BREAKPOINTS : public k8BaseEvent
-{
-public:
-
- k8Event_DR3_BREAKPOINTS()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Number of breakpoints for DR3");
- event_id = 0xDF;
- unitEncode = FR;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DR3_BREAKPOINTS");
-
-
-};
-
-
-
-// E0
-typedef union EVENT_MASK( k8_page_access_event)
-{
- struct
- {
- uint16 PageHit:1; // Page hit" },
- uint16 PageMiss:1; // Page miss" },
- uint16 PageConflict:1; // Page conflict" } }
- };
- uint16 flat;
-
-}EVENT_MASK( k8_page_access_event);
-
-class k8Event_MEM_PAGE_ACCESS : public k8BaseEvent
-{
-public:
-
- k8Event_MEM_PAGE_ACCESS()
- {
- eventMask = (EVENT_MASK(k8_page_access_event) *)&m_eventMask;
- name = _T("Memory controller page access");
- event_id = 0xE0;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_page_access_event) * eventMask;
- // name = _T("MEM_PAGE_ACCESS");
-
-
-};
-class k8Event_MEM_PAGE_TBL_OVERFLOW : public k8BaseEvent
-{
-public:
-
- k8Event_MEM_PAGE_TBL_OVERFLOW()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Memory controller page table overflow");
- event_id = 0xE1;
- unitEncode = NB;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("MEM_PAGE_TBL_OVERFLOW");
-
-
-};
-class k8Event_DRAM_SLOTS_MISSED : public k8BaseEvent
-{
-public:
-
- k8Event_DRAM_SLOTS_MISSED()
- {
- eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
- name = _T("Memory controller DRAM command slots missed (in MemClks)");
- event_id = 0xE2;
- unitEncode = NB;
-
- }
- EVENT_MASK(NULL_MASK) * eventMask;
- // name = _T("DRAM_SLOTS_MISSED");
-
-
-};
-
-
-// e3
-typedef union EVENT_MASK( k8_turnaround)
-{
-
- struct
- {
- uint16 DIMMTurnaround:1; //DIMM turnaround" },
- uint16 ReadToWriteTurnaround:1; //Read to write turnaround" },
- uint16 WriteToReadTurnaround:1; //Write to read turnaround" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_turnaround);
-
-class k8Event_MEM_TURNAROUND : public k8BaseEvent
-{
-public:
-
- k8Event_MEM_TURNAROUND()
- {
- eventMask = (EVENT_MASK(k8_turnaround) *)&m_eventMask;
- name = _T("Memory controller turnaround");
- event_id = 0xE3;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_turnaround) * eventMask;
- // name = _T("MEM_TURNAROUND");
-
-
-};
-
-
-
-
-// E4
-typedef union EVENT_MASK( k8_bypass_counter_saturation)
-{
- struct
- {
- uint16 MEM_HighPriorityBypass:1; // Memory controller high priority bypass" },
- uint16 MEM_LowPriorityBypass:1; // Memory controller low priority bypass" },
- uint16 DRAM_InterfaceBypass:1; // DRAM controller interface bypass" },
- uint16 DRAM_QueueBypass:1; // DRAM controller queue bypass" } }
- };
- uint16 flat;
-
-}EVENT_MASK( k8_bypass_counter_saturation);
-
-class k8Event_MEM_BYPASS_SAT : public k8BaseEvent
-{
-public:
-
- k8Event_MEM_BYPASS_SAT()
- {
- eventMask = (EVENT_MASK(k8_bypass_counter_saturation) *)&m_eventMask;
- name = _T("Memory controller bypass counter saturation");
- event_id = 0xE4;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_bypass_counter_saturation) * eventMask;
- // name = _T("MEM_BYPASS_SAT");
-
-
-};
-
-
-
-//EB
-typedef union EVENT_MASK( k8_sized_commands)
-{
-
- struct
- {
- uint16 NonPostWrSzByte:1; // NonPostWrSzByte" },
- uint16 NonPostWrSzDword:1; // NonPostWrSzDword" },
- uint16 PostWrSzByte:1; // PostWrSzByte" },
- uint16 PostWrSzDword:1; // PostWrSzDword" },
- uint16 RdSzByte:1; // RdSzByte" },
- uint16 RdSzDword:1; // RdSzDword" },
- uint16 RdModWr:1; // RdModWr" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_sized_commands);
-
-
-class k8Event_SIZED_COMMANDS : public k8BaseEvent
-{
-public:
-
- k8Event_SIZED_COMMANDS()
- {
- eventMask = (EVENT_MASK(k8_sized_commands) *)&m_eventMask;
- name = _T("Sized commands");
- event_id = 0xEB;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_sized_commands) * eventMask;
- // name = _T("SIZED_COMMANDS");
-
-
-};
-
-typedef union EVENT_MASK( k8_probe_result)
-{
- struct
- {
- uint16 ProbeMiss:1; // Probe miss" },
- uint16 ProbeHit:1; // Probe hit" },
- uint16 ProbeHitDirtyWithoutMemoryCancel:1; // Probe hit dirty without memory cancel" },
- uint16 ProbeHitDirtyWithMemoryCancel:1; // Probe hit dirty with memory cancel" } }
- uint16 UpstreamDisplayRefreshReads:1; // Rev D and later
- uint16 UpstreamNonDisplayRefreshReads:1; // Rev D and later
- uint16 UpstreamWrites:1; // Rev D and later
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_probe_result);
-
-
-class k8Event_PROBE_RESULT : public k8BaseEvent
-{
-public:
-
- k8Event_PROBE_RESULT()
- {
- eventMask = (EVENT_MASK(k8_probe_result) *)&m_eventMask;
- name = _T("Probe result");
- event_id = 0xEC;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_probe_result) * eventMask;
- // name = _T("PROBE_RESULT");
-
-
-};
-
-typedef union EVENT_MASK( k8_ht)
-{
-
- struct
- {
- uint16 CommandSent:1; //Command sent" },
- uint16 DataSent:1; //Data sent" },
- uint16 BufferReleaseSent:1; //Buffer release sent"
- uint16 NopSent:1; //Nop sent" } }
- };
- uint16 flat;
-
-
-}EVENT_MASK( k8_ht);
-
-
-class k8Event_HYPERTRANSPORT_BUS0_WIDTH : public k8BaseEvent
-{
-public:
-
- k8Event_HYPERTRANSPORT_BUS0_WIDTH()
- {
- eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
- name = _T("Hypertransport (tm) bus 0 bandwidth");
- event_id = 0xF6;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_ht) * eventMask;
- // name = _T("HYPERTRANSPORT_BUS0_WIDTH");
-
-
-};
-class k8Event_HYPERTRANSPORT_BUS1_WIDTH : public k8BaseEvent
-{
-public:
-
- k8Event_HYPERTRANSPORT_BUS1_WIDTH()
- {
- eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
- name = _T("Hypertransport (tm) bus 1 bandwidth");
- event_id = 0xF7;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_ht) * eventMask;
- // name = _T("HYPERTRANSPORT_BUS1_WIDTH");
-
-
-};
-class k8Event_HYPERTRANSPORT_BUS2_WIDTH : public k8BaseEvent
-{
-public:
-
- k8Event_HYPERTRANSPORT_BUS2_WIDTH()
- {
- eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
- name = _T("Hypertransport (tm) bus 2 bandwidth");
- event_id = 0xF8;
- unitEncode = NB;
-
- }
- EVENT_MASK(k8_ht) * eventMask;
- // name = _T("HYPERTRANSPORT_BUS2_WIDTH");
-
-};
-
-//
-//typedef union EVENT_MASK( perfctr_event_set k8_common_event_set)
-//{
-//
-// .cpu_type = PERFCTR_X86_AMD_K8,
-// .event_prefix = _T("K8_"),
-// .include = &k7_official_event_set,
-// .nevents = ARRAY_SIZE(k8_common_events),
-// .events = k8_common_events,
-//}EVENT_MASK( perfctr_event_set k8_common_event_set);
-//
-//typedef union EVENT_MASK( perfctr_event k8_events[])
-//{
-//
-// { 0x24, 0xF, UM(NULL), _T("LOCKED_OP"), /* unit mask changed in Rev. C */
-// _T("Locked operation") },
-//}EVENT_MASK( perfctr_event k8_events[]);
-
-
-
-
-//const struct perfctr_event_set perfctr_k8_event_set)
-//{
-//
-// .cpu_type = PERFCTR_X86_AMD_K8,
-// .event_prefix = _T("K8_"),
-// .include = &k8_common_event_set,
-// .nevents = ARRAY_SIZE(k8_events),
-// .events = k8_events,
-//};
-//
-/*
- * K8 Revision C. Starts at CPUID 0xF58 for Opteron/Athlon64FX and
- * CPUID 0xF48 for Athlon64. (CPUID 0xF51 is Opteron Revision B3.)
- */
-
-
-
-
-
-
-
-
-//
-//typedef union EVENT_MASK( k8_lock_accesses)
-//{
-// struct
-// {
-// uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" },
-// uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } }
-// };
-// uint16 flat;
-//
-//}EVENT_MASK( k8_lock_accesses);
-//
-
-#endif // K8PERFORMANCECOUNTERS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef K8PERFORMANCECOUNTERS_H
+#define K8PERFORMANCECOUNTERS_H
+
+/*
+ * AMD K8 events.
+ *
+ */
+
+
+
+typedef union EVENT_MASK(NULL_MASK)
+{
+ // no tests defined
+ uint16 flat;
+} EVENT_MASK(NULL_MASK);
+
+
+#define MSR_K8_EVNTSEL0 0xC0010000 /* .. 0xC0010003 */
+#define MSR_K8_PERFCTR0 0xC0010004 /* .. 0xC0010007 */
+
+# pragma pack(push, 1)
+
+
+
+// access to these bits is through the methods
+typedef union PerfEvtSel
+{
+ struct
+ {
+ uint64 EventMask : 8;
+
+ uint64 UnitMask : 8;
+ uint64 USR : 1;
+ uint64 OS : 1;
+ uint64 Edge : 1;
+ uint64 PC : 1;
+ uint64 INTAPIC : 1;
+ uint64 Reserved21 : 1;
+ uint64 Enable : 1;
+ uint64 Complement : 1; // aka INV
+ uint64 Threshold : 8; // aka CounterMask
+ uint64 Reserver32 : 32;
+ };
+ uint64 flat;
+
+} PerfEvtSel;
+
+
+enum UnitEncode
+{
+ FP,
+ LS,
+ DC,
+ BU,
+ IC,
+ UE_Unknown,
+ FR,
+ NB
+};
+
+# pragma pack(pop)
+
+// Turn off the no return value warning in ReadCounter.
+#pragma warning( disable : 4035 )
+#define k8NUM_COUNTERS 4
+class k8BaseEvent
+{
+public:
+
+ PME * pme;
+
+ PerfEvtSel eventSelect[k8NUM_COUNTERS];
+
+ unsigned short m_eventMask;
+ int event_id;
+ tchar * name;
+ tchar revRequired;
+ int eventSelectNum;
+ UnitEncode unitEncode;
+
+
+ void SetCounter(int n)
+ {
+ if (n < 0)
+ n = 0;
+ else if (n > 3)
+ n = 3;
+ eventSelectNum = n;
+
+ }
+ k8BaseEvent()
+ {
+ pme = PME::Instance();
+
+ for(int i = 0; i< k8NUM_COUNTERS; i++)
+ {
+ eventSelect[i].flat = 0;
+
+ }
+ eventSelectNum = 0;
+
+ m_eventMask = 0;
+ event_id = 0;
+ name = 0;
+ revRequired = 'A';
+
+
+ }
+
+ void SetCaptureMode(PrivilegeCapture priv)
+ {
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+ StopCounter();
+
+ switch (priv)
+ {
+ case OS_Only:
+ select.USR = 0;
+ select.OS = 1;
+ break;
+
+ case USR_Only:
+ select.USR = 1;
+ select.OS = 0;
+ break;
+
+ case OS_and_USR:
+ select.USR = 1;
+ select.OS = 1;
+ break;
+ }
+
+
+ select.UnitMask = m_eventMask;
+ select.EventMask = event_id;
+
+
+ int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
+ pme->WriteMSR(selectPort, select.flat);
+ }
+
+
+ void SetFiltering(CompareState compareEnable,
+ CompareMethod compareMethod,
+ uint8 threshold,
+ EdgeState edgeEnable)
+ {
+
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+
+ StopCounter();
+
+ if (compareEnable == CompareDisable)
+ select.Threshold = 0;
+ else
+ select.Threshold = threshold;
+
+ select.Complement = compareMethod;
+
+ select.Edge = edgeEnable;
+
+ int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
+ pme->WriteMSR(selectPort, select.flat);
+
+
+ }
+
+
+ void StartCounter()
+ {
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+
+ select.Enable = 1;
+ int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
+
+ pme->WriteMSR(selectPort, select.flat);
+
+ }
+ void StopCounter()
+ {
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+ select.Enable = 0;
+ int selectPort = MSR_K8_EVNTSEL0 + eventSelectNum;
+
+ pme->WriteMSR(selectPort, select.flat);
+ }
+
+
+
+ void ClearCounter()
+ {
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+
+ int counterPort = MSR_K8_PERFCTR0 + eventSelectNum;
+
+ pme->WriteMSR(counterPort, 0ui64 ); // clear
+ }
+
+ void WriteCounter(int64 value)
+ {
+
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+
+ int counterPort = MSR_K8_PERFCTR0 + eventSelectNum;
+ pme->WriteMSR(counterPort, value); // clear
+ }
+
+ int64 ReadCounter()
+ {
+
+#if PME_DEBUG
+ PerfEvtSel & select = eventSelect[eventSelectNum];
+
+ if (select.USR == 0 && select.OS == 0)
+ return -1; // no area to collect, use SetCaptureMode
+
+ if (select.EventMask == 0)
+ return -2; // no event mask set
+
+ if (eventSelectNum < 0 || eventSelectNum > 3)
+ return -3; // counter not legal
+
+ // check revision
+
+#endif
+
+ // ReadMSR should work here too, but RDPMC should be faster
+ //ReadMSR(counterPort, int64);
+
+ // we need to copy this into a temp for some reason
+#ifdef COMPILER_MSVC64
+ return __readpmc((unsigned long) eventSelectNum);
+#else
+ int temp = eventSelectNum;
+ _asm
+ {
+ mov ecx, temp
+ RDPMC
+ }
+#endif
+
+ }
+
+
+};
+#pragma warning( default : 4035 )
+
+
+
+
+typedef union EVENT_MASK(k8_dispatched_fpu_ops)
+{
+ // event 0
+ struct
+ {
+ uint16 AddPipeOps:1; // Add pipe ops excluding junk ops" },
+ uint16 MulPipeOps:1; // Multiply pipe ops excluding junk ops" },,
+ uint16 StoreOps:1; // Store pipe ops excluding junk ops" },
+ uint16 AndPipeOpsJunk:1; // Add pipe junk ops" },,
+ uint16 MulPipeOpsJunk:1; // Multiply pipe junk ops" },
+ uint16 StoreOpsJunk:1; // Store pipe junk ops" } }
+ };
+ uint16 flat;
+} EVENT_MASK(k8_dispatched_fpu_ops);
+
+class k8Event_DISPATCHED_FPU_OPS : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCHED_FPU_OPS()
+ {
+ eventMask = (EVENT_MASK(k8_dispatched_fpu_ops) *)&m_eventMask;
+
+ event_id = 0x00;
+ unitEncode = FP;
+ name = _T("Dispatched FPU ops");
+ revRequired = 'B';
+ }
+ EVENT_MASK(k8_dispatched_fpu_ops) * eventMask;
+
+};
+
+//////////////////////////////////////////////////////////
+
+
+
+class k8Event_NO_FPU_OPS : public k8BaseEvent
+{
+public:
+
+ k8Event_NO_FPU_OPS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ event_id = 0x01;
+ unitEncode = FP;
+
+ name = _T("Cycles with no FPU ops retired");
+ revRequired = 'B';
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+//////////////////////////////////////////////////////////
+
+class k8Event_FAST_FPU_OPS : public k8BaseEvent
+{
+public:
+
+ k8Event_FAST_FPU_OPS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ event_id = 0x02;
+ unitEncode = FP;
+
+ name = _T("Dispatched FPU ops that use the fast flag interface");
+ revRequired = 'B';
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+//////////////////////////////////////////////////////////
+
+
+typedef union EVENT_MASK(k8_segment_register_load)
+{
+
+ struct
+ {
+ uint16 ES:1;
+ uint16 CS:1;
+ uint16 SS:1;
+ uint16 DS:1;
+ uint16 FS:1;
+ uint16 GS:1;
+ uint16 HS:1;
+ };
+ uint16 flat;
+} EVENT_MASK(k8_segment_register_load);
+
+
+class k8Event_SEG_REG_LOAD : public k8BaseEvent
+{
+public:
+
+ k8Event_SEG_REG_LOAD()
+ {
+ eventMask = (EVENT_MASK(k8_segment_register_load) *)&m_eventMask;
+ name = _T("Segment register load");
+ event_id = 0x20;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(k8_segment_register_load) * eventMask;
+
+};
+
+
+class k8Event_SELF_MODIFY_RESYNC : public k8BaseEvent
+{
+public:
+
+ k8Event_SELF_MODIFY_RESYNC()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Microarchitectural resync caused by self modifying code");
+ event_id = 0x21;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+
+};
+class k8Event_LS_RESYNC_BY_SNOOP : public k8BaseEvent
+{
+public:
+
+ k8Event_LS_RESYNC_BY_SNOOP()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ event_id = 0x22;
+ unitEncode = LS;
+
+ name = _T("Microarchitectural resync caused by snoop");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+
+};
+class k8Event_LS_BUFFER_FULL : public k8BaseEvent
+{
+public:
+
+ k8Event_LS_BUFFER_FULL()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("LS Buffer 2 Full");
+ event_id = 0x23;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+typedef union EVENT_MASK(k8_locked_op)
+{
+
+
+ struct
+ {
+ uint16 NumLockInstr : 1; //Number of lock instructions executed
+ uint16 NumCyclesInRequestGrant : 1; //Number of cycles spent in the lock request/grant stage
+
+ uint16 NumCyclesForLock:1;
+ /*Number of cycles a lock takes to complete once it is
+ non-speculative and is the oldest load/store operation
+ (non-speculative cycles in Ls2 entry 0)*/
+
+
+ };
+ uint16 flat;
+
+
+} EVENT_MASK(k8_locked_op);
+
+
+
+class k8Event_LOCKED_OP : public k8BaseEvent
+{
+public:
+
+ EVENT_MASK(k8_locked_op) * eventMask;
+
+ k8Event_LOCKED_OP()
+ {
+ eventMask = (EVENT_MASK(k8_locked_op) *)&m_eventMask;
+ name = _T("Locked operation");
+ event_id = 0x24;
+ unitEncode = LS;
+
+ revRequired = 'C';
+ }
+
+
+};
+
+class k8Event_OP_LATE_CANCEL : public k8BaseEvent
+{
+public:
+
+ k8Event_OP_LATE_CANCEL()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Microarchitectural late cancel of an operation");
+ event_id = 0x25;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("OP_LATE_CANCEL");
+
+
+};
+class k8Event_CFLUSH_RETIRED : public k8BaseEvent
+{
+public:
+
+ k8Event_CFLUSH_RETIRED()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Retired CFLUSH instructions");
+ event_id = 0x26;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("CFLUSH_RETIRED");
+
+
+};
+class k8Event_CPUID_RETIRED : public k8BaseEvent
+{
+public:
+
+ k8Event_CPUID_RETIRED()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Retired CPUID instructions");
+ event_id = 0x27;
+ unitEncode = LS;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("CPUID_RETIRED");
+
+
+};
+
+typedef union EVENT_MASK( k8_cache)
+{
+
+ struct
+ {
+ uint16 Invalid:1;
+ uint16 Exclusive:1;
+ uint16 Shared:1;
+ uint16 Owner:1;
+ uint16 Modified:1;
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_cache);
+ /* 0x40-0x47: from K7 official event set */
+
+
+class k8Event_DATA_CACHE_ACCESSES : public k8BaseEvent
+{
+ k8Event_DATA_CACHE_ACCESSES()
+ {
+
+ event_id = 0x40;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ //_T("DATA_CACHE_ACCESSES"),
+ name = _T("Data cache accesses");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+class k8Event_DATA_CACHE_MISSES : public k8BaseEvent
+{
+ k8Event_DATA_CACHE_MISSES()
+ {
+
+ event_id = 0x41;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ //_T("DATA_CACHE_MISSES"),
+ name = _T("Data cache misses");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+
+class k8Event_DATA_CACHE_REFILLS_FROM_L2 : public k8BaseEvent
+{
+ k8Event_DATA_CACHE_REFILLS_FROM_L2()
+ {
+
+ event_id = 0x42;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
+
+
+ name = _T("Data cache refills from L2");
+ }
+ EVENT_MASK(k8_cache) * eventMask;
+
+};
+
+class k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM : public k8BaseEvent
+{
+ k8Event_DATA_CACHE_REFILLS_FROM_SYSTEM()
+ {
+
+ event_id = 0x43;
+ unitEncode = DC;
+
+
+ eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
+
+ //UM(k7_um_moesi),
+ //_T("DATA_CACHE_REFILLS_FROM_SYSTEM"),
+ name = _T("Data cache refills from system");
+ }
+ EVENT_MASK(k8_cache) * eventMask;
+
+};
+
+class k8Event_DATA_CACHE_WRITEBACKS : public k8BaseEvent
+{
+ k8Event_DATA_CACHE_WRITEBACKS()
+ {
+
+ event_id = 0x44;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
+
+ //UM(k7_um_moesi),
+ //_T("DATA_CACHE_WRITEBACKS"),
+ name = _T("Data cache writebacks");
+ }
+ EVENT_MASK(k8_cache) * eventMask;
+
+
+};
+
+class k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS : public k8BaseEvent
+{
+ k8Event_L1_DTLB_MISSES_AND_L2_DTLB_HITS()
+ {
+
+ event_id = 0x45;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ name = _T("L1 DTLB misses and L2 DTLB hits");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+
+};
+
+class k8Event_L1_AND_L2_DTLB_MISSES : public k8BaseEvent
+{
+ k8Event_L1_AND_L2_DTLB_MISSES()
+ {
+
+ event_id = 0x46;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ name = _T("L1 and L2 DTLB misses") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+class k8Event_MISALIGNED_DATA_REFERENCES : public k8BaseEvent
+{
+ k8Event_MISALIGNED_DATA_REFERENCES()
+ {
+
+ event_id = 0x47;
+ unitEncode = DC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ //NULL, _T("MISALIGNED_DATA_REFERENCES"),
+ name = _T("Misaligned data references");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+
+class k8Event_ACCESS_CANCEL_LATE : public k8BaseEvent
+{
+public:
+
+ k8Event_ACCESS_CANCEL_LATE()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Microarchitectural late cancel of an access");
+ event_id = 0x48;
+ unitEncode = DC;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("ACCESS_CANCEL_LATE");
+
+
+};
+class k8Event_ACCESS_CANCEL_EARLY : public k8BaseEvent
+{
+public:
+
+ k8Event_ACCESS_CANCEL_EARLY()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Microarchitectural early cancel of an access");
+ event_id = 0x49;
+ unitEncode = DC;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("ACCESS_CANCEL_EARLY");
+
+
+};
+typedef union EVENT_MASK( k8_ecc)
+{
+ struct
+ {
+ uint16 ScrubberError : 1; // Scrubber error" },
+ uint16 PiggybackScrubberErrors : 1; // Piggyback scrubber errors" } }
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_ecc);
+
+
+class k8Event_ECC_BIT_ERR : public k8BaseEvent
+{
+public:
+
+ k8Event_ECC_BIT_ERR()
+ {
+ eventMask = (EVENT_MASK(k8_ecc) *)&m_eventMask;
+ name = _T("One bit ECC error recorded found by scrubber");
+ event_id = 0x4A;
+ unitEncode = DC;
+
+ }
+ EVENT_MASK(k8_ecc) * eventMask;
+ // name = _T("ECC_BIT_ERR");
+
+
+};
+
+// 4B
+typedef union EVENT_MASK( k8_distpatch_prefetch_instructions)
+{
+ struct
+ {
+ uint16 Load : 1;
+ uint16 Store : 1;
+ uint16 NTA : 1;
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_distpatch_prefetch_instructions);
+
+class k8Event_DISPATCHED_PRE_INSTRS : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCHED_PRE_INSTRS()
+ {
+ eventMask = (EVENT_MASK(k8_distpatch_prefetch_instructions) *)&m_eventMask;
+ name = _T("Dispatched prefetch instructions");
+ event_id = 0x4B;
+ unitEncode = DC;
+
+ }
+ EVENT_MASK(k8_distpatch_prefetch_instructions) * eventMask;
+ // name = _T("DISPATCHED_PRE_INSTRS");
+
+ /* 0x4C: added in Revision C */
+
+};
+
+
+
+typedef union EVENT_MASK( k8_lock_accesses)
+{
+ struct
+ {
+ uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" },
+ uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } }
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_lock_accesses);
+
+
+
+class k8Event_LOCK_ACCESSES : public k8BaseEvent
+{
+public:
+
+ k8Event_LOCK_ACCESSES()
+ {
+ eventMask = (EVENT_MASK(k8_lock_accesses) *)&m_eventMask;
+ name = _T("DCACHE accesses by locks") ;
+ event_id = 0x4C;
+ unitEncode = DC;
+
+ revRequired = 'C';
+ }
+ EVENT_MASK(k8_lock_accesses) * eventMask;
+
+
+};
+
+
+class k8Event_CYCLES_PROCESSOR_IS_RUNNING : public k8BaseEvent
+{
+public:
+
+ k8Event_CYCLES_PROCESSOR_IS_RUNNING()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Cycles processor is running (not in HLT or STPCLK)");
+ event_id = 0x76;
+ unitEncode = BU;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("CYCLES_PROCESSOR_IS_RUNNING"); /* undocumented *;
+
+
+};
+
+
+typedef union EVENT_MASK( k8_internal_L2_request)
+{
+ struct
+ {
+ uint16 ICFill:1; // IC fill" },
+ uint16 DCFill:1; // DC fill" },
+ uint16 TLBReload:1; // TLB reload" },
+ uint16 TagSnoopRequest:1; // Tag snoop request" },
+ uint16 CancelledRequest:1; // Cancelled request" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_internal_L2_request);
+
+class k8Event_BU_INT_L2_REQ : public k8BaseEvent
+{
+public:
+
+ k8Event_BU_INT_L2_REQ()
+ {
+ eventMask = (EVENT_MASK(k8_internal_L2_request) *)&m_eventMask;
+ name = _T("Internal L2 request");
+ unitEncode = BU;
+ event_id = 0x7D;
+ }
+
+ EVENT_MASK(k8_internal_L2_request) * eventMask;
+} ;
+
+ // name = _T("BU_INT_L2_REQ");
+
+
+
+// 7E
+typedef union EVENT_MASK( k8_fill_request_missed_L2)
+{
+
+ struct
+ {
+ uint16 ICFill:1; // IC fill" },
+ uint16 DCFill:1; // DC fill" },
+ uint16 TLBReload:1; // TLB reload" },
+ };
+ uint16 flat;
+
+} EVENT_MASK( k8_fill_request_missed_L2);
+
+
+class k8Event_BU_FILL_REQ : public k8BaseEvent
+{
+public:
+
+ k8Event_BU_FILL_REQ()
+ {
+ eventMask = (EVENT_MASK(k8_fill_request_missed_L2) *)&m_eventMask;
+ name = _T("Fill request that missed in L2");
+ event_id = 0x7E;
+ unitEncode = BU;
+
+ }
+ EVENT_MASK(k8_fill_request_missed_L2) * eventMask;
+ // name = _T("BU_FILL_REQ");
+
+
+
+};
+
+
+
+
+// 7F
+typedef union EVENT_MASK( k8_fill_into_L2)
+{
+
+ struct
+ {
+ uint16 DirtyL2Victim:1; // Dirty L2 victim
+ uint16 VictimFromL2:1; // Victim from L2
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_fill_into_L2);
+
+class k8Event_BU_FILL_L2 : public k8BaseEvent
+{
+public:
+
+ k8Event_BU_FILL_L2()
+ {
+ eventMask = (EVENT_MASK(k8_fill_into_L2) *)&m_eventMask;
+ name = _T("Fill into L2");
+ event_id = 0x7F;
+ unitEncode = BU;
+
+ }
+ EVENT_MASK(k8_fill_into_L2) * eventMask;
+ // name = _T("BU_FILL_L2");
+
+
+};
+
+class k8Event_INSTRUCTION_CACHE_FETCHES : public k8BaseEvent
+{
+public:
+ k8Event_INSTRUCTION_CACHE_FETCHES()
+ {
+ event_id = 0x80;
+ unitEncode = IC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ name = _T("Instruction cache fetches");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+class k8Event_INSTRUCTION_CACHE_MISSES : public k8BaseEvent
+{
+public:
+ k8Event_INSTRUCTION_CACHE_MISSES()
+ {
+ event_id = 0x81;
+ unitEncode = IC;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ //0xF, NULL, _T("INSTRUCTION_CACHE_MISSES"),
+ name = _T("Instruction cache misses");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+class k8Event_IC_REFILL_FROM_L2 : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_REFILL_FROM_L2()
+ {
+ eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
+ name = _T("Refill from L2");
+ event_id = 0x82;
+ unitEncode = IC;
+
+ }
+ EVENT_MASK(k8_cache) * eventMask;
+ // name = _T("IC_REFILL_FROM_L2");
+
+
+
+};
+class k8Event_IC_REFILL_FROM_SYS : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_REFILL_FROM_SYS()
+ {
+ eventMask = (EVENT_MASK(k8_cache) *)&m_eventMask;
+ name = _T("Refill from system");
+ event_id = 0x83;
+ unitEncode = IC;
+
+ }
+ EVENT_MASK(k8_cache) * eventMask;
+ // name = _T("IC_REFILL_FROM_SYS");
+
+
+
+};
+class k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS : public k8BaseEvent
+{
+public:
+ k8Event_L1_ITLB_MISSES_AND_L2_ITLB_HITS()
+ {
+
+ event_id = 0x84;
+ unitEncode = IC;
+
+ name = _T("L1 ITLB misses (and L2 ITLB hits)");
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+
+};
+
+class k8Event_L1_AND_L2_ITLB_MISSES : public k8BaseEvent
+{
+public:
+ k8Event_L1_AND_L2_ITLB_MISSES()
+ {
+ event_id = 0x85;
+ unitEncode = IC;
+
+ name = _T("(L1 and) L2 ITLB misses");
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+
+
+class k8Event_IC_RESYNC_BY_SNOOP : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_RESYNC_BY_SNOOP()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ event_id = 0x86;
+ unitEncode = IC;
+
+ name = _T("Microarchitectural resync caused by snoop");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("IC_RESYNC_BY_SNOOP");
+ /* similar to 0x22; but IC unit instead of LS unit */
+
+
+
+};
+class k8Event_IC_FETCH_STALL : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_FETCH_STALL()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Instruction fetch stall");
+ event_id = 0x87;
+ unitEncode = IC;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("IC_FETCH_STALL");
+
+
+
+};
+class k8Event_IC_STACK_HIT : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_STACK_HIT()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Return stack hit");
+ event_id = 0x88;
+ unitEncode = IC;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("IC_STACK_HIT");
+
+
+
+};
+class k8Event_IC_STACK_OVERFLOW : public k8BaseEvent
+{
+public:
+
+ k8Event_IC_STACK_OVERFLOW()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Return stack overflow");
+ event_id = 0x89;
+ unitEncode = IC;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("IC_STACK_OVERFLOW");
+
+
+
+
+};
+
+ /* 0xC0-0xC7: from K7 official event set */
+class k8Event_RETIRED_INSTRUCTIONS : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_INSTRUCTIONS()
+ {
+ event_id = 0xC0;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ //0xF, NULL, _T("RETIRED_INSTRUCTIONS"),
+ name = _T("Retired instructions (includes exceptions, interrupts, resyncs)");
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+
+class k8Event_RETIRED_OPS : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_OPS()
+ {
+ event_id = 0xC1;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_OPS"),
+ name = _T("Retired Ops") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_BRANCHES : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_BRANCHES()
+ {
+ event_id = 0xC2;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_BRANCHES"),
+ name = _T("Retired branches (conditional, unconditional, exceptions, interrupts)") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_BRANCHES_MISPREDICTED : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_BRANCHES_MISPREDICTED()
+ {
+ event_id = 0xC3;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_BRANCHES_MISPREDICTED"),
+ name = _T("Retired branches mispredicted") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_TAKEN_BRANCHES : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_TAKEN_BRANCHES()
+ {
+ event_id = 0xC4;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES"),
+ name = _T("Retired taken branches") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_TAKEN_BRANCHES_MISPREDICTED()
+ {
+ event_id = 0xC5;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_TAKEN_BRANCHES_MISPREDICTED"),
+ name = _T("Retired taken branches mispredicted") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_FAR_CONTROL_TRANSFERS : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_FAR_CONTROL_TRANSFERS()
+ {
+ event_id = 0xC6;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_FAR_CONTROL_TRANSFERS"),
+ name = _T("Retired far control transfers") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+class k8Event_RETIRED_RESYNC_BRANCHES : public k8BaseEvent
+{
+public:
+ k8Event_RETIRED_RESYNC_BRANCHES()
+ {
+ event_id = 0xC7;
+ unitEncode = FR;
+
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ //0xF, NULL, _T("RETIRED_RESYNC_BRANCHES"),
+ name = _T("Retired resync branches (only non-control transfer branches counted)") ;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+};
+
+class k8Event_RETIRED_NEAR_RETURNS : public k8BaseEvent
+{
+public:
+
+ k8Event_RETIRED_NEAR_RETURNS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Retired near returns");
+ event_id = 0xC8;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+
+
+};
+class k8Event_RETIRED_RETURNS_MISPREDICT : public k8BaseEvent
+{
+public:
+
+ k8Event_RETIRED_RETURNS_MISPREDICT()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Retired near returns mispredicted");
+ event_id = 0xC9;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("RETIRED_RETURNS_MISPREDICT");
+
+
+};
+class k8Event_RETIRED_BRANCH_MISCOMPARE : public k8BaseEvent
+{
+public:
+
+ k8Event_RETIRED_BRANCH_MISCOMPARE()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Retired taken branches mispredicted due to address miscompare");
+ event_id = 0xCA;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("RETIRED_BRANCH_MISCOMPARE");
+
+
+};
+
+
+ /* Revision B and later */
+
+typedef union EVENT_MASK( k8_retired_fpu_instr)
+{
+ struct
+ {
+ uint16 DirtyL2Victim:1; // x87 instructions
+ uint16 CombinedMMX_3DNow:1; // Combined MMX & 3DNow! instructions" },
+ uint16 CombinedPackedSSE_SSE2:1; // Combined packed SSE and SSE2 instructions" },
+ uint16 CombinedScalarSSE_SSE2:1; // Combined scalar SSE and SSE2 instructions" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_retired_fpu_instr);
+
+
+class k8Event_RETIRED_FPU_INSTRS : public k8BaseEvent
+{
+public:
+
+ k8Event_RETIRED_FPU_INSTRS()
+ {
+ eventMask = (EVENT_MASK(k8_retired_fpu_instr) *)&m_eventMask;
+ event_id = 0xCB;
+ unitEncode = FR;
+
+ name = _T("Retired FPU instructions");
+ revRequired = 'B';
+ }
+ EVENT_MASK(k8_retired_fpu_instr) * eventMask;
+ /* Revision B and later */
+
+
+
+};
+
+// CC
+typedef union EVENT_MASK( k8_retired_fastpath_double_op_instr )
+{
+
+ struct
+ {
+ uint16 LowOpPosition0:1; // With low op in position 0" },
+ uint16 LowOpPosition1:1; // With low op in position 1" },
+ uint16 LowOpPosition2:1; // With low op in position 2" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_retired_fastpath_double_op_instr);
+
+class k8Event_RETIRED_FASTPATH_INSTRS : public k8BaseEvent
+{
+public:
+
+ k8Event_RETIRED_FASTPATH_INSTRS()
+ {
+ eventMask = (EVENT_MASK(k8_retired_fastpath_double_op_instr) *)&m_eventMask;
+ event_id = 0xCC;
+ unitEncode = FR;
+
+ name = _T("Retired fastpath double op instructions");
+ revRequired = 'B';
+
+ }
+ EVENT_MASK(k8_retired_fastpath_double_op_instr) * eventMask;
+
+
+};
+
+class k8Event_INTERRUPTS_MASKED_CYCLES : public k8BaseEvent
+{
+public:
+ k8Event_INTERRUPTS_MASKED_CYCLES()
+ {
+ event_id = 0xCD;
+ unitEncode = FR;
+
+ //0xF, NULL, _T("INTERRUPTS_MASKED_CYCLES"),
+ name = _T("Interrupts masked cycles (IF=0)") ;
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+class k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES : public k8BaseEvent
+{
+public:
+ k8Event_INTERRUPTS_MASKED_WHILE_PENDING_CYCLES()
+ {
+ event_id = 0xCE;
+ unitEncode = FR;
+
+ //0xF, NULL, _T("INTERRUPTS_MASKED_WHILE_PENDING_CYCLES"),
+ name = _T("Interrupts masked while pending cycles (INTR while IF=0)") ;
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+class k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS : public k8BaseEvent
+{
+public:
+ k8Event_NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS()
+ {
+ event_id = 0xCF;
+ unitEncode = FR;
+
+ //0xF, NULL, _T("NUMBER_OF_TAKEN_HARDWARE_INTERRUPTS"),
+ name = _T("Number of taken hardware interrupts") ;
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+
+};
+
+
+class k8Event_DECODER_EMPTY : public k8BaseEvent
+{
+public:
+
+ k8Event_DECODER_EMPTY()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Nothing to dispatch (decoder empty)");
+ event_id = 0xD0;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DECODER_EMPTY");
+
+
+};
+class k8Event_DISPATCH_STALLS : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALLS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stalls (events 0xD2-0xDA combined)");
+ event_id = 0xD1;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALLS");
+
+
+
+};
+class k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_FROM_BRANCH_ABORT()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall from branch abort to retire");
+ event_id = 0xD2;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_FROM_BRANCH_ABORT");
+
+
+
+};
+class k8Event_DISPATCH_STALL_SERIALIZATION : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_SERIALIZATION()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall for serialization");
+ event_id = 0xD3;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_SERIALIZATION");
+
+
+};
+class k8Event_DISPATCH_STALL_SEG_LOAD : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_SEG_LOAD()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall for segment load");
+ event_id = 0xD4;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_SEG_LOAD");
+
+
+
+};
+class k8Event_DISPATCH_STALL_REORDER_BUFFER : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_REORDER_BUFFER()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when reorder buffer is full");
+ event_id = 0xD5;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_REORDER_BUFFER");
+
+
+};
+class k8Event_DISPATCH_STALL_RESERVE_STATIONS : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_RESERVE_STATIONS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when reservation stations are full");
+ event_id = 0xD6;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_RESERVE_STATIONS");
+
+
+};
+class k8Event_DISPATCH_STALL_FPU : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_FPU()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when FPU is full");
+ event_id = 0xD7;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_FPU");
+
+
+};
+class k8Event_DISPATCH_STALL_LS : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_LS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when LS is full");
+ event_id = 0xD8;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_LS");
+
+
+};
+class k8Event_DISPATCH_STALL_QUIET_WAIT : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_QUIET_WAIT()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when waiting for all to be quiet");
+ event_id = 0xD9;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_QUIET_WAIT");
+
+
+
+};
+class k8Event_DISPATCH_STALL_PENDING : public k8BaseEvent
+{
+public:
+
+ k8Event_DISPATCH_STALL_PENDING()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Dispatch stall when far control transfer or resync branch is pending");
+ event_id = 0xDA;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DISPATCH_STALL_PENDING");
+
+
+
+};
+
+
+typedef union EVENT_MASK( k8_fpu_exceptions)
+{
+
+
+
+ struct
+ {
+ uint16 x87ReclassMicrofaults:1; // x87 reclass microfaults" },
+ uint16 SSERetypeMicrofaults:1; // SSE retype microfaults" },
+ uint16 SSEReclassMicrofaults:1; // SSE reclass microfaults" },
+ uint16 SSE_x87Microtraps:1; // SSE and x87 microtraps" } }
+ };
+ uint16 flat;
+
+
+
+}EVENT_MASK( k8_fpu_exceptions);
+
+class k8Event_FPU_EXCEPTIONS : public k8BaseEvent
+{
+public:
+
+ k8Event_FPU_EXCEPTIONS()
+ {
+ eventMask = (EVENT_MASK(k8_fpu_exceptions) *)&m_eventMask;
+ event_id = 0xDB;
+ unitEncode = FR;
+
+ name = _T("FPU exceptions");
+ revRequired = 'B';
+
+ }
+ EVENT_MASK(k8_fpu_exceptions) * eventMask;
+ // name = _T("FPU_EXCEPTIONS");
+ /* Revision B and later */
+
+
+
+};
+class k8Event_DR0_BREAKPOINTS : public k8BaseEvent
+{
+public:
+
+ k8Event_DR0_BREAKPOINTS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Number of breakpoints for DR0");
+ event_id = 0xDC;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DR0_BREAKPOINTS");
+
+
+
+};
+class k8Event_DR1_BREAKPOINTS : public k8BaseEvent
+{
+public:
+
+ k8Event_DR1_BREAKPOINTS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Number of breakpoints for DR1");
+ event_id = 0xDD;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DR1_BREAKPOINTS");
+
+
+
+};
+class k8Event_DR2_BREAKPOINTS : public k8BaseEvent
+{
+public:
+
+ k8Event_DR2_BREAKPOINTS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Number of breakpoints for DR2");
+ event_id = 0xDE;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DR2_BREAKPOINTS");
+
+
+};
+class k8Event_DR3_BREAKPOINTS : public k8BaseEvent
+{
+public:
+
+ k8Event_DR3_BREAKPOINTS()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Number of breakpoints for DR3");
+ event_id = 0xDF;
+ unitEncode = FR;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DR3_BREAKPOINTS");
+
+
+};
+
+
+
+// E0
+typedef union EVENT_MASK( k8_page_access_event)
+{
+ struct
+ {
+ uint16 PageHit:1; // Page hit" },
+ uint16 PageMiss:1; // Page miss" },
+ uint16 PageConflict:1; // Page conflict" } }
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_page_access_event);
+
+class k8Event_MEM_PAGE_ACCESS : public k8BaseEvent
+{
+public:
+
+ k8Event_MEM_PAGE_ACCESS()
+ {
+ eventMask = (EVENT_MASK(k8_page_access_event) *)&m_eventMask;
+ name = _T("Memory controller page access");
+ event_id = 0xE0;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_page_access_event) * eventMask;
+ // name = _T("MEM_PAGE_ACCESS");
+
+
+};
+class k8Event_MEM_PAGE_TBL_OVERFLOW : public k8BaseEvent
+{
+public:
+
+ k8Event_MEM_PAGE_TBL_OVERFLOW()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Memory controller page table overflow");
+ event_id = 0xE1;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("MEM_PAGE_TBL_OVERFLOW");
+
+
+};
+class k8Event_DRAM_SLOTS_MISSED : public k8BaseEvent
+{
+public:
+
+ k8Event_DRAM_SLOTS_MISSED()
+ {
+ eventMask = (EVENT_MASK(NULL_MASK) *)&m_eventMask;
+ name = _T("Memory controller DRAM command slots missed (in MemClks)");
+ event_id = 0xE2;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(NULL_MASK) * eventMask;
+ // name = _T("DRAM_SLOTS_MISSED");
+
+
+};
+
+
+// e3
+typedef union EVENT_MASK( k8_turnaround)
+{
+
+ struct
+ {
+ uint16 DIMMTurnaround:1; //DIMM turnaround" },
+ uint16 ReadToWriteTurnaround:1; //Read to write turnaround" },
+ uint16 WriteToReadTurnaround:1; //Write to read turnaround" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_turnaround);
+
+class k8Event_MEM_TURNAROUND : public k8BaseEvent
+{
+public:
+
+ k8Event_MEM_TURNAROUND()
+ {
+ eventMask = (EVENT_MASK(k8_turnaround) *)&m_eventMask;
+ name = _T("Memory controller turnaround");
+ event_id = 0xE3;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_turnaround) * eventMask;
+ // name = _T("MEM_TURNAROUND");
+
+
+};
+
+
+
+
+// E4
+typedef union EVENT_MASK( k8_bypass_counter_saturation)
+{
+ struct
+ {
+ uint16 MEM_HighPriorityBypass:1; // Memory controller high priority bypass" },
+ uint16 MEM_LowPriorityBypass:1; // Memory controller low priority bypass" },
+ uint16 DRAM_InterfaceBypass:1; // DRAM controller interface bypass" },
+ uint16 DRAM_QueueBypass:1; // DRAM controller queue bypass" } }
+ };
+ uint16 flat;
+
+}EVENT_MASK( k8_bypass_counter_saturation);
+
+class k8Event_MEM_BYPASS_SAT : public k8BaseEvent
+{
+public:
+
+ k8Event_MEM_BYPASS_SAT()
+ {
+ eventMask = (EVENT_MASK(k8_bypass_counter_saturation) *)&m_eventMask;
+ name = _T("Memory controller bypass counter saturation");
+ event_id = 0xE4;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_bypass_counter_saturation) * eventMask;
+ // name = _T("MEM_BYPASS_SAT");
+
+
+};
+
+
+
+//EB
+typedef union EVENT_MASK( k8_sized_commands)
+{
+
+ struct
+ {
+ uint16 NonPostWrSzByte:1; // NonPostWrSzByte" },
+ uint16 NonPostWrSzDword:1; // NonPostWrSzDword" },
+ uint16 PostWrSzByte:1; // PostWrSzByte" },
+ uint16 PostWrSzDword:1; // PostWrSzDword" },
+ uint16 RdSzByte:1; // RdSzByte" },
+ uint16 RdSzDword:1; // RdSzDword" },
+ uint16 RdModWr:1; // RdModWr" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_sized_commands);
+
+
+class k8Event_SIZED_COMMANDS : public k8BaseEvent
+{
+public:
+
+ k8Event_SIZED_COMMANDS()
+ {
+ eventMask = (EVENT_MASK(k8_sized_commands) *)&m_eventMask;
+ name = _T("Sized commands");
+ event_id = 0xEB;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_sized_commands) * eventMask;
+ // name = _T("SIZED_COMMANDS");
+
+
+};
+
+typedef union EVENT_MASK( k8_probe_result)
+{
+ struct
+ {
+ uint16 ProbeMiss:1; // Probe miss" },
+ uint16 ProbeHit:1; // Probe hit" },
+ uint16 ProbeHitDirtyWithoutMemoryCancel:1; // Probe hit dirty without memory cancel" },
+ uint16 ProbeHitDirtyWithMemoryCancel:1; // Probe hit dirty with memory cancel" } }
+ uint16 UpstreamDisplayRefreshReads:1; // Rev D and later
+ uint16 UpstreamNonDisplayRefreshReads:1; // Rev D and later
+ uint16 UpstreamWrites:1; // Rev D and later
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_probe_result);
+
+
+class k8Event_PROBE_RESULT : public k8BaseEvent
+{
+public:
+
+ k8Event_PROBE_RESULT()
+ {
+ eventMask = (EVENT_MASK(k8_probe_result) *)&m_eventMask;
+ name = _T("Probe result");
+ event_id = 0xEC;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_probe_result) * eventMask;
+ // name = _T("PROBE_RESULT");
+
+
+};
+
+typedef union EVENT_MASK( k8_ht)
+{
+
+ struct
+ {
+ uint16 CommandSent:1; //Command sent" },
+ uint16 DataSent:1; //Data sent" },
+ uint16 BufferReleaseSent:1; //Buffer release sent"
+ uint16 NopSent:1; //Nop sent" } }
+ };
+ uint16 flat;
+
+
+}EVENT_MASK( k8_ht);
+
+
+class k8Event_HYPERTRANSPORT_BUS0_WIDTH : public k8BaseEvent
+{
+public:
+
+ k8Event_HYPERTRANSPORT_BUS0_WIDTH()
+ {
+ eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
+ name = _T("Hypertransport (tm) bus 0 bandwidth");
+ event_id = 0xF6;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_ht) * eventMask;
+ // name = _T("HYPERTRANSPORT_BUS0_WIDTH");
+
+
+};
+class k8Event_HYPERTRANSPORT_BUS1_WIDTH : public k8BaseEvent
+{
+public:
+
+ k8Event_HYPERTRANSPORT_BUS1_WIDTH()
+ {
+ eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
+ name = _T("Hypertransport (tm) bus 1 bandwidth");
+ event_id = 0xF7;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_ht) * eventMask;
+ // name = _T("HYPERTRANSPORT_BUS1_WIDTH");
+
+
+};
+class k8Event_HYPERTRANSPORT_BUS2_WIDTH : public k8BaseEvent
+{
+public:
+
+ k8Event_HYPERTRANSPORT_BUS2_WIDTH()
+ {
+ eventMask = (EVENT_MASK(k8_ht) *)&m_eventMask;
+ name = _T("Hypertransport (tm) bus 2 bandwidth");
+ event_id = 0xF8;
+ unitEncode = NB;
+
+ }
+ EVENT_MASK(k8_ht) * eventMask;
+ // name = _T("HYPERTRANSPORT_BUS2_WIDTH");
+
+};
+
+//
+//typedef union EVENT_MASK( perfctr_event_set k8_common_event_set)
+//{
+//
+// .cpu_type = PERFCTR_X86_AMD_K8,
+// .event_prefix = _T("K8_"),
+// .include = &k7_official_event_set,
+// .nevents = ARRAY_SIZE(k8_common_events),
+// .events = k8_common_events,
+//}EVENT_MASK( perfctr_event_set k8_common_event_set);
+//
+//typedef union EVENT_MASK( perfctr_event k8_events[])
+//{
+//
+// { 0x24, 0xF, UM(NULL), _T("LOCKED_OP"), /* unit mask changed in Rev. C */
+// _T("Locked operation") },
+//}EVENT_MASK( perfctr_event k8_events[]);
+
+
+
+
+//const struct perfctr_event_set perfctr_k8_event_set)
+//{
+//
+// .cpu_type = PERFCTR_X86_AMD_K8,
+// .event_prefix = _T("K8_"),
+// .include = &k8_common_event_set,
+// .nevents = ARRAY_SIZE(k8_events),
+// .events = k8_events,
+//};
+//
+/*
+ * K8 Revision C. Starts at CPUID 0xF58 for Opteron/Athlon64FX and
+ * CPUID 0xF48 for Athlon64. (CPUID 0xF51 is Opteron Revision B3.)
+ */
+
+
+
+
+
+
+
+
+//
+//typedef union EVENT_MASK( k8_lock_accesses)
+//{
+// struct
+// {
+// uint16 DcacheAccesses:1; // Number of dcache accesses by lock instructions" },
+// uint16 DcacheMisses:1; // Number of dcache misses by lock instructions" } }
+// };
+// uint16 flat;
+//
+//}EVENT_MASK( k8_lock_accesses);
+//
+
+#endif // K8PERFORMANCECOUNTERS_H
diff --git a/sp/src/public/tier0/P4PerformanceCounters.h b/sp/src/public/tier0/P4PerformanceCounters.h
index 9af67afc..b52b6911 100644
--- a/sp/src/public/tier0/P4PerformanceCounters.h
+++ b/sp/src/public/tier0/P4PerformanceCounters.h
@@ -1,322 +1,322 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef P4PERFORMANCECOUNTERS_H
-#define P4PERFORMANCECOUNTERS_H
-
-#pragma once
-// Pentium 4 support
-
-/*
- http://developer.intel.com/design/Pentium4/documentation.htm
-
- IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture
-
- IA-32 Intel Architecture Software Developer's Manual Volume 2A: Instruction Set Reference, A-M
-
- IA-32 Intel Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z
-
- IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming Guide
-
-
- From Mikael Pettersson's perfctr:
-
- http://user.it.uu.se/~mikpe/linux/perfctr/
-
- * Known quirks:
- - OVF_PMI+FORCE_OVF counters must have an ireset value of -1.
- This allows the regular overflow check to also handle FORCE_OVF
- counters. Not having this restriction would lead to MAJOR
- complications in the driver's "detect overflow counters" code.
- There is no loss of functionality since the ireset value doesn't
- affect the counter's PMI rate for FORCE_OVF counters.
-
- - In experiments with FORCE_OVF counters, and regular OVF_PMI
- counters with small ireset values between -8 and -1, it appears
- that the faulting instruction is subjected to a new PMI before
- it can complete, ad infinitum. This occurs even though the driver
- clears the CCCR (and in testing also the ESCR) and invokes a
- user-space signal handler before restoring the CCCR and resuming
- the instruction.
-*/
-
-#define NCOUNTERS 18
-
-// The 18 counters
-enum Counters
-{
- MSR_BPU_COUNTER0,
- MSR_BPU_COUNTER1,
- MSR_BPU_COUNTER2,
- MSR_BPU_COUNTER3,
- MSR_MS_COUNTER0,
- MSR_MS_COUNTER1,
- MSR_MS_COUNTER2,
- MSR_MS_COUNTER3,
- MSR_FLAME_COUNTER0,
- MSR_FLAME_COUNTER1,
- MSR_FLAME_COUNTER2,
- MSR_FLAME_COUNTER3,
- MSR_IQ_COUNTER0,
- MSR_IQ_COUNTER1,
- MSR_IQ_COUNTER2,
- MSR_IQ_COUNTER3,
- MSR_IQ_COUNTER4,
- MSR_IQ_COUNTER5
-};
-
-// register base for counters
-#define MSR_COUNTER_BASE 0x300
-
-// register base for CCCR register
-#define MSR_CCCR_BASE 0x360
-
-#pragma pack(push, 1)
-// access to these bits is through the methods
-typedef union ESCR
-{
- struct
- {
- uint64 Reserved0_1 : 2; //
- uint64 USR : 1; //
- uint64 OS : 1; //
- uint64 TagEnable : 1; //
- uint64 TagValue : 4; //
- uint64 EventMask : 16; // from event select
- uint64 ESCREventSelect : 6; // 31:25 class of event
- uint64 Reserved31 : 1; //
-
- uint64 Reserved32_63 : 32; //
- };
- uint64 flat;
-
-} ESCR;
-
-typedef union CCCR
-{
- struct
- {
- uint64 Reserved0_11 : 12;// 0 -11
- uint64 Enable : 1; // 12
- uint64 CCCRSelect : 3; // 13-15
- uint64 Reserved16_17 : 2; // 16 17
-
- uint64 Compare : 1; // 18
- uint64 Complement : 1; // 19
- uint64 Threshold : 4; // 20-23
- uint64 Edge : 1; // 24
- uint64 FORCE_OVF : 1; // 25
- uint64 OVF_PMI : 1; // 26
- uint64 Reserved27_29 : 3; // 27-29
- uint64 Cascade : 1; // 30
- uint64 OVF : 1; // 31
-
- uint64 Reserved32_63 : 32; //
- };
- uint64 flat;
-
-} CCCR;
-
-#pragma pack(pop)
-
-extern const unsigned short cccr_escr_map[NCOUNTERS][8];
-
-enum P4TagState
-{
- TagDisable, //
- TagEnable, //
-};
-
-enum P4ForceOverflow
-{
- ForceOverflowDisable,
- ForceOverflowEnable,
-};
-
-enum P4OverflowInterrupt
-{
- OverflowInterruptDisable,
- OverflowInterruptEnable,
-};
-
-// Turn off the no return value warning in ReadCounter.
-#pragma warning( disable : 4035 )
-class P4BaseEvent
-{
- int m_counter;
-
-protected:
-
- void SetCounter(int counter)
- {
- m_counter = counter;
- cccrPort = MSR_CCCR_BASE + m_counter;
- counterPort = MSR_COUNTER_BASE + m_counter;
- escrPort = cccr_escr_map[m_counter][cccr.CCCRSelect];
- }
-
-public:
-
- unsigned short m_eventMask;
- const tchar *description;
- PME *pme;
- ESCR escr;
- CCCR cccr;
- int counterPort;
- int cccrPort;
- int escrPort;
-
- P4BaseEvent()
- {
- pme = PME::Instance();
- m_eventMask = 0;
- description = _T("");
- escr.flat = 0;
- cccr.flat = 0;
- cccr.Reserved16_17 = 3; // must be set
- escrPort = 0;
- m_counter = -1;
- }
-
- void StartCounter()
- {
- cccr.Enable = 1;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void StopCounter()
- {
- cccr.Enable = 0;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void ClearCounter()
- {
- pme->WriteMSR( counterPort, 0ui64 ); // clear
- }
-
- void WriteCounter( int64 value )
- {
- pme->WriteMSR( counterPort, value ); // clear
- }
-
- int64 ReadCounter()
- {
-#if PME_DEBUG
- if ( escr.USR == 0 && escr.OS == 0 )
- return -1; // no area to collect, use SetCaptureMode
-
- if ( escr.EventMask == 0 )
- return -2; // no event mask set
-
- if ( m_counter == -1 )
- return -3; // counter not legal
-#endif
-
- // ReadMSR should work here too, but RDPMC should be faster
- int64 value = 0;
- pme->ReadMSR( counterPort, &value );
- return value;
-#if 0
- // we need to copy this into a temp for some reason
- int temp = m_counter;
- _asm
- {
- mov ecx, temp
- RDPMC
- }
-#endif
- }
-
- void SetCaptureMode( PrivilegeCapture priv )
- {
- switch ( priv )
- {
- case OS_Only:
- {
- escr.USR = 0;
- escr.OS = 1;
- break;
- }
- case USR_Only:
- {
- escr.USR = 1;
- escr.OS = 0;
- break;
- }
- case OS_and_USR:
- {
- escr.USR = 1;
- escr.OS = 1;
- break;
- }
- }
-
- escr.EventMask = m_eventMask;
- pme->WriteMSR( escrPort, escr.flat );
- }
-
- void SetTagging( P4TagState tagEnable, uint8 tagValue )
- {
- escr.TagEnable = tagEnable;
- escr.TagValue = tagValue;
- pme->WriteMSR( escrPort, escr.flat );
- }
-
- void SetFiltering( CompareState compareEnable, CompareMethod compareMethod, uint8 threshold, EdgeState edgeEnable )
- {
- cccr.Compare = compareEnable;
- cccr.Complement = compareMethod;
- cccr.Threshold = threshold;
- cccr.Edge = edgeEnable;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void SetOverflowEnables( P4ForceOverflow overflowEnable, P4OverflowInterrupt overflowInterruptEnable )
- {
- cccr.FORCE_OVF = overflowEnable;
- cccr.OVF_PMI = overflowInterruptEnable;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void SetOverflow()
- {
- cccr.OVF = 1;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void ClearOverflow()
- {
- cccr.OVF = 0;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- bool isOverflow()
- {
- CCCR cccr_temp;
- pme->ReadMSR( cccrPort, &cccr_temp.flat );
- return cccr_temp.OVF;
- }
-
- void SetCascade()
- {
- cccr.Cascade = 1;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-
- void ClearCascade()
- {
- cccr.Cascade = 0;
- pme->WriteMSR( cccrPort, cccr.flat );
- }
-};
-#pragma warning( default : 4035 )
-
-#include "EventMasks.h"
-#include "EventModes.h"
-
-#endif // P4PERFORMANCECOUNTERS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef P4PERFORMANCECOUNTERS_H
+#define P4PERFORMANCECOUNTERS_H
+
+#pragma once
+// Pentium 4 support
+
+/*
+ http://developer.intel.com/design/Pentium4/documentation.htm
+
+ IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture
+
+ IA-32 Intel Architecture Software Developer's Manual Volume 2A: Instruction Set Reference, A-M
+
+ IA-32 Intel Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z
+
+ IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming Guide
+
+
+ From Mikael Pettersson's perfctr:
+
+ http://user.it.uu.se/~mikpe/linux/perfctr/
+
+ * Known quirks:
+ - OVF_PMI+FORCE_OVF counters must have an ireset value of -1.
+ This allows the regular overflow check to also handle FORCE_OVF
+ counters. Not having this restriction would lead to MAJOR
+ complications in the driver's "detect overflow counters" code.
+ There is no loss of functionality since the ireset value doesn't
+ affect the counter's PMI rate for FORCE_OVF counters.
+
+ - In experiments with FORCE_OVF counters, and regular OVF_PMI
+ counters with small ireset values between -8 and -1, it appears
+ that the faulting instruction is subjected to a new PMI before
+ it can complete, ad infinitum. This occurs even though the driver
+ clears the CCCR (and in testing also the ESCR) and invokes a
+ user-space signal handler before restoring the CCCR and resuming
+ the instruction.
+*/
+
+#define NCOUNTERS 18
+
+// The 18 counters
+enum Counters
+{
+ MSR_BPU_COUNTER0,
+ MSR_BPU_COUNTER1,
+ MSR_BPU_COUNTER2,
+ MSR_BPU_COUNTER3,
+ MSR_MS_COUNTER0,
+ MSR_MS_COUNTER1,
+ MSR_MS_COUNTER2,
+ MSR_MS_COUNTER3,
+ MSR_FLAME_COUNTER0,
+ MSR_FLAME_COUNTER1,
+ MSR_FLAME_COUNTER2,
+ MSR_FLAME_COUNTER3,
+ MSR_IQ_COUNTER0,
+ MSR_IQ_COUNTER1,
+ MSR_IQ_COUNTER2,
+ MSR_IQ_COUNTER3,
+ MSR_IQ_COUNTER4,
+ MSR_IQ_COUNTER5
+};
+
+// register base for counters
+#define MSR_COUNTER_BASE 0x300
+
+// register base for CCCR register
+#define MSR_CCCR_BASE 0x360
+
+#pragma pack(push, 1)
+// access to these bits is through the methods
+typedef union ESCR
+{
+ struct
+ {
+ uint64 Reserved0_1 : 2; //
+ uint64 USR : 1; //
+ uint64 OS : 1; //
+ uint64 TagEnable : 1; //
+ uint64 TagValue : 4; //
+ uint64 EventMask : 16; // from event select
+ uint64 ESCREventSelect : 6; // 31:25 class of event
+ uint64 Reserved31 : 1; //
+
+ uint64 Reserved32_63 : 32; //
+ };
+ uint64 flat;
+
+} ESCR;
+
+typedef union CCCR
+{
+ struct
+ {
+ uint64 Reserved0_11 : 12;// 0 -11
+ uint64 Enable : 1; // 12
+ uint64 CCCRSelect : 3; // 13-15
+ uint64 Reserved16_17 : 2; // 16 17
+
+ uint64 Compare : 1; // 18
+ uint64 Complement : 1; // 19
+ uint64 Threshold : 4; // 20-23
+ uint64 Edge : 1; // 24
+ uint64 FORCE_OVF : 1; // 25
+ uint64 OVF_PMI : 1; // 26
+ uint64 Reserved27_29 : 3; // 27-29
+ uint64 Cascade : 1; // 30
+ uint64 OVF : 1; // 31
+
+ uint64 Reserved32_63 : 32; //
+ };
+ uint64 flat;
+
+} CCCR;
+
+#pragma pack(pop)
+
+extern const unsigned short cccr_escr_map[NCOUNTERS][8];
+
+enum P4TagState
+{
+ TagDisable, //
+ TagEnable, //
+};
+
+enum P4ForceOverflow
+{
+ ForceOverflowDisable,
+ ForceOverflowEnable,
+};
+
+enum P4OverflowInterrupt
+{
+ OverflowInterruptDisable,
+ OverflowInterruptEnable,
+};
+
+// Turn off the no return value warning in ReadCounter.
+#pragma warning( disable : 4035 )
+class P4BaseEvent
+{
+ int m_counter;
+
+protected:
+
+ void SetCounter(int counter)
+ {
+ m_counter = counter;
+ cccrPort = MSR_CCCR_BASE + m_counter;
+ counterPort = MSR_COUNTER_BASE + m_counter;
+ escrPort = cccr_escr_map[m_counter][cccr.CCCRSelect];
+ }
+
+public:
+
+ unsigned short m_eventMask;
+ const tchar *description;
+ PME *pme;
+ ESCR escr;
+ CCCR cccr;
+ int counterPort;
+ int cccrPort;
+ int escrPort;
+
+ P4BaseEvent()
+ {
+ pme = PME::Instance();
+ m_eventMask = 0;
+ description = _T("");
+ escr.flat = 0;
+ cccr.flat = 0;
+ cccr.Reserved16_17 = 3; // must be set
+ escrPort = 0;
+ m_counter = -1;
+ }
+
+ void StartCounter()
+ {
+ cccr.Enable = 1;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void StopCounter()
+ {
+ cccr.Enable = 0;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void ClearCounter()
+ {
+ pme->WriteMSR( counterPort, 0ui64 ); // clear
+ }
+
+ void WriteCounter( int64 value )
+ {
+ pme->WriteMSR( counterPort, value ); // clear
+ }
+
+ int64 ReadCounter()
+ {
+#if PME_DEBUG
+ if ( escr.USR == 0 && escr.OS == 0 )
+ return -1; // no area to collect, use SetCaptureMode
+
+ if ( escr.EventMask == 0 )
+ return -2; // no event mask set
+
+ if ( m_counter == -1 )
+ return -3; // counter not legal
+#endif
+
+ // ReadMSR should work here too, but RDPMC should be faster
+ int64 value = 0;
+ pme->ReadMSR( counterPort, &value );
+ return value;
+#if 0
+ // we need to copy this into a temp for some reason
+ int temp = m_counter;
+ _asm
+ {
+ mov ecx, temp
+ RDPMC
+ }
+#endif
+ }
+
+ void SetCaptureMode( PrivilegeCapture priv )
+ {
+ switch ( priv )
+ {
+ case OS_Only:
+ {
+ escr.USR = 0;
+ escr.OS = 1;
+ break;
+ }
+ case USR_Only:
+ {
+ escr.USR = 1;
+ escr.OS = 0;
+ break;
+ }
+ case OS_and_USR:
+ {
+ escr.USR = 1;
+ escr.OS = 1;
+ break;
+ }
+ }
+
+ escr.EventMask = m_eventMask;
+ pme->WriteMSR( escrPort, escr.flat );
+ }
+
+ void SetTagging( P4TagState tagEnable, uint8 tagValue )
+ {
+ escr.TagEnable = tagEnable;
+ escr.TagValue = tagValue;
+ pme->WriteMSR( escrPort, escr.flat );
+ }
+
+ void SetFiltering( CompareState compareEnable, CompareMethod compareMethod, uint8 threshold, EdgeState edgeEnable )
+ {
+ cccr.Compare = compareEnable;
+ cccr.Complement = compareMethod;
+ cccr.Threshold = threshold;
+ cccr.Edge = edgeEnable;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void SetOverflowEnables( P4ForceOverflow overflowEnable, P4OverflowInterrupt overflowInterruptEnable )
+ {
+ cccr.FORCE_OVF = overflowEnable;
+ cccr.OVF_PMI = overflowInterruptEnable;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void SetOverflow()
+ {
+ cccr.OVF = 1;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void ClearOverflow()
+ {
+ cccr.OVF = 0;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ bool isOverflow()
+ {
+ CCCR cccr_temp;
+ pme->ReadMSR( cccrPort, &cccr_temp.flat );
+ return cccr_temp.OVF;
+ }
+
+ void SetCascade()
+ {
+ cccr.Cascade = 1;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+
+ void ClearCascade()
+ {
+ cccr.Cascade = 0;
+ pme->WriteMSR( cccrPort, cccr.flat );
+ }
+};
+#pragma warning( default : 4035 )
+
+#include "EventMasks.h"
+#include "EventModes.h"
+
+#endif // P4PERFORMANCECOUNTERS_H
diff --git a/sp/src/public/tier0/P5P6PerformanceCounters.h b/sp/src/public/tier0/P5P6PerformanceCounters.h
index 468d0bee..a7657567 100644
--- a/sp/src/public/tier0/P5P6PerformanceCounters.h
+++ b/sp/src/public/tier0/P5P6PerformanceCounters.h
@@ -1,225 +1,225 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef P5P6PERFORMANCECOUNTERS_H
-#define P5P6PERFORMANCECOUNTERS_H
-
-// defined for < Pentium 4
-
-//---------------------------------------------------------------------------
-// Format of the performance event IDs within this header file in case you
-// wish to add any additional events that may not be present here.
-//
-// BITS 0-8 Unit Mask, Unsed on P5 processors
-// BIT 9 Set if event can be set on counter 0
-// BIT 10 Set if event can be set on counter 1
-// BITS 11-15 Unused Set to zero
-// BITS 16-23 Event Select ID, Only bits 16-21 used on P5 Family
-// BITS 24-27 Unused set to zero
-// BITS 28-32 Process family that the event belong to, as returned by
-// the CPUID instruction.
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// PENTIUM PERFORMANCE COUNTERS.
-//---------------------------------------------------------------------------
-#define P5_DTCRD 0x50000300 //Data Cache Reads
-#define P5_DWRIT 0x50010300 //Data Cache Writes
-#define P5_DTTLB 0x50020300 //Data TLB Miss
-#define P5_DTRMS 0x50030300 //Data Read Misses
-#define P5_DWRMS 0x50040300 //Data Write Miss
-#define P5_WHLCL 0x50050300 //Write (Hit) to M- or E-state line
-#define P5_DCLWB 0x50060300 //Data Cache Lines Written Back
-#define P5_DCSNP 0x50070300 //External Snoops
-#define P5_DCSHT 0x50080300 //Data Cache Snoop Hits
-#define P5_MAIBP 0x50090300 //Memory Access in Both Pipes
-#define P5_BANKS 0x500A0300 //Bank Conflicts
-#define P5_MISAL 0x500B0300 //Misaligned Data Memory Reference
-#define P5_COCRD 0x500C0300 //Code Cache Reads
-#define P5_COTLB 0x500D0300 //Code TLB Misses
-#define P5_COCMS 0x500E0300 //Code Cache Misses
-#define P5_ANYSG 0x500F0300 //Any Segment Register Loaded
-#define P5_BRANC 0x50120300 //Branches
-#define P5_BTBHT 0x50130300 //BTB Hits
-#define P5_TBRAN 0x50140300 //Taken Branch or BTB hit
-#define P5_PFLSH 0x50150300 //Pipeline flushes
-#define P5_INSTR 0x50160300 //Instructions Executed
-#define P5_INSTV 0x50170300 //Instructions Executed in the V-Pipe (Pairing)
-#define P5_CLOCL 0x50180300 //Bus active
-#define P5_PSDWR 0x50190300 //Full write buffers
-#define P5_PSWDR 0x501A0300 //Waiting for Data Memory Read
-#define P5_NCLSW 0x501B0300 //Clocks stalled writing an E or M state line
-#define P5_IORWC 0x501D0300 //I/O Read or Write Cycle
-#define P5_NOCMR 0x501E0300 //Non-Cacheable Memory Reads
-#define P5_PSLDA 0x501F0300 //Clocks stalled due to AGI
-#define P5_FLOPS 0x50220300 //Floating Point Operations
-#define P5_DBGR0 0x50230300 //Breakpoint match on DR0
-#define P5_DBGR1 0x50240300 //Breakpoint match on DR1
-#define P5_DBGR2 0x50250300 //Breakpoint match on DR2
-#define P5_DBGR3 0x50260300 //Breakpoint match on DR3
-#define P5_HWINT 0x50270300 //Hardware interrupts
-#define P5_DTRWR 0x50280300 //Data reads or writes
-#define P5_DTRWM 0x50290300 //Data read or write miss
-#define P5_BOLAT 0x502A0100 //Bus ownership latency
-#define P5_BOTFR 0x502A0200 //Bus ownership transfer
-#define P5_MMXA1 0x502B0100 //MMX Instruction Executed in U-pipe
-#define P5_MMXA2 0x502B0200 //MMX Instruction Executed in V-pipe
-#define P5_MMXMS 0x502C0100 //Cache M state line sharing
-#define P5_MMSLS 0x502C0200 //Cache line sharing
-#define P5_MMXB1 0x502D0100 //EMMS Instructions Executed
-#define P5_MMXB2 0x502D0200 //Transition from MMX to FP instructions
-#define P5_NOCMW 0x502E0200 //Non-Cacheable Memory Writes
-#define P5_MMXC1 0x502F0100 //Saturated MMX Instructions Executed
-#define P5_MMXC2 0x502F0200 //Saturations Performed
-#define P5_MMXHS 0x50300100 //Cycles Not in HALT State
-#define P5_MMXD2 0x50310100 //MMX Data Read
-#define P5_MMXFP 0x50320100 //Floating Point Stalls
-#define P5_MMXTB 0x50320200 //Taken Branches
-#define P5_MMXD0 0x50330100 //D1 Starvation and FIFO Empty
-#define P5_MMXD1 0x50330200 //D1 Starvation and one instruction in FIFO
-#define P5_MMXE1 0x50340100 //MMX Data Writes
-#define P5_MMXE2 0x50340200 //MMX Data Write Misses
-#define P5_MMXWB 0x50350100 //Pipeline flushes, wrong branch prediction
-#define P5_MMXWJ 0x50350200 //Pipeline flushes, branch prediction WB-stage
-#define P5_MMXF1 0x50360100 //Misaligned MMX Data Memory Reference
-#define P5_MMXF2 0x50360200 //Pipeline Stalled Waiting for MMX data read
-#define P5_MMXRI 0x50370100 //Returns Predicted Incorrectly
-#define P5_MMXRP 0x50370200 //Returns Predicted
-#define P5_MMXG1 0x50380100 //MMX Multiply Unit Interlock
-#define P5_MMXG2 0x50380200 //MOVD/MOVQ store stall, previous operation
-#define P5_MMXRT 0x50390100 //Returns
-#define P5_MMXRO 0x50390200 //RSB Overflows
-#define P5_MMXBF 0x503A0100 //BTB False entries
-#define P5_MMXBM 0x503A0200 //BTB misprediction on a Not-Taken Branch
-#define P5_PXDWR 0x503B0100 //stalled due MMX Full write buffers
-#define P5_PXZWR 0x503B0200 //stalled on MMX write to E or M state line
-
-#define P5_CLOCK 0x503F0300 //Special value to count clocks on P5
-
-
-//---------------------------------------------------------------------------
-// PENTIUM PRO / PENTIUM II PERFORMANCE COUNTERS.
-//---------------------------------------------------------------------------
-#define P6_STRBB 0x60030300 //Store Buffer Block
-#define P6_STBDC 0x60040300 //Store Buffer Drain Cycles
-#define P6_MISMM 0x60050300 //Misaligned Data Memory Reference
-#define P6_SEGLD 0x60060300 //Segment register loads
-#define P6_FPOPE 0x60100100 //FP Computational Op. (COUNTER 0 ONLY)
-#define P6_FPEOA 0x60110200 //FP Microcode Exceptions (COUNTER 1 ONLY)
-#define P6_FMULT 0x60120200 //Multiplies (COUNTER 1 ONLY)
-#define P6_FPDIV 0x60130200 //Divides (COUNTER 1 ONLY)
-#define P6_DBUSY 0x60140200 //Cycles Divider Busy (COUNTER 1 ONLY)
-#define P6_L2STR 0x60210300 //L2 address strobes => address bus utilization
-#define P6_L2BBS 0x60220300 //Cycles L2 Bus Busy
-#define P6_L2BBT 0x60230300 //Cycles L2 Bus Busy transferring data to CPU
-#define P6_L2ALO 0x60240300 //L2 Lines Allocated
-#define P6_L2MAL 0x60250300 //L2 M-state Lines Allocated
-#define P6_L2CEV 0x60260300 //L2 Lines Evicted
-#define P6_L2MEV 0x60270300 //L2 M-state Lines Evicted
-#define P6_L2MCF 0x60280301 //L2 Cache Instruction Fetch Misses
-#define P6_L2FET 0x6028030F //L2 Cache Instruction Fetches
-#define P6_L2DRM 0x60290301 //L2 Cache Read Misses
-#define P6_L2DMR 0x6029030F //L2 Cache Reads
-#define P6_L2DWM 0x602A0301 //L2 Cache Write Misses
-#define P6_L2DMW 0x602A030F //L2 Cache Writes
-#define P6_L2CMS 0x602E0301 //L2 Cache Request Misses
-#define P6_L2DCR 0x602E030F //L2 Cache Requests
-#define P6_DMREF 0x60430300 //Data Memory References
-#define P6_DCALO 0x6045030F //L1 Lines Allocated
-#define P6_DCMAL 0x60460300 //L1 M-state Data Cache Lines Allocated
-#define P6_DCMEV 0x60470300 //L1 M-state Data Cache Lines Evicted
-#define P6_DCOUT 0x60480300 //L1 Misses outstanding
-#define P6_TSMCD 0x60520300 //Time Self-Modifiying Code Detected
-#define P6_BRWRA 0x60600300 //External Bus Cycles While Receive Active
-#define P6_BRDCD 0x60600300 //External Bus Request Outstanding
-#define P6_BRBNR 0x60610300 //External Bus Cycles While BNR Asserted
-#define P6_BUSBS 0x60620300 //External Bus Cycles-DRDY Asserted (busy)
-#define P6_BLOCK 0x60630300 //External Bus Cycles-LOCK signal asserted
-#define P6_BBRCV 0x60640300 //External Bus Cycles-Processor receiving data
-#define P6_BURST 0x60650300 //External Bus Burst Read Operations
-#define P6_BRINV 0x60660300 //External Bus Read for Ownership Transaction
-#define P6_BMLEV 0x60670300 //External Bus Writeback M-state Evicted
-#define P6_BBIFT 0x60680300 //External Bus Burst Instruction Fetches
-#define P6_BINVL 0x60690300 //External Bus Invalidate Transactions
-#define P6_BPRBT 0x606A0300 //External Bus Partial Read Transactions
-#define P6_BPTMO 0x606B0300 //External Bus Partial Memory Transactions
-#define P6_BUSIO 0x606C0300 //External Bus I/O Bus Transactions
-#define P6_BUSDF 0x606D0300 //External Bus Deferred Transactions
-#define P6_BUSTB 0x606E0300 //External Bus Burst Transactions
-#define P6_BMALL 0x606F0300 //External Bus Memory Transactions
-#define P6_BSALL 0x60700300 //External Bus Transactions
-#define P6_CLOCK 0x60790300 //Clockticks
-#define P6_BRHIT 0x607A0300 //External Bus Cycles While HIT Asserted
-#define P6_BRHTM 0x607B0300 //External Bus Cycles While HITM Asserted
-#define P6_BRSST 0x607E0300 //External Bus Cycles While Snoop Stalled
-#define P6_CMREF 0x60800300 //Total Instruction Fetches
-#define P6_TOIFM 0x60810300 //Total Instruction Fetch Misses
-#define P6_INTLB 0x60850300 //Instructions TLB Misses
-#define P6_CSFET 0x60860300 //Cycles Instruction Fetch Stalled
-#define P6_FTSTL 0x60870300 //Cycles Instruction Fetch stalled
-#define P6_RSTAL 0x60A20300 //Resource Related Stalls
-#define P6_MMXIE 0x60B00300 //MMX Instructions Executed
-#define P6_SAISE 0x60B10300 //Saturated Arithmetic Instructions Executed
-#define P6_PORT0 0x60B20301 //MMX micro-ops executed on Port 0
-#define P6_PORT1 0x60B20302 //MMX micro-ops executed on Port 1
-#define P6_PORT2 0x60B20304 //MMX micro-ops executed on Port 2
-#define P6_PORT3 0x60B20308 //MMX micro-ops executed on Port 3
-#define P6_MMXPA 0x60B30300 //MMX Packed Arithmetic
-#define P6_MMXPM 0x60B30301 //MMX Packed Multiply
-#define P6_MMXPS 0x60B30302 //MMX Packed Shift
-#define P6_MMXPO 0x60B30304 //MMX Packed Operations
-#define P6_MMXUO 0x60B30308 //MMX Unpacked Operations
-#define P6_MMXPL 0x60B30310 //MMX Packed Logical
-#define P6_INSTR 0x60C00300 //Instructions Retired
-#define P6_FPOPS 0x60C10100 //FP operations retired (COUNTER 0 ONLY)
-#define P6_UOPSR 0x60C20300 //Micro-Ops Retired
-#define P6_BRRET 0x60C40300 //Branch Instructions Retired
-#define P6_BRMSR 0x60C50300 //Branch Mispredictions Retired
-#define P6_MASKD 0x60C60300 //Clocks while interrupts masked
-#define P6_MSKPN 0x60C70300 //Clocks while interrupt is pending
-#define P6_HWINT 0x60C80300 //Hardware Interrupts Received
-#define P6_BTAKR 0x60C90300 //Taken Branch Retired
-#define P6_BTAKM 0x60CA0300 //Taken Branch Mispredictions
-#define P6_FPMMX 0x60CC0301 //Transitions from Floating Point to MMX
-#define P6_MMXFP 0x60CC0300 //Transitions from MMX to Floating Point
-#define P6_SIMDA 0x60CD0300 //SIMD Assists (EMMS Instructions Executed)
-#define P6_MMXIR 0x60CE0300 //MMX Instructions Retired
-#define P6_SAISR 0x60CF0300 //Saturated Arithmetic Instructions Retired
-#define P6_INSTD 0x60D00300 //Instructions Decoded
-#define P6_NPRTL 0x60D20300 //Renaming Stalls
-#define P6_SRSES 0x60D40301 //Segment Rename Stalls - ES
-#define P6_SRSDS 0x60D40302 //Segment Rename Stalls - DS
-#define P6_SRSFS 0x60D40304 //Segment Rename Stalls - FS
-#define P6_SRSGS 0x60D40308 //Segment Rename Stalls - GS
-#define P6_SRSXS 0x60D4030F //Segment Rename Stalls - ES DS FS GS
-#define P6_SRNES 0x60D50301 //Segment Renames - ES
-#define P6_SRNDS 0x60D50302 //Segment Renames - DS
-#define P6_SRNFS 0x60D50304 //Segment Renames - FS
-#define P6_SRNGS 0x60D50308 //Segment Renames - GS
-#define P6_SRNXS 0x60D5030F //Segment Renames - ES DS FS GS
-#define P6_BRDEC 0x60E00300 //Branch Instructions Decoded
-#define P6_BTBMS 0x60E20301 //BTB Misses
-#define P6_RETDC 0x60E40300 //Bogus Branches
-#define P6_BACLR 0x60E60300 //BACLEARS Asserted (Testing)
-
-
-
-
-
-
-// INTEL
-#define PENTIUM_FAMILY 5 // define for pentium
-#define PENTIUMPRO_FAMILY 6 // define for pentium pro
-#define PENTIUM4_FAMILY 15 // define for pentium 4
-
-
-// AMD
-#define K6_FAMILY 5
-#define K8_FAMILY 6
-#define EXTENDED_FAMILY 15 // AMD 64 and AMD Opteron
-
-#endif // P5P6PERFORMANCECOUNTERS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef P5P6PERFORMANCECOUNTERS_H
+#define P5P6PERFORMANCECOUNTERS_H
+
+// defined for < Pentium 4
+
+//---------------------------------------------------------------------------
+// Format of the performance event IDs within this header file in case you
+// wish to add any additional events that may not be present here.
+//
+// BITS 0-8 Unit Mask, Unsed on P5 processors
+// BIT 9 Set if event can be set on counter 0
+// BIT 10 Set if event can be set on counter 1
+// BITS 11-15 Unused Set to zero
+// BITS 16-23 Event Select ID, Only bits 16-21 used on P5 Family
+// BITS 24-27 Unused set to zero
+// BITS 28-32 Process family that the event belong to, as returned by
+// the CPUID instruction.
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// PENTIUM PERFORMANCE COUNTERS.
+//---------------------------------------------------------------------------
+#define P5_DTCRD 0x50000300 //Data Cache Reads
+#define P5_DWRIT 0x50010300 //Data Cache Writes
+#define P5_DTTLB 0x50020300 //Data TLB Miss
+#define P5_DTRMS 0x50030300 //Data Read Misses
+#define P5_DWRMS 0x50040300 //Data Write Miss
+#define P5_WHLCL 0x50050300 //Write (Hit) to M- or E-state line
+#define P5_DCLWB 0x50060300 //Data Cache Lines Written Back
+#define P5_DCSNP 0x50070300 //External Snoops
+#define P5_DCSHT 0x50080300 //Data Cache Snoop Hits
+#define P5_MAIBP 0x50090300 //Memory Access in Both Pipes
+#define P5_BANKS 0x500A0300 //Bank Conflicts
+#define P5_MISAL 0x500B0300 //Misaligned Data Memory Reference
+#define P5_COCRD 0x500C0300 //Code Cache Reads
+#define P5_COTLB 0x500D0300 //Code TLB Misses
+#define P5_COCMS 0x500E0300 //Code Cache Misses
+#define P5_ANYSG 0x500F0300 //Any Segment Register Loaded
+#define P5_BRANC 0x50120300 //Branches
+#define P5_BTBHT 0x50130300 //BTB Hits
+#define P5_TBRAN 0x50140300 //Taken Branch or BTB hit
+#define P5_PFLSH 0x50150300 //Pipeline flushes
+#define P5_INSTR 0x50160300 //Instructions Executed
+#define P5_INSTV 0x50170300 //Instructions Executed in the V-Pipe (Pairing)
+#define P5_CLOCL 0x50180300 //Bus active
+#define P5_PSDWR 0x50190300 //Full write buffers
+#define P5_PSWDR 0x501A0300 //Waiting for Data Memory Read
+#define P5_NCLSW 0x501B0300 //Clocks stalled writing an E or M state line
+#define P5_IORWC 0x501D0300 //I/O Read or Write Cycle
+#define P5_NOCMR 0x501E0300 //Non-Cacheable Memory Reads
+#define P5_PSLDA 0x501F0300 //Clocks stalled due to AGI
+#define P5_FLOPS 0x50220300 //Floating Point Operations
+#define P5_DBGR0 0x50230300 //Breakpoint match on DR0
+#define P5_DBGR1 0x50240300 //Breakpoint match on DR1
+#define P5_DBGR2 0x50250300 //Breakpoint match on DR2
+#define P5_DBGR3 0x50260300 //Breakpoint match on DR3
+#define P5_HWINT 0x50270300 //Hardware interrupts
+#define P5_DTRWR 0x50280300 //Data reads or writes
+#define P5_DTRWM 0x50290300 //Data read or write miss
+#define P5_BOLAT 0x502A0100 //Bus ownership latency
+#define P5_BOTFR 0x502A0200 //Bus ownership transfer
+#define P5_MMXA1 0x502B0100 //MMX Instruction Executed in U-pipe
+#define P5_MMXA2 0x502B0200 //MMX Instruction Executed in V-pipe
+#define P5_MMXMS 0x502C0100 //Cache M state line sharing
+#define P5_MMSLS 0x502C0200 //Cache line sharing
+#define P5_MMXB1 0x502D0100 //EMMS Instructions Executed
+#define P5_MMXB2 0x502D0200 //Transition from MMX to FP instructions
+#define P5_NOCMW 0x502E0200 //Non-Cacheable Memory Writes
+#define P5_MMXC1 0x502F0100 //Saturated MMX Instructions Executed
+#define P5_MMXC2 0x502F0200 //Saturations Performed
+#define P5_MMXHS 0x50300100 //Cycles Not in HALT State
+#define P5_MMXD2 0x50310100 //MMX Data Read
+#define P5_MMXFP 0x50320100 //Floating Point Stalls
+#define P5_MMXTB 0x50320200 //Taken Branches
+#define P5_MMXD0 0x50330100 //D1 Starvation and FIFO Empty
+#define P5_MMXD1 0x50330200 //D1 Starvation and one instruction in FIFO
+#define P5_MMXE1 0x50340100 //MMX Data Writes
+#define P5_MMXE2 0x50340200 //MMX Data Write Misses
+#define P5_MMXWB 0x50350100 //Pipeline flushes, wrong branch prediction
+#define P5_MMXWJ 0x50350200 //Pipeline flushes, branch prediction WB-stage
+#define P5_MMXF1 0x50360100 //Misaligned MMX Data Memory Reference
+#define P5_MMXF2 0x50360200 //Pipeline Stalled Waiting for MMX data read
+#define P5_MMXRI 0x50370100 //Returns Predicted Incorrectly
+#define P5_MMXRP 0x50370200 //Returns Predicted
+#define P5_MMXG1 0x50380100 //MMX Multiply Unit Interlock
+#define P5_MMXG2 0x50380200 //MOVD/MOVQ store stall, previous operation
+#define P5_MMXRT 0x50390100 //Returns
+#define P5_MMXRO 0x50390200 //RSB Overflows
+#define P5_MMXBF 0x503A0100 //BTB False entries
+#define P5_MMXBM 0x503A0200 //BTB misprediction on a Not-Taken Branch
+#define P5_PXDWR 0x503B0100 //stalled due MMX Full write buffers
+#define P5_PXZWR 0x503B0200 //stalled on MMX write to E or M state line
+
+#define P5_CLOCK 0x503F0300 //Special value to count clocks on P5
+
+
+//---------------------------------------------------------------------------
+// PENTIUM PRO / PENTIUM II PERFORMANCE COUNTERS.
+//---------------------------------------------------------------------------
+#define P6_STRBB 0x60030300 //Store Buffer Block
+#define P6_STBDC 0x60040300 //Store Buffer Drain Cycles
+#define P6_MISMM 0x60050300 //Misaligned Data Memory Reference
+#define P6_SEGLD 0x60060300 //Segment register loads
+#define P6_FPOPE 0x60100100 //FP Computational Op. (COUNTER 0 ONLY)
+#define P6_FPEOA 0x60110200 //FP Microcode Exceptions (COUNTER 1 ONLY)
+#define P6_FMULT 0x60120200 //Multiplies (COUNTER 1 ONLY)
+#define P6_FPDIV 0x60130200 //Divides (COUNTER 1 ONLY)
+#define P6_DBUSY 0x60140200 //Cycles Divider Busy (COUNTER 1 ONLY)
+#define P6_L2STR 0x60210300 //L2 address strobes => address bus utilization
+#define P6_L2BBS 0x60220300 //Cycles L2 Bus Busy
+#define P6_L2BBT 0x60230300 //Cycles L2 Bus Busy transferring data to CPU
+#define P6_L2ALO 0x60240300 //L2 Lines Allocated
+#define P6_L2MAL 0x60250300 //L2 M-state Lines Allocated
+#define P6_L2CEV 0x60260300 //L2 Lines Evicted
+#define P6_L2MEV 0x60270300 //L2 M-state Lines Evicted
+#define P6_L2MCF 0x60280301 //L2 Cache Instruction Fetch Misses
+#define P6_L2FET 0x6028030F //L2 Cache Instruction Fetches
+#define P6_L2DRM 0x60290301 //L2 Cache Read Misses
+#define P6_L2DMR 0x6029030F //L2 Cache Reads
+#define P6_L2DWM 0x602A0301 //L2 Cache Write Misses
+#define P6_L2DMW 0x602A030F //L2 Cache Writes
+#define P6_L2CMS 0x602E0301 //L2 Cache Request Misses
+#define P6_L2DCR 0x602E030F //L2 Cache Requests
+#define P6_DMREF 0x60430300 //Data Memory References
+#define P6_DCALO 0x6045030F //L1 Lines Allocated
+#define P6_DCMAL 0x60460300 //L1 M-state Data Cache Lines Allocated
+#define P6_DCMEV 0x60470300 //L1 M-state Data Cache Lines Evicted
+#define P6_DCOUT 0x60480300 //L1 Misses outstanding
+#define P6_TSMCD 0x60520300 //Time Self-Modifiying Code Detected
+#define P6_BRWRA 0x60600300 //External Bus Cycles While Receive Active
+#define P6_BRDCD 0x60600300 //External Bus Request Outstanding
+#define P6_BRBNR 0x60610300 //External Bus Cycles While BNR Asserted
+#define P6_BUSBS 0x60620300 //External Bus Cycles-DRDY Asserted (busy)
+#define P6_BLOCK 0x60630300 //External Bus Cycles-LOCK signal asserted
+#define P6_BBRCV 0x60640300 //External Bus Cycles-Processor receiving data
+#define P6_BURST 0x60650300 //External Bus Burst Read Operations
+#define P6_BRINV 0x60660300 //External Bus Read for Ownership Transaction
+#define P6_BMLEV 0x60670300 //External Bus Writeback M-state Evicted
+#define P6_BBIFT 0x60680300 //External Bus Burst Instruction Fetches
+#define P6_BINVL 0x60690300 //External Bus Invalidate Transactions
+#define P6_BPRBT 0x606A0300 //External Bus Partial Read Transactions
+#define P6_BPTMO 0x606B0300 //External Bus Partial Memory Transactions
+#define P6_BUSIO 0x606C0300 //External Bus I/O Bus Transactions
+#define P6_BUSDF 0x606D0300 //External Bus Deferred Transactions
+#define P6_BUSTB 0x606E0300 //External Bus Burst Transactions
+#define P6_BMALL 0x606F0300 //External Bus Memory Transactions
+#define P6_BSALL 0x60700300 //External Bus Transactions
+#define P6_CLOCK 0x60790300 //Clockticks
+#define P6_BRHIT 0x607A0300 //External Bus Cycles While HIT Asserted
+#define P6_BRHTM 0x607B0300 //External Bus Cycles While HITM Asserted
+#define P6_BRSST 0x607E0300 //External Bus Cycles While Snoop Stalled
+#define P6_CMREF 0x60800300 //Total Instruction Fetches
+#define P6_TOIFM 0x60810300 //Total Instruction Fetch Misses
+#define P6_INTLB 0x60850300 //Instructions TLB Misses
+#define P6_CSFET 0x60860300 //Cycles Instruction Fetch Stalled
+#define P6_FTSTL 0x60870300 //Cycles Instruction Fetch stalled
+#define P6_RSTAL 0x60A20300 //Resource Related Stalls
+#define P6_MMXIE 0x60B00300 //MMX Instructions Executed
+#define P6_SAISE 0x60B10300 //Saturated Arithmetic Instructions Executed
+#define P6_PORT0 0x60B20301 //MMX micro-ops executed on Port 0
+#define P6_PORT1 0x60B20302 //MMX micro-ops executed on Port 1
+#define P6_PORT2 0x60B20304 //MMX micro-ops executed on Port 2
+#define P6_PORT3 0x60B20308 //MMX micro-ops executed on Port 3
+#define P6_MMXPA 0x60B30300 //MMX Packed Arithmetic
+#define P6_MMXPM 0x60B30301 //MMX Packed Multiply
+#define P6_MMXPS 0x60B30302 //MMX Packed Shift
+#define P6_MMXPO 0x60B30304 //MMX Packed Operations
+#define P6_MMXUO 0x60B30308 //MMX Unpacked Operations
+#define P6_MMXPL 0x60B30310 //MMX Packed Logical
+#define P6_INSTR 0x60C00300 //Instructions Retired
+#define P6_FPOPS 0x60C10100 //FP operations retired (COUNTER 0 ONLY)
+#define P6_UOPSR 0x60C20300 //Micro-Ops Retired
+#define P6_BRRET 0x60C40300 //Branch Instructions Retired
+#define P6_BRMSR 0x60C50300 //Branch Mispredictions Retired
+#define P6_MASKD 0x60C60300 //Clocks while interrupts masked
+#define P6_MSKPN 0x60C70300 //Clocks while interrupt is pending
+#define P6_HWINT 0x60C80300 //Hardware Interrupts Received
+#define P6_BTAKR 0x60C90300 //Taken Branch Retired
+#define P6_BTAKM 0x60CA0300 //Taken Branch Mispredictions
+#define P6_FPMMX 0x60CC0301 //Transitions from Floating Point to MMX
+#define P6_MMXFP 0x60CC0300 //Transitions from MMX to Floating Point
+#define P6_SIMDA 0x60CD0300 //SIMD Assists (EMMS Instructions Executed)
+#define P6_MMXIR 0x60CE0300 //MMX Instructions Retired
+#define P6_SAISR 0x60CF0300 //Saturated Arithmetic Instructions Retired
+#define P6_INSTD 0x60D00300 //Instructions Decoded
+#define P6_NPRTL 0x60D20300 //Renaming Stalls
+#define P6_SRSES 0x60D40301 //Segment Rename Stalls - ES
+#define P6_SRSDS 0x60D40302 //Segment Rename Stalls - DS
+#define P6_SRSFS 0x60D40304 //Segment Rename Stalls - FS
+#define P6_SRSGS 0x60D40308 //Segment Rename Stalls - GS
+#define P6_SRSXS 0x60D4030F //Segment Rename Stalls - ES DS FS GS
+#define P6_SRNES 0x60D50301 //Segment Renames - ES
+#define P6_SRNDS 0x60D50302 //Segment Renames - DS
+#define P6_SRNFS 0x60D50304 //Segment Renames - FS
+#define P6_SRNGS 0x60D50308 //Segment Renames - GS
+#define P6_SRNXS 0x60D5030F //Segment Renames - ES DS FS GS
+#define P6_BRDEC 0x60E00300 //Branch Instructions Decoded
+#define P6_BTBMS 0x60E20301 //BTB Misses
+#define P6_RETDC 0x60E40300 //Bogus Branches
+#define P6_BACLR 0x60E60300 //BACLEARS Asserted (Testing)
+
+
+
+
+
+
+// INTEL
+#define PENTIUM_FAMILY 5 // define for pentium
+#define PENTIUMPRO_FAMILY 6 // define for pentium pro
+#define PENTIUM4_FAMILY 15 // define for pentium 4
+
+
+// AMD
+#define K6_FAMILY 5
+#define K8_FAMILY 6
+#define EXTENDED_FAMILY 15 // AMD 64 and AMD Opteron
+
+#endif // P5P6PERFORMANCECOUNTERS_H
diff --git a/sp/src/public/tier0/PMELib.h b/sp/src/public/tier0/PMELib.h
index 2ad59145..5eeb63cf 100644
--- a/sp/src/public/tier0/PMELib.h
+++ b/sp/src/public/tier0/PMELib.h
@@ -1,192 +1,192 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef PMELIB_H
-#define PMELIB_H
-
-#include "Windows.h"
-#include "tier0/platform.h"
-
-// Get rid of a bunch of STL warnings!
-#pragma warning( push, 3 )
-#pragma warning( disable : 4018 )
-
-#define VERSION "1.0.2"
-
-// uncomment this list to add some runtime checks
-//#define PME_DEBUG
-
-#include "tier0/valve_off.h"
-#include <string>
-#include "tier0/valve_on.h"
-
-using namespace std;
-
-// RDTSC Instruction macro
-#define RDTSC(var) var = __rdtsc()
-
-// RDPMC Instruction macro
-#define RDPMC(counter, var) \
-_asm mov ecx, counter \
-_asm RDPMC \
-_asm mov DWORD PTR var,eax \
-_asm mov DWORD PTR var+4,edx
-
-// RDPMC Instruction macro, for performance counter 1 (ecx = 1)
-#define RDPMC0(var) \
-_asm mov ecx, 0 \
-_asm RDPMC \
-_asm mov DWORD PTR var,eax \
-_asm mov DWORD PTR var+4,edx
-
-#define RDPMC1(var) \
-_asm mov ecx, 1 \
-_asm RDPMC \
-_asm mov DWORD PTR var,eax \
-_asm mov DWORD PTR var+4,edx
-
-#define EVENT_TYPE(mode) EventType##mode
-#define EVENT_MASK(mode) EventMask##mode
-
-#include "ia32detect.h"
-
-enum ProcessPriority
-{
- ProcessPriorityNormal,
- ProcessPriorityHigh,
-};
-
-enum PrivilegeCapture
-{
- OS_Only, // ring 0, kernel level
- USR_Only, // app level
- OS_and_USR, // all levels
-};
-
-enum CompareMethod
-{
- CompareGreater, //
- CompareLessEqual, //
-};
-
-enum EdgeState
-{
- RisingEdgeDisabled, //
- RisingEdgeEnabled, //
-};
-
-enum CompareState
-{
- CompareDisable, //
- CompareEnable, //
-};
-
-// Singletion Class
-class PME : public ia32detect
-{
-public:
-//private:
-
- static PME* _singleton;
-
- HANDLE hFile;
- bool bDriverOpen;
- double m_CPUClockSpeed;
-
- //ia32detect detect;
- HRESULT Init();
- HRESULT Close();
-
-protected:
-
- PME()
- {
- hFile = NULL;
- bDriverOpen = FALSE;
- m_CPUClockSpeed = 0;
- Init();
- }
-
-public:
-
- static PME* Instance(); // gives back a real object
-
- ~PME()
- {
- Close();
- }
-
- double GetCPUClockSpeedSlow( void );
- double GetCPUClockSpeedFast( void );
-
- HRESULT SelectP5P6PerformanceEvent( uint32 dw_event, uint32 dw_counter, bool b_user, bool b_kernel );
-
- HRESULT ReadMSR( uint32 dw_reg, int64 * pi64_value );
- HRESULT ReadMSR( uint32 dw_reg, uint64 * pi64_value );
-
- HRESULT WriteMSR( uint32 dw_reg, const int64 & i64_value );
- HRESULT WriteMSR( uint32 dw_reg, const uint64 & i64_value );
-
- void SetProcessPriority( ProcessPriority priority )
- {
- switch( priority )
- {
- case ProcessPriorityNormal:
- {
- SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
- SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_NORMAL);
- break;
- }
- case ProcessPriorityHigh:
- {
- SetPriorityClass (GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
- SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
- break;
- }
- }
- }
-
- //---------------------------------------------------------------------------
- // Return the family of the processor
- //---------------------------------------------------------------------------
- CPUVendor GetVendor(void)
- {
- return vendor;
- }
-
- int GetProcessorFamily(void)
- {
- return version.Family;
- }
-
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-#endif // DBGFLAG_VALIDATE
-
-};
-
-#include "P5P6PerformanceCounters.h"
-#include "P4PerformanceCounters.h"
-#include "K8PerformanceCounters.h"
-
-enum PerfErrors
-{
- E_UNKNOWN_CPU_VENDOR = -1,
- E_BAD_COUNTER = -2,
- E_UNKNOWN_CPU = -3,
- E_CANT_OPEN_DRIVER = -4,
- E_DRIVER_ALREADY_OPEN = -5,
- E_DRIVER_NOT_OPEN = -6,
- E_DISABLED = -7,
- E_BAD_DATA = -8,
- E_CANT_CLOSE = -9,
- E_ILLEGAL_OPERATION = -10,
-};
-
-#pragma warning( pop )
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef PMELIB_H
+#define PMELIB_H
+
+#include "Windows.h"
+#include "tier0/platform.h"
+
+// Get rid of a bunch of STL warnings!
+#pragma warning( push, 3 )
+#pragma warning( disable : 4018 )
+
+#define VERSION "1.0.2"
+
+// uncomment this list to add some runtime checks
+//#define PME_DEBUG
+
+#include "tier0/valve_off.h"
+#include <string>
+#include "tier0/valve_on.h"
+
+using namespace std;
+
+// RDTSC Instruction macro
+#define RDTSC(var) var = __rdtsc()
+
+// RDPMC Instruction macro
+#define RDPMC(counter, var) \
+_asm mov ecx, counter \
+_asm RDPMC \
+_asm mov DWORD PTR var,eax \
+_asm mov DWORD PTR var+4,edx
+
+// RDPMC Instruction macro, for performance counter 1 (ecx = 1)
+#define RDPMC0(var) \
+_asm mov ecx, 0 \
+_asm RDPMC \
+_asm mov DWORD PTR var,eax \
+_asm mov DWORD PTR var+4,edx
+
+#define RDPMC1(var) \
+_asm mov ecx, 1 \
+_asm RDPMC \
+_asm mov DWORD PTR var,eax \
+_asm mov DWORD PTR var+4,edx
+
+#define EVENT_TYPE(mode) EventType##mode
+#define EVENT_MASK(mode) EventMask##mode
+
+#include "ia32detect.h"
+
+enum ProcessPriority
+{
+ ProcessPriorityNormal,
+ ProcessPriorityHigh,
+};
+
+enum PrivilegeCapture
+{
+ OS_Only, // ring 0, kernel level
+ USR_Only, // app level
+ OS_and_USR, // all levels
+};
+
+enum CompareMethod
+{
+ CompareGreater, //
+ CompareLessEqual, //
+};
+
+enum EdgeState
+{
+ RisingEdgeDisabled, //
+ RisingEdgeEnabled, //
+};
+
+enum CompareState
+{
+ CompareDisable, //
+ CompareEnable, //
+};
+
+// Singletion Class
+class PME : public ia32detect
+{
+public:
+//private:
+
+ static PME* _singleton;
+
+ HANDLE hFile;
+ bool bDriverOpen;
+ double m_CPUClockSpeed;
+
+ //ia32detect detect;
+ HRESULT Init();
+ HRESULT Close();
+
+protected:
+
+ PME()
+ {
+ hFile = NULL;
+ bDriverOpen = FALSE;
+ m_CPUClockSpeed = 0;
+ Init();
+ }
+
+public:
+
+ static PME* Instance(); // gives back a real object
+
+ ~PME()
+ {
+ Close();
+ }
+
+ double GetCPUClockSpeedSlow( void );
+ double GetCPUClockSpeedFast( void );
+
+ HRESULT SelectP5P6PerformanceEvent( uint32 dw_event, uint32 dw_counter, bool b_user, bool b_kernel );
+
+ HRESULT ReadMSR( uint32 dw_reg, int64 * pi64_value );
+ HRESULT ReadMSR( uint32 dw_reg, uint64 * pi64_value );
+
+ HRESULT WriteMSR( uint32 dw_reg, const int64 & i64_value );
+ HRESULT WriteMSR( uint32 dw_reg, const uint64 & i64_value );
+
+ void SetProcessPriority( ProcessPriority priority )
+ {
+ switch( priority )
+ {
+ case ProcessPriorityNormal:
+ {
+ SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
+ SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_NORMAL);
+ break;
+ }
+ case ProcessPriorityHigh:
+ {
+ SetPriorityClass (GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
+ SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
+ break;
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------
+ // Return the family of the processor
+ //---------------------------------------------------------------------------
+ CPUVendor GetVendor(void)
+ {
+ return vendor;
+ }
+
+ int GetProcessorFamily(void)
+ {
+ return version.Family;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+#endif // DBGFLAG_VALIDATE
+
+};
+
+#include "P5P6PerformanceCounters.h"
+#include "P4PerformanceCounters.h"
+#include "K8PerformanceCounters.h"
+
+enum PerfErrors
+{
+ E_UNKNOWN_CPU_VENDOR = -1,
+ E_BAD_COUNTER = -2,
+ E_UNKNOWN_CPU = -3,
+ E_CANT_OPEN_DRIVER = -4,
+ E_DRIVER_ALREADY_OPEN = -5,
+ E_DRIVER_NOT_OPEN = -6,
+ E_DISABLED = -7,
+ E_BAD_DATA = -8,
+ E_CANT_CLOSE = -9,
+ E_ILLEGAL_OPERATION = -10,
+};
+
+#pragma warning( pop )
+
#endif // PMELIB_H \ No newline at end of file
diff --git a/sp/src/public/tier0/afxmem_override.cpp b/sp/src/public/tier0/afxmem_override.cpp
index e9a8c3cc..425cabd8 100644
--- a/sp/src/public/tier0/afxmem_override.cpp
+++ b/sp/src/public/tier0/afxmem_override.cpp
@@ -1,460 +1,460 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-// File extracted from MFC due to symbol conflicts
-
-// This is a part of the Microsoft Foundation Classes C++ library.
-// Copyright (C) Microsoft Corporation
-// All rights reserved.
-//
-// This source code is only intended as a supplement to the
-// Microsoft Foundation Classes Reference and related
-// electronic documentation provided with the library.
-// See these sources for detailed information regarding the
-// Microsoft Foundation Classes product.
-
-#include "stdafx.h"
-
-#ifdef AFX_CORE1_SEG
-#pragma code_seg(AFX_CORE1_SEG)
-#endif
-
-
-/////////////////////////////////////////////////////////////////////////////
-// Debug memory globals and implementation helpers
-
-#ifdef _DEBUG // most of this file is for debugging
-
-void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine);
-#if _MSC_VER >= 1210
-void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine);
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-// test allocation routines
-
-void* PASCAL CObject::operator new(size_t nSize)
-{
-#ifdef _AFX_NO_DEBUG_CRT
- return ::operator new(nSize);
-#else
- return ::operator new(nSize, _AFX_CLIENT_BLOCK, NULL, 0);
-#endif // _AFX_NO_DEBUG_CRT
-}
-
-void PASCAL CObject::operator delete(void* p)
-{
-#ifdef _AFX_NO_DEBUG_CRT
- free(p);
-#else
- _free_dbg(p, _AFX_CLIENT_BLOCK);
-#endif
-}
-
-#if _MSC_VER >= 1200
-void PASCAL CObject::operator delete(void* p, void*)
-{
-#ifdef _AFX_NO_DEBUG_CRT
- free(p);
-#else
- _free_dbg(p, _AFX_CLIENT_BLOCK);
-#endif
-}
-#endif
-
-#ifndef _AFX_NO_DEBUG_CRT
-
-void* __cdecl operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
-{
- return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
-}
-
-#if _MSC_VER >= 1210
-void* __cdecl operator new[](size_t nSize, LPCSTR lpszFileName, int nLine)
-{
- return ::operator new[](nSize, _NORMAL_BLOCK, lpszFileName, nLine);
-}
-#endif
-
-#if _MSC_VER >= 1200
-void __cdecl operator delete(void* pData, LPCSTR /* lpszFileName */,
- int /* nLine */)
-{
- ::operator delete(pData);
-}
-#endif
-
-#if _MSC_VER >= 1210
-void __cdecl operator delete[](void* pData, LPCSTR /* lpszFileName */,
- int /* nLine */)
-{
- ::operator delete(pData);
-}
-#endif
-
-void* PASCAL
-CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
-{
- return ::operator new(nSize, _AFX_CLIENT_BLOCK, lpszFileName, nLine);
-}
-
-#if _MSC_VER >= 1200
-void PASCAL
-CObject::operator delete(void *pObject, LPCSTR /* lpszFileName */,
- int /* nLine */)
-{
-#ifdef _AFX_NO_DEBUG_CRT
- free(pObject);
-#else
- _free_dbg(pObject, _AFX_CLIENT_BLOCK);
-#endif
-}
-#endif
-
-void* AFXAPI AfxAllocMemoryDebug(size_t nSize, BOOL bIsObject, LPCSTR lpszFileName, int nLine)
-{
- return _malloc_dbg(nSize, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK,
- lpszFileName, nLine);
-}
-
-void AFXAPI AfxFreeMemoryDebug(void* pbData, BOOL bIsObject)
-{
- _free_dbg(pbData, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// allocation failure hook, tracking turn on
-
-BOOL AFXAPI _AfxDefaultAllocHook(size_t, BOOL, LONG)
- { return TRUE; }
-
-AFX_STATIC_DATA AFX_ALLOC_HOOK pfnAllocHook = _AfxDefaultAllocHook;
-
-AFX_STATIC_DATA _CRT_ALLOC_HOOK pfnCrtAllocHook = NULL;
-#if _MSC_VER >= 1200
-int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize,
- int nBlockUse, long lRequest, const unsigned char * szFilename, int nLine)
-#else
-int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize,
- int nBlockUse, long lRequest, const char * szFilename, int nLine)
-#endif
-{
-#if _MSC_VER >= 1200
- if (nAllocType != _HOOK_ALLOC)
- return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
- nBlockUse, lRequest, (const unsigned char*) szFilename, nLine);
- if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest))
- return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
- nBlockUse, lRequest, (const unsigned char*) szFilename, nLine);
-#else
- if (nAllocType != _HOOK_ALLOC)
- return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
- nBlockUse, lRequest, szFilename, nLine);
- if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest))
- return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
- nBlockUse, lRequest, szFilename, nLine);
-#endif
- return FALSE;
-}
-
-AFX_ALLOC_HOOK AFXAPI AfxSetAllocHook(AFX_ALLOC_HOOK pfnNewHook)
-{
- if (pfnCrtAllocHook == NULL)
- pfnCrtAllocHook = _CrtSetAllocHook(_AfxAllocHookProxy);
-
- AFX_ALLOC_HOOK pfnOldHook = pfnAllocHook;
- pfnAllocHook = pfnNewHook;
- return pfnOldHook;
-}
-
-// This can be set to TRUE to override all AfxEnableMemoryTracking calls,
-// allowing all allocations, even MFC internal allocations to be tracked.
-BOOL _afxMemoryLeakOverride = FALSE;
-
-BOOL AFXAPI AfxEnableMemoryTracking(BOOL bTrack)
-{
- if (_afxMemoryLeakOverride)
- return TRUE;
-
- int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
- if (bTrack)
- _CrtSetDbgFlag(nOldState | _CRTDBG_ALLOC_MEM_DF);
- else
- _CrtSetDbgFlag(nOldState & ~_CRTDBG_ALLOC_MEM_DF);
- return nOldState & _CRTDBG_ALLOC_MEM_DF;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// stop on a specific memory request
-
-// Obsolete API
-void AFXAPI AfxSetAllocStop(LONG lRequestNumber)
-{
- _CrtSetBreakAlloc(lRequestNumber);
-}
-
-BOOL AFXAPI AfxCheckMemory()
- // check all of memory (look for memory tromps)
-{
- return _CrtCheckMemory();
-}
-
-// -- true if block of exact size, allocated on the heap
-// -- set *plRequestNumber to request number (or 0)
-BOOL AFXAPI AfxIsMemoryBlock(const void* pData, UINT nBytes,
- LONG* plRequestNumber)
-{
- return _CrtIsMemoryBlock(pData, nBytes, plRequestNumber, NULL, NULL);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// CMemoryState
-
-CMemoryState::CMemoryState()
-{
- memset(this, 0, sizeof(*this));
-}
-
-void CMemoryState::UpdateData()
-{
- for(int i = 0; i < nBlockUseMax; i++)
- {
- m_lCounts[i] = m_memState.lCounts[i];
- m_lSizes[i] = m_memState.lSizes[i];
- }
- m_lHighWaterCount = m_memState.lHighWaterCount;
- m_lTotalCount = m_memState.lTotalCount;
-}
-
-// fills 'this' with the difference, returns TRUE if significant
-BOOL CMemoryState::Difference(const CMemoryState& oldState,
- const CMemoryState& newState)
-{
- int nResult = _CrtMemDifference(&m_memState, &oldState.m_memState, &newState.m_memState);
- UpdateData();
- return nResult != 0;
-}
-
-void CMemoryState::DumpStatistics() const
-{
- _CrtMemDumpStatistics(&m_memState);
-}
-
-// -- fill with current memory state
-void CMemoryState::Checkpoint()
-{
- _CrtMemCheckpoint(&m_memState);
- UpdateData();
-}
-
-// Dump objects created after this memory state was checkpointed
-// Will dump all objects if this memory state wasn't checkpointed
-// Dump all objects, report about non-objects also
-// List request number in {}
-void CMemoryState::DumpAllObjectsSince() const
-{
- _CrtMemDumpAllObjectsSince(&m_memState);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Enumerate all objects allocated in the diagnostic memory heap
-
-struct _AFX_ENUM_CONTEXT
-{
- void (*m_pfn)(CObject*,void*);
- void* m_pContext;
-};
-
-AFX_STATIC void _AfxDoForAllObjectsProxy(void* pObject, void* pContext)
-{
- _AFX_ENUM_CONTEXT* p = (_AFX_ENUM_CONTEXT*)pContext;
- (*p->m_pfn)((CObject*)pObject, p->m_pContext);
-}
-
-void AFXAPI
-AfxDoForAllObjects(void (AFX_CDECL *pfn)(CObject*, void*), void* pContext)
-{
- if (pfn == NULL)
- {
- AfxThrowInvalidArgException();
- }
- _AFX_ENUM_CONTEXT context;
- context.m_pfn = pfn;
- context.m_pContext = pContext;
- _CrtDoForAllClientObjects(_AfxDoForAllObjectsProxy, &context);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-// Automatic debug memory diagnostics
-
-BOOL AFXAPI AfxDumpMemoryLeaks()
-{
- return _CrtDumpMemoryLeaks();
-}
-
-#endif // _AFX_NO_DEBUG_CRT
-#endif // _DEBUG
-
-/////////////////////////////////////////////////////////////////////////////
-// Non-diagnostic memory routines
-
-int AFX_CDECL AfxNewHandler(size_t /* nSize */)
-{
- AfxThrowMemoryException();
-}
-
-#pragma warning(disable: 4273)
-
-#ifndef _AFXDLL
-_PNH _afxNewHandler = &AfxNewHandler;
-#endif
-
-_PNH AFXAPI AfxGetNewHandler(void)
-{
-#ifdef _AFXDLL
- AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
- return pState->m_pfnNewHandler;
-#else
- return _afxNewHandler;
-#endif
-}
-
-_PNH AFXAPI AfxSetNewHandler(_PNH pfnNewHandler)
-{
-#ifdef _AFXDLL
- AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
- _PNH pfnOldHandler = pState->m_pfnNewHandler;
- pState->m_pfnNewHandler = pfnNewHandler;
- return pfnOldHandler;
-#else
- _PNH pfnOldHandler = _afxNewHandler;
- _afxNewHandler = pfnNewHandler;
- return pfnOldHandler;
-#endif
-}
-
-AFX_STATIC_DATA const _PNH _pfnUninitialized = (_PNH)-1;
-
-void* __cdecl operator new(size_t nSize)
-{
- void* pResult;
-#ifdef _AFXDLL
- _PNH pfnNewHandler = _pfnUninitialized;
-#endif
- for (;;)
- {
-#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
- pResult = _malloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0);
-#else
- pResult = malloc(nSize);
-#endif
- if (pResult != NULL)
- return pResult;
-
-#ifdef _AFXDLL
- if (pfnNewHandler == _pfnUninitialized)
- {
- AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
- pfnNewHandler = pState->m_pfnNewHandler;
- }
- if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
- break;
-#else
- if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
- break;
-#endif
- }
- return pResult;
-}
-
-void __cdecl operator delete(void* p)
-{
-#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
- _free_dbg(p, _NORMAL_BLOCK);
-#else
- free(p);
-#endif
-}
-
-#if _MSC_VER >= 1210
-void* __cdecl operator new[](size_t nSize)
-{
- return ::operator new(nSize);
-}
-
-void __cdecl operator delete[](void* p)
-{
- ::operator delete(p);
-}
-#endif
-
-#ifdef _DEBUG
-
-void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
-{
-#ifdef _AFX_NO_DEBUG_CRT
- UNUSED_ALWAYS(nType);
- UNUSED_ALWAYS(lpszFileName);
- UNUSED_ALWAYS(nLine);
- return ::operator new(nSize);
-#else
- void* pResult;
-#ifdef _AFXDLL
- _PNH pfnNewHandler = _pfnUninitialized;
-#endif
- for (;;)
- {
- pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine);
- if (pResult != NULL)
- return pResult;
-
-#ifdef _AFXDLL
- if (pfnNewHandler == _pfnUninitialized)
- {
- AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
- pfnNewHandler = pState->m_pfnNewHandler;
- }
- if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
- break;
-#else
- if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
- break;
-#endif
- }
- return pResult;
-#endif
-}
-
-#if 0
-#if _MSC_VER >= 1200
-void __cdecl operator delete(void* p, int nType, LPCSTR /* lpszFileName */, int /* nLine */)
-{
-#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
- _free_dbg(p, nType);
-#else
- free(p);
-#endif
-}
-#endif // _MSC_VER >= 1200
-#endif
-
-#if _MSC_VER >= 1210
-void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
-{
- return ::operator new(nSize, nType, lpszFileName, nLine);
-}
-#if 0
-void __cdecl operator delete[](void* p, int nType, LPCSTR lpszFileName, int nLine)
-{
- ::operator delete(p, nType, lpszFileName, nLine);
-}
-#endif
-#endif // _MSC_VER >= 1210
-
-#endif //_DEBUG
-
-/////////////////////////////////////////////////////////////////////////////
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// File extracted from MFC due to symbol conflicts
+
+// This is a part of the Microsoft Foundation Classes C++ library.
+// Copyright (C) Microsoft Corporation
+// All rights reserved.
+//
+// This source code is only intended as a supplement to the
+// Microsoft Foundation Classes Reference and related
+// electronic documentation provided with the library.
+// See these sources for detailed information regarding the
+// Microsoft Foundation Classes product.
+
+#include "stdafx.h"
+
+#ifdef AFX_CORE1_SEG
+#pragma code_seg(AFX_CORE1_SEG)
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Debug memory globals and implementation helpers
+
+#ifdef _DEBUG // most of this file is for debugging
+
+void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine);
+#if _MSC_VER >= 1210
+void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine);
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// test allocation routines
+
+void* PASCAL CObject::operator new(size_t nSize)
+{
+#ifdef _AFX_NO_DEBUG_CRT
+ return ::operator new(nSize);
+#else
+ return ::operator new(nSize, _AFX_CLIENT_BLOCK, NULL, 0);
+#endif // _AFX_NO_DEBUG_CRT
+}
+
+void PASCAL CObject::operator delete(void* p)
+{
+#ifdef _AFX_NO_DEBUG_CRT
+ free(p);
+#else
+ _free_dbg(p, _AFX_CLIENT_BLOCK);
+#endif
+}
+
+#if _MSC_VER >= 1200
+void PASCAL CObject::operator delete(void* p, void*)
+{
+#ifdef _AFX_NO_DEBUG_CRT
+ free(p);
+#else
+ _free_dbg(p, _AFX_CLIENT_BLOCK);
+#endif
+}
+#endif
+
+#ifndef _AFX_NO_DEBUG_CRT
+
+void* __cdecl operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
+{
+ return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
+}
+
+#if _MSC_VER >= 1210
+void* __cdecl operator new[](size_t nSize, LPCSTR lpszFileName, int nLine)
+{
+ return ::operator new[](nSize, _NORMAL_BLOCK, lpszFileName, nLine);
+}
+#endif
+
+#if _MSC_VER >= 1200
+void __cdecl operator delete(void* pData, LPCSTR /* lpszFileName */,
+ int /* nLine */)
+{
+ ::operator delete(pData);
+}
+#endif
+
+#if _MSC_VER >= 1210
+void __cdecl operator delete[](void* pData, LPCSTR /* lpszFileName */,
+ int /* nLine */)
+{
+ ::operator delete(pData);
+}
+#endif
+
+void* PASCAL
+CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
+{
+ return ::operator new(nSize, _AFX_CLIENT_BLOCK, lpszFileName, nLine);
+}
+
+#if _MSC_VER >= 1200
+void PASCAL
+CObject::operator delete(void *pObject, LPCSTR /* lpszFileName */,
+ int /* nLine */)
+{
+#ifdef _AFX_NO_DEBUG_CRT
+ free(pObject);
+#else
+ _free_dbg(pObject, _AFX_CLIENT_BLOCK);
+#endif
+}
+#endif
+
+void* AFXAPI AfxAllocMemoryDebug(size_t nSize, BOOL bIsObject, LPCSTR lpszFileName, int nLine)
+{
+ return _malloc_dbg(nSize, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK,
+ lpszFileName, nLine);
+}
+
+void AFXAPI AfxFreeMemoryDebug(void* pbData, BOOL bIsObject)
+{
+ _free_dbg(pbData, bIsObject ? _AFX_CLIENT_BLOCK : _NORMAL_BLOCK);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// allocation failure hook, tracking turn on
+
+BOOL AFXAPI _AfxDefaultAllocHook(size_t, BOOL, LONG)
+ { return TRUE; }
+
+AFX_STATIC_DATA AFX_ALLOC_HOOK pfnAllocHook = _AfxDefaultAllocHook;
+
+AFX_STATIC_DATA _CRT_ALLOC_HOOK pfnCrtAllocHook = NULL;
+#if _MSC_VER >= 1200
+int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize,
+ int nBlockUse, long lRequest, const unsigned char * szFilename, int nLine)
+#else
+int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize,
+ int nBlockUse, long lRequest, const char * szFilename, int nLine)
+#endif
+{
+#if _MSC_VER >= 1200
+ if (nAllocType != _HOOK_ALLOC)
+ return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
+ nBlockUse, lRequest, (const unsigned char*) szFilename, nLine);
+ if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest))
+ return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
+ nBlockUse, lRequest, (const unsigned char*) szFilename, nLine);
+#else
+ if (nAllocType != _HOOK_ALLOC)
+ return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
+ nBlockUse, lRequest, szFilename, nLine);
+ if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _AFX_CLIENT_BLOCK, lRequest))
+ return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
+ nBlockUse, lRequest, szFilename, nLine);
+#endif
+ return FALSE;
+}
+
+AFX_ALLOC_HOOK AFXAPI AfxSetAllocHook(AFX_ALLOC_HOOK pfnNewHook)
+{
+ if (pfnCrtAllocHook == NULL)
+ pfnCrtAllocHook = _CrtSetAllocHook(_AfxAllocHookProxy);
+
+ AFX_ALLOC_HOOK pfnOldHook = pfnAllocHook;
+ pfnAllocHook = pfnNewHook;
+ return pfnOldHook;
+}
+
+// This can be set to TRUE to override all AfxEnableMemoryTracking calls,
+// allowing all allocations, even MFC internal allocations to be tracked.
+BOOL _afxMemoryLeakOverride = FALSE;
+
+BOOL AFXAPI AfxEnableMemoryTracking(BOOL bTrack)
+{
+ if (_afxMemoryLeakOverride)
+ return TRUE;
+
+ int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ if (bTrack)
+ _CrtSetDbgFlag(nOldState | _CRTDBG_ALLOC_MEM_DF);
+ else
+ _CrtSetDbgFlag(nOldState & ~_CRTDBG_ALLOC_MEM_DF);
+ return nOldState & _CRTDBG_ALLOC_MEM_DF;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// stop on a specific memory request
+
+// Obsolete API
+void AFXAPI AfxSetAllocStop(LONG lRequestNumber)
+{
+ _CrtSetBreakAlloc(lRequestNumber);
+}
+
+BOOL AFXAPI AfxCheckMemory()
+ // check all of memory (look for memory tromps)
+{
+ return _CrtCheckMemory();
+}
+
+// -- true if block of exact size, allocated on the heap
+// -- set *plRequestNumber to request number (or 0)
+BOOL AFXAPI AfxIsMemoryBlock(const void* pData, UINT nBytes,
+ LONG* plRequestNumber)
+{
+ return _CrtIsMemoryBlock(pData, nBytes, plRequestNumber, NULL, NULL);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMemoryState
+
+CMemoryState::CMemoryState()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+void CMemoryState::UpdateData()
+{
+ for(int i = 0; i < nBlockUseMax; i++)
+ {
+ m_lCounts[i] = m_memState.lCounts[i];
+ m_lSizes[i] = m_memState.lSizes[i];
+ }
+ m_lHighWaterCount = m_memState.lHighWaterCount;
+ m_lTotalCount = m_memState.lTotalCount;
+}
+
+// fills 'this' with the difference, returns TRUE if significant
+BOOL CMemoryState::Difference(const CMemoryState& oldState,
+ const CMemoryState& newState)
+{
+ int nResult = _CrtMemDifference(&m_memState, &oldState.m_memState, &newState.m_memState);
+ UpdateData();
+ return nResult != 0;
+}
+
+void CMemoryState::DumpStatistics() const
+{
+ _CrtMemDumpStatistics(&m_memState);
+}
+
+// -- fill with current memory state
+void CMemoryState::Checkpoint()
+{
+ _CrtMemCheckpoint(&m_memState);
+ UpdateData();
+}
+
+// Dump objects created after this memory state was checkpointed
+// Will dump all objects if this memory state wasn't checkpointed
+// Dump all objects, report about non-objects also
+// List request number in {}
+void CMemoryState::DumpAllObjectsSince() const
+{
+ _CrtMemDumpAllObjectsSince(&m_memState);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Enumerate all objects allocated in the diagnostic memory heap
+
+struct _AFX_ENUM_CONTEXT
+{
+ void (*m_pfn)(CObject*,void*);
+ void* m_pContext;
+};
+
+AFX_STATIC void _AfxDoForAllObjectsProxy(void* pObject, void* pContext)
+{
+ _AFX_ENUM_CONTEXT* p = (_AFX_ENUM_CONTEXT*)pContext;
+ (*p->m_pfn)((CObject*)pObject, p->m_pContext);
+}
+
+void AFXAPI
+AfxDoForAllObjects(void (AFX_CDECL *pfn)(CObject*, void*), void* pContext)
+{
+ if (pfn == NULL)
+ {
+ AfxThrowInvalidArgException();
+ }
+ _AFX_ENUM_CONTEXT context;
+ context.m_pfn = pfn;
+ context.m_pContext = pContext;
+ _CrtDoForAllClientObjects(_AfxDoForAllObjectsProxy, &context);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Automatic debug memory diagnostics
+
+BOOL AFXAPI AfxDumpMemoryLeaks()
+{
+ return _CrtDumpMemoryLeaks();
+}
+
+#endif // _AFX_NO_DEBUG_CRT
+#endif // _DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// Non-diagnostic memory routines
+
+int AFX_CDECL AfxNewHandler(size_t /* nSize */)
+{
+ AfxThrowMemoryException();
+}
+
+#pragma warning(disable: 4273)
+
+#ifndef _AFXDLL
+_PNH _afxNewHandler = &AfxNewHandler;
+#endif
+
+_PNH AFXAPI AfxGetNewHandler(void)
+{
+#ifdef _AFXDLL
+ AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
+ return pState->m_pfnNewHandler;
+#else
+ return _afxNewHandler;
+#endif
+}
+
+_PNH AFXAPI AfxSetNewHandler(_PNH pfnNewHandler)
+{
+#ifdef _AFXDLL
+ AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
+ _PNH pfnOldHandler = pState->m_pfnNewHandler;
+ pState->m_pfnNewHandler = pfnNewHandler;
+ return pfnOldHandler;
+#else
+ _PNH pfnOldHandler = _afxNewHandler;
+ _afxNewHandler = pfnNewHandler;
+ return pfnOldHandler;
+#endif
+}
+
+AFX_STATIC_DATA const _PNH _pfnUninitialized = (_PNH)-1;
+
+void* __cdecl operator new(size_t nSize)
+{
+ void* pResult;
+#ifdef _AFXDLL
+ _PNH pfnNewHandler = _pfnUninitialized;
+#endif
+ for (;;)
+ {
+#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
+ pResult = _malloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0);
+#else
+ pResult = malloc(nSize);
+#endif
+ if (pResult != NULL)
+ return pResult;
+
+#ifdef _AFXDLL
+ if (pfnNewHandler == _pfnUninitialized)
+ {
+ AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
+ pfnNewHandler = pState->m_pfnNewHandler;
+ }
+ if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
+ break;
+#else
+ if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
+ break;
+#endif
+ }
+ return pResult;
+}
+
+void __cdecl operator delete(void* p)
+{
+#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
+ _free_dbg(p, _NORMAL_BLOCK);
+#else
+ free(p);
+#endif
+}
+
+#if _MSC_VER >= 1210
+void* __cdecl operator new[](size_t nSize)
+{
+ return ::operator new(nSize);
+}
+
+void __cdecl operator delete[](void* p)
+{
+ ::operator delete(p);
+}
+#endif
+
+#ifdef _DEBUG
+
+void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
+{
+#ifdef _AFX_NO_DEBUG_CRT
+ UNUSED_ALWAYS(nType);
+ UNUSED_ALWAYS(lpszFileName);
+ UNUSED_ALWAYS(nLine);
+ return ::operator new(nSize);
+#else
+ void* pResult;
+#ifdef _AFXDLL
+ _PNH pfnNewHandler = _pfnUninitialized;
+#endif
+ for (;;)
+ {
+ pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine);
+ if (pResult != NULL)
+ return pResult;
+
+#ifdef _AFXDLL
+ if (pfnNewHandler == _pfnUninitialized)
+ {
+ AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
+ pfnNewHandler = pState->m_pfnNewHandler;
+ }
+ if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
+ break;
+#else
+ if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
+ break;
+#endif
+ }
+ return pResult;
+#endif
+}
+
+#if 0
+#if _MSC_VER >= 1200
+void __cdecl operator delete(void* p, int nType, LPCSTR /* lpszFileName */, int /* nLine */)
+{
+#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
+ _free_dbg(p, nType);
+#else
+ free(p);
+#endif
+}
+#endif // _MSC_VER >= 1200
+#endif
+
+#if _MSC_VER >= 1210
+void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
+{
+ return ::operator new(nSize, nType, lpszFileName, nLine);
+}
+#if 0
+void __cdecl operator delete[](void* p, int nType, LPCSTR lpszFileName, int nLine)
+{
+ ::operator delete(p, nType, lpszFileName, nLine);
+}
+#endif
+#endif // _MSC_VER >= 1210
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/sp/src/public/tier0/annotations.h b/sp/src/public/tier0/annotations.h
index fe674971..f81cea32 100644
--- a/sp/src/public/tier0/annotations.h
+++ b/sp/src/public/tier0/annotations.h
@@ -1,119 +1,119 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-#ifndef ANALYSIS_ANNOTATIONS_H
-#define ANALYSIS_ANNOTATIONS_H
-
-#if _MSC_VER >= 1600 // VS 2010 and above.
-//-----------------------------------------------------------------------------
-// Upgrading important helpful warnings to errors
-//-----------------------------------------------------------------------------
-#pragma warning(error : 4789 ) // warning C4789: destination of memory copy is too small
-
-// Suppress some code analysis warnings
-#ifdef _PREFAST_
-// Include the annotation header file.
-#include <sal.h>
-
-// /Analyze warnings can only be suppressed when using a compiler that supports them, which VS 2010
-// Professional does not.
-
-// We don't care about these warnings because they are bugs that can only occur during resource
-// exhaustion or other unexpected API failure, which we are nowhere near being able to handle.
-#pragma warning(disable : 6308) // warning C6308: 'realloc' might return null pointer: assigning null pointer to 's_ppTestCases', which is passed as an argument to 'realloc', will cause the original memory block to be leaked
-#pragma warning(disable : 6255) // warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
-#pragma warning(disable : 6387) // warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'GetProcAddress'
-#pragma warning(disable : 6309) // warning C6309: Argument '1' is null: this does not adhere to function specification of 'GetProcAddress'
-#pragma warning(disable : 6011) // warning C6011: Dereferencing NULL pointer 'm_ppTestCases'
-#pragma warning(disable : 6211) // warning C6211: Leaking memory 'newKeyValue' due to an exception. Consider using a local catch block to clean up memory
-#pragma warning(disable : 6031) // warning C6031: Return value ignored: '_getcwd'
-
-// These warnings are because /analyze doesn't like our use of constants, especially things like IsPC()
-#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
-#pragma warning(disable : 6239) // warning C6239: (<non-zero constant> && <expression>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
-#pragma warning(disable : 6285) // warning C6285: (<non-zero constant> || <non-zero constant>) is always a non-zero constant. Did you intend to use the bitwise-and operator?
-#pragma warning(disable : 6237) // warning C6237: (<zero> && <expression>) is always zero. <expression> is never evaluated and might have side effects
-#pragma warning(disable : 6235) // warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
-#pragma warning(disable : 6240) // warning C6240: (<expression> && <non-zero constant>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
-
-// These warnings aren't really important:
-#pragma warning(disable : 6323) // warning C6323: Use of arithmetic operator on Boolean type(s)
-
-// Miscellaneous other /analyze warnings. We should consider fixing these at some point.
-//#pragma warning(disable : 6204) // warning C6204: Possible buffer overrun in call to 'memcpy': use of unchecked parameter 'src'
-//#pragma warning(disable : 6262) // warning C6262: Function uses '16464' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap
-// This is a serious warning. Don't suppress it.
-//#pragma warning(disable : 6263) // warning C6263: Using _alloca in a loop: this can quickly overflow stack
-// 6328 is also used for passing __int64 to printf when int is expected so we can't suppress it.
-//#pragma warning(disable : 6328) // warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'V_isdigit'
-// /analyze doesn't like GCOMPILER_ASSERT's implementation of compile-time asserts
-#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
-#pragma warning(disable : 6335) // warning C6335: Leaking process information handle 'pi.hThread'
-#pragma warning(disable : 6320) // warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled
-#pragma warning(disable : 6250) // warning C6250: Calling 'VirtualFree' without the MEM_RELEASE flag might free memory but not address descriptors (VADs). This causes address space leaks
-#pragma warning(disable : 6384) // ientity2_class_h_schema_gen.cpp(76): warning C6384: Dividing sizeof a pointer by another value
-
-// For temporarily suppressing warnings -- the warnings are suppressed for the next source line.
-#define ANALYZE_SUPPRESS(wnum) __pragma(warning(suppress: wnum))
-#define ANALYZE_SUPPRESS2(wnum1, wnum2) __pragma(warning(supress: wnum1 wnum2))
-#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3) __pragma(warning(suppress: wnum1 wnum2 wnum3))
-#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4) __pragma(warning(suppress: wnum1 wnum2 wnum3 wnum4))
-
-// Tag all printf style format strings with this
-#define PRINTF_FORMAT_STRING _Printf_format_string_
-#define SCANF_FORMAT_STRING _Scanf_format_string_impl_
-// Various macros for specifying the capacity of the buffer pointed
-// to by a function parameter. Variations include in/out/inout,
-// CAP (elements) versus BYTECAP (bytes), and null termination or
-// not (_Z).
-#define IN_Z _In_z_
-#define IN_CAP(x) _In_count_(x)
-#define IN_BYTECAP(x) _In_bytecount_(x)
-#define OUT_Z_CAP(x) _Out_z_cap_(x)
-#define OUT_CAP(x) _Out_cap_(x)
-#define OUT_CAP_C(x) _Out_cap_c_(x) // Output buffer with specified *constant* capacity in elements
-#define OUT_BYTECAP(x) _Out_bytecap_(x)
-#define OUT_Z_BYTECAP(x) _Out_z_bytecap_(x)
-#define INOUT_BYTECAP(x) _Inout_bytecap_(x)
-#define INOUT_Z_CAP(x) _Inout_z_cap_(x)
-#define INOUT_Z_BYTECAP(x) _Inout_z_bytecap_(x)
-// These macros are use for annotating array reference parameters, typically used in functions
-// such as V_strcpy_safe. Because they are array references the capacity is already known.
-#if _MSC_VER >= 1700
-#define IN_Z_ARRAY _Pre_z_
-#define OUT_Z_ARRAY _Post_z_
-#define INOUT_Z_ARRAY _Prepost_z_
-#else
-#define IN_Z_ARRAY _Deref_pre_z_
-#define OUT_Z_ARRAY _Deref_post_z_
-#define INOUT_Z_ARRAY _Deref_prepost_z_
-#endif // _MSC_VER >= 1700
-// Use the macros above to annotate string functions that fill buffers as shown here,
-// in order to give VS's /analyze more opportunities to find bugs.
-// void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
-// int V_snwprintf( OUT_Z_CAP(maxLenInCharacters) wchar_t *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t *pFormat, ... );
-
-#endif // _PREFAST_
-#endif // _MSC_VER >= 1600 // VS 2010 and above.
-
-#ifndef ANALYZE_SUPPRESS
-#define ANALYZE_SUPPRESS(wnum)
-#define ANALYZE_SUPPRESS2(wnum1, wnum2)
-#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3)
-#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4)
-#define PRINTF_FORMAT_STRING
-#define SCANF_FORMAT_STRING
-#define IN_Z
-#define IN_CAP(x)
-#define IN_BYTECAP(x)
-#define OUT_Z_CAP(x)
-#define OUT_CAP(x)
-#define OUT_CAP_C(x)
-#define OUT_BYTECAP(x)
-#define OUT_Z_BYTECAP(x)
-#define INOUT_BYTECAP(x)
-#define INOUT_Z_CAP(x)
-#define INOUT_Z_BYTECAP(x)
-#define OUT_Z_ARRAY
-#define INOUT_Z_ARRAY
-#endif
-
-#endif // ANALYSIS_ANNOTATIONS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifndef ANALYSIS_ANNOTATIONS_H
+#define ANALYSIS_ANNOTATIONS_H
+
+#if _MSC_VER >= 1600 // VS 2010 and above.
+//-----------------------------------------------------------------------------
+// Upgrading important helpful warnings to errors
+//-----------------------------------------------------------------------------
+#pragma warning(error : 4789 ) // warning C4789: destination of memory copy is too small
+
+// Suppress some code analysis warnings
+#ifdef _PREFAST_
+// Include the annotation header file.
+#include <sal.h>
+
+// /Analyze warnings can only be suppressed when using a compiler that supports them, which VS 2010
+// Professional does not.
+
+// We don't care about these warnings because they are bugs that can only occur during resource
+// exhaustion or other unexpected API failure, which we are nowhere near being able to handle.
+#pragma warning(disable : 6308) // warning C6308: 'realloc' might return null pointer: assigning null pointer to 's_ppTestCases', which is passed as an argument to 'realloc', will cause the original memory block to be leaked
+#pragma warning(disable : 6255) // warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
+#pragma warning(disable : 6387) // warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'GetProcAddress'
+#pragma warning(disable : 6309) // warning C6309: Argument '1' is null: this does not adhere to function specification of 'GetProcAddress'
+#pragma warning(disable : 6011) // warning C6011: Dereferencing NULL pointer 'm_ppTestCases'
+#pragma warning(disable : 6211) // warning C6211: Leaking memory 'newKeyValue' due to an exception. Consider using a local catch block to clean up memory
+#pragma warning(disable : 6031) // warning C6031: Return value ignored: '_getcwd'
+
+// These warnings are because /analyze doesn't like our use of constants, especially things like IsPC()
+#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
+#pragma warning(disable : 6239) // warning C6239: (<non-zero constant> && <expression>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
+#pragma warning(disable : 6285) // warning C6285: (<non-zero constant> || <non-zero constant>) is always a non-zero constant. Did you intend to use the bitwise-and operator?
+#pragma warning(disable : 6237) // warning C6237: (<zero> && <expression>) is always zero. <expression> is never evaluated and might have side effects
+#pragma warning(disable : 6235) // warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
+#pragma warning(disable : 6240) // warning C6240: (<expression> && <non-zero constant>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
+
+// These warnings aren't really important:
+#pragma warning(disable : 6323) // warning C6323: Use of arithmetic operator on Boolean type(s)
+
+// Miscellaneous other /analyze warnings. We should consider fixing these at some point.
+//#pragma warning(disable : 6204) // warning C6204: Possible buffer overrun in call to 'memcpy': use of unchecked parameter 'src'
+//#pragma warning(disable : 6262) // warning C6262: Function uses '16464' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap
+// This is a serious warning. Don't suppress it.
+//#pragma warning(disable : 6263) // warning C6263: Using _alloca in a loop: this can quickly overflow stack
+// 6328 is also used for passing __int64 to printf when int is expected so we can't suppress it.
+//#pragma warning(disable : 6328) // warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'V_isdigit'
+// /analyze doesn't like GCOMPILER_ASSERT's implementation of compile-time asserts
+#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
+#pragma warning(disable : 6335) // warning C6335: Leaking process information handle 'pi.hThread'
+#pragma warning(disable : 6320) // warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled
+#pragma warning(disable : 6250) // warning C6250: Calling 'VirtualFree' without the MEM_RELEASE flag might free memory but not address descriptors (VADs). This causes address space leaks
+#pragma warning(disable : 6384) // ientity2_class_h_schema_gen.cpp(76): warning C6384: Dividing sizeof a pointer by another value
+
+// For temporarily suppressing warnings -- the warnings are suppressed for the next source line.
+#define ANALYZE_SUPPRESS(wnum) __pragma(warning(suppress: wnum))
+#define ANALYZE_SUPPRESS2(wnum1, wnum2) __pragma(warning(supress: wnum1 wnum2))
+#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3) __pragma(warning(suppress: wnum1 wnum2 wnum3))
+#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4) __pragma(warning(suppress: wnum1 wnum2 wnum3 wnum4))
+
+// Tag all printf style format strings with this
+#define PRINTF_FORMAT_STRING _Printf_format_string_
+#define SCANF_FORMAT_STRING _Scanf_format_string_impl_
+// Various macros for specifying the capacity of the buffer pointed
+// to by a function parameter. Variations include in/out/inout,
+// CAP (elements) versus BYTECAP (bytes), and null termination or
+// not (_Z).
+#define IN_Z _In_z_
+#define IN_CAP(x) _In_count_(x)
+#define IN_BYTECAP(x) _In_bytecount_(x)
+#define OUT_Z_CAP(x) _Out_z_cap_(x)
+#define OUT_CAP(x) _Out_cap_(x)
+#define OUT_CAP_C(x) _Out_cap_c_(x) // Output buffer with specified *constant* capacity in elements
+#define OUT_BYTECAP(x) _Out_bytecap_(x)
+#define OUT_Z_BYTECAP(x) _Out_z_bytecap_(x)
+#define INOUT_BYTECAP(x) _Inout_bytecap_(x)
+#define INOUT_Z_CAP(x) _Inout_z_cap_(x)
+#define INOUT_Z_BYTECAP(x) _Inout_z_bytecap_(x)
+// These macros are use for annotating array reference parameters, typically used in functions
+// such as V_strcpy_safe. Because they are array references the capacity is already known.
+#if _MSC_VER >= 1700
+#define IN_Z_ARRAY _Pre_z_
+#define OUT_Z_ARRAY _Post_z_
+#define INOUT_Z_ARRAY _Prepost_z_
+#else
+#define IN_Z_ARRAY _Deref_pre_z_
+#define OUT_Z_ARRAY _Deref_post_z_
+#define INOUT_Z_ARRAY _Deref_prepost_z_
+#endif // _MSC_VER >= 1700
+// Use the macros above to annotate string functions that fill buffers as shown here,
+// in order to give VS's /analyze more opportunities to find bugs.
+// void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
+// int V_snwprintf( OUT_Z_CAP(maxLenInCharacters) wchar_t *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t *pFormat, ... );
+
+#endif // _PREFAST_
+#endif // _MSC_VER >= 1600 // VS 2010 and above.
+
+#ifndef ANALYZE_SUPPRESS
+#define ANALYZE_SUPPRESS(wnum)
+#define ANALYZE_SUPPRESS2(wnum1, wnum2)
+#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3)
+#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4)
+#define PRINTF_FORMAT_STRING
+#define SCANF_FORMAT_STRING
+#define IN_Z
+#define IN_CAP(x)
+#define IN_BYTECAP(x)
+#define OUT_Z_CAP(x)
+#define OUT_CAP(x)
+#define OUT_CAP_C(x)
+#define OUT_BYTECAP(x)
+#define OUT_Z_BYTECAP(x)
+#define INOUT_BYTECAP(x)
+#define INOUT_Z_CAP(x)
+#define INOUT_Z_BYTECAP(x)
+#define OUT_Z_ARRAY
+#define INOUT_Z_ARRAY
+#endif
+
+#endif // ANALYSIS_ANNOTATIONS_H
diff --git a/sp/src/public/tier0/basetypes.h b/sp/src/public/tier0/basetypes.h
index df7b2705..22ce51bc 100644
--- a/sp/src/public/tier0/basetypes.h
+++ b/sp/src/public/tier0/basetypes.h
@@ -1,398 +1,398 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef BASETYPES_H
-#define BASETYPES_H
-
-#include "commonmacros.h"
-#include "wchartypes.h"
-
-#include "tier0/valve_off.h"
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-// This is a trick to get the DLL extension off the -D option on the command line.
-#define DLLExtTokenPaste(x) #x
-#define DLLExtTokenPaste2(x) DLLExtTokenPaste(x)
-#define DLL_EXT_STRING DLLExtTokenPaste2( _DLL_EXT )
-
-
-#include "protected_things.h"
-
-// There's a different version of this file in the xbox codeline
-// so the PC version built in the xbox branch includes things like
-// tickrate changes.
-#include "xbox_codeline_defines.h"
-
-#ifdef IN_XBOX_CODELINE
-#define XBOX_CODELINE_ONLY()
-#else
-#define XBOX_CODELINE_ONLY() Error_Compiling_Code_Only_Valid_in_Xbox_Codeline
-#endif
-
-// stdio.h
-#ifndef NULL
-#define NULL 0
-#endif
-
-
-#ifdef POSIX
-#include <stdint.h>
-#endif
-
-#define ExecuteNTimes( nTimes, x ) \
- { \
- static int __executeCount=0;\
- if ( __executeCount < nTimes )\
- { \
- x; \
- ++__executeCount; \
- } \
- }
-
-
-#define ExecuteOnce( x ) ExecuteNTimes( 1, x )
-
-
-template <typename T>
-inline T AlignValue( T val, uintptr_t alignment )
-{
- return (T)( ( (uintptr_t)val + alignment - 1 ) & ~( alignment - 1 ) );
-}
-
-
-// Pad a number so it lies on an N byte boundary.
-// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
-#define PAD_NUMBER(number, boundary) \
- ( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
-
-// In case this ever changes
-#if !defined(M_PI) && !defined(HAVE_M_PI)
-#define M_PI 3.14159265358979323846
-#endif
-
-#include "valve_minmax_on.h"
-
-// #define COMPILETIME_MAX and COMPILETIME_MIN for max/min in constant expressions
-#define COMPILETIME_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
-#define COMPILETIME_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
-#ifndef MIN
-#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
-#endif
-
-#ifndef MAX
-#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
-#endif
-
-#ifdef __cplusplus
-
-// This is the preferred clamp operator. Using the clamp macro can lead to
-// unexpected side-effects or more expensive code. Even the clamp (all
-// lower-case) function can generate more expensive code because of the
-// mixed types involved.
-template< class T >
-T Clamp( T const &val, T const &minVal, T const &maxVal )
-{
- if( val < minVal )
- return minVal;
- else if( val > maxVal )
- return maxVal;
- else
- return val;
-}
-
-// This is the preferred Min operator. Using the MIN macro can lead to unexpected
-// side-effects or more expensive code.
-template< class T >
-T Min( T const &val1, T const &val2 )
-{
- return val1 < val2 ? val1 : val2;
-}
-
-// This is the preferred Max operator. Using the MAX macro can lead to unexpected
-// side-effects or more expensive code.
-template< class T >
-T Max( T const &val1, T const &val2 )
-{
- return val1 > val2 ? val1 : val2;
-}
-
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE (!FALSE)
-#endif
-
-
-#ifndef DONT_DEFINE_BOOL // Needed for Cocoa stuff to compile.
-typedef int BOOL;
-#endif
-
-typedef int qboolean;
-typedef unsigned long ULONG;
-typedef unsigned char BYTE;
-typedef unsigned char byte;
-typedef unsigned short word;
-#ifdef _WIN32
-typedef wchar_t ucs2; // under windows wchar_t is ucs2
-#else
-typedef unsigned short ucs2;
-#endif
-
-enum ThreeState_t
-{
- TRS_FALSE,
- TRS_TRUE,
- TRS_NONE,
-};
-
-typedef float vec_t;
-
-#if defined(__GNUC__)
-#define fpmin __builtin_fminf
-#define fpmax __builtin_fmaxf
-#elif !defined(_X360)
-#define fpmin min
-#define fpmax max
-#endif
-
-
-//-----------------------------------------------------------------------------
-// look for NANs, infinities, and underflows.
-// This assumes the ANSI/IEEE 754-1985 standard
-//-----------------------------------------------------------------------------
-
-inline unsigned long& FloatBits( vec_t& f )
-{
- return *reinterpret_cast<unsigned long*>(&f);
-}
-
-inline unsigned long const& FloatBits( vec_t const& f )
-{
- return *reinterpret_cast<unsigned long const*>(&f);
-}
-
-inline vec_t BitsToFloat( unsigned long i )
-{
- return *reinterpret_cast<vec_t*>(&i);
-}
-
-inline bool IsFinite( vec_t f )
-{
- return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
-}
-
-inline unsigned long FloatAbsBits( vec_t f )
-{
- return FloatBits(f) & 0x7FFFFFFF;
-}
-
-// Given today's processors, I cannot think of any circumstance
-// where bit tricks would be faster than fabs. henryg 8/16/2011
-#ifdef _MSC_VER
-#ifndef _In_
-#define _In_
-#endif
-extern "C" float fabsf(_In_ float);
-#else
-#include <math.h>
-#endif
-
-inline float FloatMakeNegative( vec_t f )
-{
- return -fabsf(f);
-}
-
-inline float FloatMakePositive( vec_t f )
-{
- return fabsf(f);
-}
-
-inline float FloatNegate( vec_t f )
-{
- return -f;
-}
-
-
-#define FLOAT32_NAN_BITS (unsigned long)0x7FC00000 // not a number!
-#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
-
-#define VEC_T_NAN FLOAT32_NAN
-
-
-
-// FIXME: why are these here? Hardly anyone actually needs them.
-struct color24
-{
- byte r, g, b;
-};
-
-typedef struct color32_s
-{
- bool operator!=( const struct color32_s &other ) const;
-
- byte r, g, b, a;
-} color32;
-
-inline bool color32::operator!=( const color32 &other ) const
-{
- return r != other.r || g != other.g || b != other.b || a != other.a;
-}
-
-struct colorVec
-{
- unsigned r, g, b, a;
-};
-
-
-#ifndef NOTE_UNUSED
-#define NOTE_UNUSED(x) (void)(x) // for pesky compiler / lint warnings
-#endif
-
-struct vrect_t
-{
- int x,y,width,height;
- vrect_t *pnext;
-};
-
-
-//-----------------------------------------------------------------------------
-// MaterialRect_t struct - used for DrawDebugText
-//-----------------------------------------------------------------------------
-struct Rect_t
-{
- int x, y;
- int width, height;
-};
-
-
-//-----------------------------------------------------------------------------
-// Interval, used by soundemittersystem + the game
-//-----------------------------------------------------------------------------
-struct interval_t
-{
- float start;
- float range;
-};
-
-
-//-----------------------------------------------------------------------------
-// Declares a type-safe handle type; you can't assign one handle to the next
-//-----------------------------------------------------------------------------
-
-// 32-bit pointer handles.
-
-// Typesafe 8-bit and 16-bit handles.
-template< class HandleType >
-class CBaseIntHandle
-{
-public:
-
- inline bool operator==( const CBaseIntHandle &other ) { return m_Handle == other.m_Handle; }
- inline bool operator!=( const CBaseIntHandle &other ) { return m_Handle != other.m_Handle; }
-
- // Only the code that doles out these handles should use these functions.
- // Everyone else should treat them as a transparent type.
- inline HandleType GetHandleValue() { return m_Handle; }
- inline void SetHandleValue( HandleType val ) { m_Handle = val; }
-
- typedef HandleType HANDLE_TYPE;
-
-protected:
-
- HandleType m_Handle;
-};
-
-template< class DummyType >
-class CIntHandle16 : public CBaseIntHandle< unsigned short >
-{
-public:
- inline CIntHandle16() {}
-
- static inline CIntHandle16<DummyType> MakeHandle( HANDLE_TYPE val )
- {
- return CIntHandle16<DummyType>( val );
- }
-
-protected:
- inline CIntHandle16( HANDLE_TYPE val )
- {
- m_Handle = val;
- }
-};
-
-
-template< class DummyType >
-class CIntHandle32 : public CBaseIntHandle< unsigned long >
-{
-public:
- inline CIntHandle32() {}
-
- static inline CIntHandle32<DummyType> MakeHandle( HANDLE_TYPE val )
- {
- return CIntHandle32<DummyType>( val );
- }
-
-protected:
- inline CIntHandle32( HANDLE_TYPE val )
- {
- m_Handle = val;
- }
-};
-
-
-// NOTE: This macro is the same as windows uses; so don't change the guts of it
-#define DECLARE_HANDLE_16BIT(name) typedef CIntHandle16< struct name##__handle * > name;
-#define DECLARE_HANDLE_32BIT(name) typedef CIntHandle32< struct name##__handle * > name;
-
-#define DECLARE_POINTER_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
-#define FORWARD_DECLARE_HANDLE(name) typedef struct name##__ *name
-
-// @TODO: Find a better home for this
-#if !defined(_STATIC_LINKED) && !defined(PUBLISH_DLL_SUBSYSTEM)
-// for platforms built with dynamic linking, the dll interface does not need spoofing
-#define PUBLISH_DLL_SUBSYSTEM()
-#endif
-
-#define UID_PREFIX generated_id_
-#define UID_CAT1(a,c) a ## c
-#define UID_CAT2(a,c) UID_CAT1(a,c)
-#define EXPAND_CONCAT(a,c) UID_CAT1(a,c)
-#ifdef _MSC_VER
-#define UNIQUE_ID UID_CAT2(UID_PREFIX,__COUNTER__)
-#else
-#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
-#endif
-
-// this allows enumerations to be used as flags, and still remain type-safe!
-#define DEFINE_ENUM_BITWISE_OPERATORS( Type ) \
- inline Type operator| ( Type a, Type b ) { return Type( int( a ) | int( b ) ); } \
- inline Type operator& ( Type a, Type b ) { return Type( int( a ) & int( b ) ); } \
- inline Type operator^ ( Type a, Type b ) { return Type( int( a ) ^ int( b ) ); } \
- inline Type operator<< ( Type a, int b ) { return Type( int( a ) << b ); } \
- inline Type operator>> ( Type a, int b ) { return Type( int( a ) >> b ); } \
- inline Type &operator|= ( Type &a, Type b ) { return a = a | b; } \
- inline Type &operator&= ( Type &a, Type b ) { return a = a & b; } \
- inline Type &operator^= ( Type &a, Type b ) { return a = a ^ b; } \
- inline Type &operator<<=( Type &a, int b ) { return a = a << b; } \
- inline Type &operator>>=( Type &a, int b ) { return a = a >> b; } \
- inline Type operator~( Type a ) { return Type( ~int( a ) ); }
-
-// defines increment/decrement operators for enums for easy iteration
-#define DEFINE_ENUM_INCREMENT_OPERATORS( Type ) \
- inline Type &operator++( Type &a ) { return a = Type( int( a ) + 1 ); } \
- inline Type &operator--( Type &a ) { return a = Type( int( a ) - 1 ); } \
- inline Type operator++( Type &a, int ) { Type t = a; ++a; return t; } \
- inline Type operator--( Type &a, int ) { Type t = a; --a; return t; }
-
-#include "tier0/valve_on.h"
-
-#endif // BASETYPES_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef BASETYPES_H
+#define BASETYPES_H
+
+#include "commonmacros.h"
+#include "wchartypes.h"
+
+#include "tier0/valve_off.h"
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+// This is a trick to get the DLL extension off the -D option on the command line.
+#define DLLExtTokenPaste(x) #x
+#define DLLExtTokenPaste2(x) DLLExtTokenPaste(x)
+#define DLL_EXT_STRING DLLExtTokenPaste2( _DLL_EXT )
+
+
+#include "protected_things.h"
+
+// There's a different version of this file in the xbox codeline
+// so the PC version built in the xbox branch includes things like
+// tickrate changes.
+#include "xbox_codeline_defines.h"
+
+#ifdef IN_XBOX_CODELINE
+#define XBOX_CODELINE_ONLY()
+#else
+#define XBOX_CODELINE_ONLY() Error_Compiling_Code_Only_Valid_in_Xbox_Codeline
+#endif
+
+// stdio.h
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+#ifdef POSIX
+#include <stdint.h>
+#endif
+
+#define ExecuteNTimes( nTimes, x ) \
+ { \
+ static int __executeCount=0;\
+ if ( __executeCount < nTimes )\
+ { \
+ x; \
+ ++__executeCount; \
+ } \
+ }
+
+
+#define ExecuteOnce( x ) ExecuteNTimes( 1, x )
+
+
+template <typename T>
+inline T AlignValue( T val, uintptr_t alignment )
+{
+ return (T)( ( (uintptr_t)val + alignment - 1 ) & ~( alignment - 1 ) );
+}
+
+
+// Pad a number so it lies on an N byte boundary.
+// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
+#define PAD_NUMBER(number, boundary) \
+ ( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
+
+// In case this ever changes
+#if !defined(M_PI) && !defined(HAVE_M_PI)
+#define M_PI 3.14159265358979323846
+#endif
+
+#include "valve_minmax_on.h"
+
+// #define COMPILETIME_MAX and COMPILETIME_MIN for max/min in constant expressions
+#define COMPILETIME_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#define COMPILETIME_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#ifndef MIN
+#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
+#endif
+
+#ifndef MAX
+#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
+#endif
+
+#ifdef __cplusplus
+
+// This is the preferred clamp operator. Using the clamp macro can lead to
+// unexpected side-effects or more expensive code. Even the clamp (all
+// lower-case) function can generate more expensive code because of the
+// mixed types involved.
+template< class T >
+T Clamp( T const &val, T const &minVal, T const &maxVal )
+{
+ if( val < minVal )
+ return minVal;
+ else if( val > maxVal )
+ return maxVal;
+ else
+ return val;
+}
+
+// This is the preferred Min operator. Using the MIN macro can lead to unexpected
+// side-effects or more expensive code.
+template< class T >
+T Min( T const &val1, T const &val2 )
+{
+ return val1 < val2 ? val1 : val2;
+}
+
+// This is the preferred Max operator. Using the MAX macro can lead to unexpected
+// side-effects or more expensive code.
+template< class T >
+T Max( T const &val1, T const &val2 )
+{
+ return val1 > val2 ? val1 : val2;
+}
+
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+
+#ifndef DONT_DEFINE_BOOL // Needed for Cocoa stuff to compile.
+typedef int BOOL;
+#endif
+
+typedef int qboolean;
+typedef unsigned long ULONG;
+typedef unsigned char BYTE;
+typedef unsigned char byte;
+typedef unsigned short word;
+#ifdef _WIN32
+typedef wchar_t ucs2; // under windows wchar_t is ucs2
+#else
+typedef unsigned short ucs2;
+#endif
+
+enum ThreeState_t
+{
+ TRS_FALSE,
+ TRS_TRUE,
+ TRS_NONE,
+};
+
+typedef float vec_t;
+
+#if defined(__GNUC__)
+#define fpmin __builtin_fminf
+#define fpmax __builtin_fmaxf
+#elif !defined(_X360)
+#define fpmin min
+#define fpmax max
+#endif
+
+
+//-----------------------------------------------------------------------------
+// look for NANs, infinities, and underflows.
+// This assumes the ANSI/IEEE 754-1985 standard
+//-----------------------------------------------------------------------------
+
+inline unsigned long& FloatBits( vec_t& f )
+{
+ return *reinterpret_cast<unsigned long*>(&f);
+}
+
+inline unsigned long const& FloatBits( vec_t const& f )
+{
+ return *reinterpret_cast<unsigned long const*>(&f);
+}
+
+inline vec_t BitsToFloat( unsigned long i )
+{
+ return *reinterpret_cast<vec_t*>(&i);
+}
+
+inline bool IsFinite( vec_t f )
+{
+ return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
+}
+
+inline unsigned long FloatAbsBits( vec_t f )
+{
+ return FloatBits(f) & 0x7FFFFFFF;
+}
+
+// Given today's processors, I cannot think of any circumstance
+// where bit tricks would be faster than fabs. henryg 8/16/2011
+#ifdef _MSC_VER
+#ifndef _In_
+#define _In_
+#endif
+extern "C" float fabsf(_In_ float);
+#else
+#include <math.h>
+#endif
+
+inline float FloatMakeNegative( vec_t f )
+{
+ return -fabsf(f);
+}
+
+inline float FloatMakePositive( vec_t f )
+{
+ return fabsf(f);
+}
+
+inline float FloatNegate( vec_t f )
+{
+ return -f;
+}
+
+
+#define FLOAT32_NAN_BITS (unsigned long)0x7FC00000 // not a number!
+#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
+
+#define VEC_T_NAN FLOAT32_NAN
+
+
+
+// FIXME: why are these here? Hardly anyone actually needs them.
+struct color24
+{
+ byte r, g, b;
+};
+
+typedef struct color32_s
+{
+ bool operator!=( const struct color32_s &other ) const;
+
+ byte r, g, b, a;
+} color32;
+
+inline bool color32::operator!=( const color32 &other ) const
+{
+ return r != other.r || g != other.g || b != other.b || a != other.a;
+}
+
+struct colorVec
+{
+ unsigned r, g, b, a;
+};
+
+
+#ifndef NOTE_UNUSED
+#define NOTE_UNUSED(x) (void)(x) // for pesky compiler / lint warnings
+#endif
+
+struct vrect_t
+{
+ int x,y,width,height;
+ vrect_t *pnext;
+};
+
+
+//-----------------------------------------------------------------------------
+// MaterialRect_t struct - used for DrawDebugText
+//-----------------------------------------------------------------------------
+struct Rect_t
+{
+ int x, y;
+ int width, height;
+};
+
+
+//-----------------------------------------------------------------------------
+// Interval, used by soundemittersystem + the game
+//-----------------------------------------------------------------------------
+struct interval_t
+{
+ float start;
+ float range;
+};
+
+
+//-----------------------------------------------------------------------------
+// Declares a type-safe handle type; you can't assign one handle to the next
+//-----------------------------------------------------------------------------
+
+// 32-bit pointer handles.
+
+// Typesafe 8-bit and 16-bit handles.
+template< class HandleType >
+class CBaseIntHandle
+{
+public:
+
+ inline bool operator==( const CBaseIntHandle &other ) { return m_Handle == other.m_Handle; }
+ inline bool operator!=( const CBaseIntHandle &other ) { return m_Handle != other.m_Handle; }
+
+ // Only the code that doles out these handles should use these functions.
+ // Everyone else should treat them as a transparent type.
+ inline HandleType GetHandleValue() { return m_Handle; }
+ inline void SetHandleValue( HandleType val ) { m_Handle = val; }
+
+ typedef HandleType HANDLE_TYPE;
+
+protected:
+
+ HandleType m_Handle;
+};
+
+template< class DummyType >
+class CIntHandle16 : public CBaseIntHandle< unsigned short >
+{
+public:
+ inline CIntHandle16() {}
+
+ static inline CIntHandle16<DummyType> MakeHandle( HANDLE_TYPE val )
+ {
+ return CIntHandle16<DummyType>( val );
+ }
+
+protected:
+ inline CIntHandle16( HANDLE_TYPE val )
+ {
+ m_Handle = val;
+ }
+};
+
+
+template< class DummyType >
+class CIntHandle32 : public CBaseIntHandle< unsigned long >
+{
+public:
+ inline CIntHandle32() {}
+
+ static inline CIntHandle32<DummyType> MakeHandle( HANDLE_TYPE val )
+ {
+ return CIntHandle32<DummyType>( val );
+ }
+
+protected:
+ inline CIntHandle32( HANDLE_TYPE val )
+ {
+ m_Handle = val;
+ }
+};
+
+
+// NOTE: This macro is the same as windows uses; so don't change the guts of it
+#define DECLARE_HANDLE_16BIT(name) typedef CIntHandle16< struct name##__handle * > name;
+#define DECLARE_HANDLE_32BIT(name) typedef CIntHandle32< struct name##__handle * > name;
+
+#define DECLARE_POINTER_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
+#define FORWARD_DECLARE_HANDLE(name) typedef struct name##__ *name
+
+// @TODO: Find a better home for this
+#if !defined(_STATIC_LINKED) && !defined(PUBLISH_DLL_SUBSYSTEM)
+// for platforms built with dynamic linking, the dll interface does not need spoofing
+#define PUBLISH_DLL_SUBSYSTEM()
+#endif
+
+#define UID_PREFIX generated_id_
+#define UID_CAT1(a,c) a ## c
+#define UID_CAT2(a,c) UID_CAT1(a,c)
+#define EXPAND_CONCAT(a,c) UID_CAT1(a,c)
+#ifdef _MSC_VER
+#define UNIQUE_ID UID_CAT2(UID_PREFIX,__COUNTER__)
+#else
+#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
+#endif
+
+// this allows enumerations to be used as flags, and still remain type-safe!
+#define DEFINE_ENUM_BITWISE_OPERATORS( Type ) \
+ inline Type operator| ( Type a, Type b ) { return Type( int( a ) | int( b ) ); } \
+ inline Type operator& ( Type a, Type b ) { return Type( int( a ) & int( b ) ); } \
+ inline Type operator^ ( Type a, Type b ) { return Type( int( a ) ^ int( b ) ); } \
+ inline Type operator<< ( Type a, int b ) { return Type( int( a ) << b ); } \
+ inline Type operator>> ( Type a, int b ) { return Type( int( a ) >> b ); } \
+ inline Type &operator|= ( Type &a, Type b ) { return a = a | b; } \
+ inline Type &operator&= ( Type &a, Type b ) { return a = a & b; } \
+ inline Type &operator^= ( Type &a, Type b ) { return a = a ^ b; } \
+ inline Type &operator<<=( Type &a, int b ) { return a = a << b; } \
+ inline Type &operator>>=( Type &a, int b ) { return a = a >> b; } \
+ inline Type operator~( Type a ) { return Type( ~int( a ) ); }
+
+// defines increment/decrement operators for enums for easy iteration
+#define DEFINE_ENUM_INCREMENT_OPERATORS( Type ) \
+ inline Type &operator++( Type &a ) { return a = Type( int( a ) + 1 ); } \
+ inline Type &operator--( Type &a ) { return a = Type( int( a ) - 1 ); } \
+ inline Type operator++( Type &a, int ) { Type t = a; ++a; return t; } \
+ inline Type operator--( Type &a, int ) { Type t = a; --a; return t; }
+
+#include "tier0/valve_on.h"
+
+#endif // BASETYPES_H
diff --git a/sp/src/public/tier0/commonmacros.h b/sp/src/public/tier0/commonmacros.h
index 3a192159..ffa934ad 100644
--- a/sp/src/public/tier0/commonmacros.h
+++ b/sp/src/public/tier0/commonmacros.h
@@ -1,173 +1,173 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef COMMONMACROS_H
-#define COMMONMACROS_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-
-// -------------------------------------------------------
-//
-// commonmacros.h
-//
-// This should contain ONLY general purpose macros that are
-// appropriate for use in engine/launcher/all tools
-//
-// -------------------------------------------------------
-
-// Makes a 4-byte "packed ID" int out of 4 characters
-#define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) )
-
-// Compares a string with a 4-byte packed ID constant
-#define STRING_MATCHES_ID( p, id ) ( (*((int *)(p)) == (id) ) ? true : false )
-#define ID_TO_STRING( id, p ) ( (p)[3] = (((id)>>24) & 0xFF), (p)[2] = (((id)>>16) & 0xFF), (p)[1] = (((id)>>8) & 0xFF), (p)[0] = (((id)>>0) & 0xFF) )
-
-#define SETBITS(iBitVector, bits) ((iBitVector) |= (bits))
-#define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits))
-#define FBitSet(iBitVector, bits) ((iBitVector) & (bits))
-
-template <typename T>
-inline bool IsPowerOfTwo( T value )
-{
- return (value & ( value - (T)1 )) == (T)0;
-}
-
-#ifndef REFERENCE
-#define REFERENCE(arg) ((void)arg)
-#endif
-
-#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
-#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
-#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
-
-// Using ARRAYSIZE implementation from winnt.h:
-#ifdef ARRAYSIZE
-#undef ARRAYSIZE
-#endif
-
-// Return the number of elements in a statically sized array.
-// DWORD Buffer[100];
-// RTL_NUMBER_OF(Buffer) == 100
-// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
-//
-#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
-
-#if defined(__cplusplus) && \
- !defined(MIDL_PASS) && \
- !defined(RC_INVOKED) && \
- (_MSC_FULL_VER >= 13009466) && \
- !defined(SORTPP_PASS)
-
-// From crtdefs.h
-#if !defined(UNALIGNED)
-#if defined(_M_IA64) || defined(_M_AMD64)
-#define UNALIGNED __unaligned
-#else
-#define UNALIGNED
-#endif
-#endif
-
-// RtlpNumberOf is a function that takes a reference to an array of N Ts.
-//
-// typedef T array_of_T[N];
-// typedef array_of_T &reference_to_array_of_T;
-//
-// RtlpNumberOf returns a pointer to an array of N chars.
-// We could return a reference instead of a pointer but older compilers do not accept that.
-//
-// typedef char array_of_char[N];
-// typedef array_of_char *pointer_to_array_of_char;
-//
-// sizeof(array_of_char) == N
-// sizeof(*pointer_to_array_of_char) == N
-//
-// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
-//
-// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
-// We do not even implement RtlpNumberOf, we just decare it.
-//
-// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
-// That is the point.
-extern "C++" // templates cannot be declared to have 'C' linkage
-template <typename T, size_t N>
-char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
-
-#ifdef _PREFAST_
-// The +0 is so that we can go:
-// size = ARRAYSIZE(array) * sizeof(array[0]) without triggering a /analyze
-// warning about multiplying sizeof.
-#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))+0)
-#else
-#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
-#endif
-
-// This does not work with:
-//
-// void Foo()
-// {
-// struct { int x; } y[2];
-// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
-// }
-//
-// You must instead do:
-//
-// struct Foo1 { int x; };
-//
-// void Foo()
-// {
-// Foo1 y[2];
-// RTL_NUMBER_OF_V2(y); // ok
-// }
-//
-// OR
-//
-// void Foo()
-// {
-// struct { int x; } y[2];
-// RTL_NUMBER_OF_V1(y); // ok
-// }
-//
-// OR
-//
-// void Foo()
-// {
-// struct { int x; } y[2];
-// _ARRAYSIZE(y); // ok
-// }
-
-#else
-#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
-#endif
-
-// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2
-// _ARRAYSIZE is a version useful for anonymous types
-#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
-#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
-
-#define Q_ARRAYSIZE(p) ARRAYSIZE(p)
-
-template< typename IndexType, typename T, unsigned int N >
-IndexType ClampedArrayIndex( const T (&buffer)[N], IndexType index )
-{
- NOTE_UNUSED( buffer );
- return clamp( index, 0, (IndexType)N - 1 );
-}
-
-template< typename T, unsigned int N >
-T ClampedArrayElement( const T (&buffer)[N], unsigned int uIndex )
-{
- // Put index in an unsigned type to halve the clamping.
- if ( uIndex >= N )
- uIndex = N - 1;
- return buffer[ uIndex ];
-}
-
-#endif // COMMONMACROS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef COMMONMACROS_H
+#define COMMONMACROS_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+
+// -------------------------------------------------------
+//
+// commonmacros.h
+//
+// This should contain ONLY general purpose macros that are
+// appropriate for use in engine/launcher/all tools
+//
+// -------------------------------------------------------
+
+// Makes a 4-byte "packed ID" int out of 4 characters
+#define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) )
+
+// Compares a string with a 4-byte packed ID constant
+#define STRING_MATCHES_ID( p, id ) ( (*((int *)(p)) == (id) ) ? true : false )
+#define ID_TO_STRING( id, p ) ( (p)[3] = (((id)>>24) & 0xFF), (p)[2] = (((id)>>16) & 0xFF), (p)[1] = (((id)>>8) & 0xFF), (p)[0] = (((id)>>0) & 0xFF) )
+
+#define SETBITS(iBitVector, bits) ((iBitVector) |= (bits))
+#define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits))
+#define FBitSet(iBitVector, bits) ((iBitVector) & (bits))
+
+template <typename T>
+inline bool IsPowerOfTwo( T value )
+{
+ return (value & ( value - (T)1 )) == (T)0;
+}
+
+#ifndef REFERENCE
+#define REFERENCE(arg) ((void)arg)
+#endif
+
+#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
+#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
+#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
+
+// Using ARRAYSIZE implementation from winnt.h:
+#ifdef ARRAYSIZE
+#undef ARRAYSIZE
+#endif
+
+// Return the number of elements in a statically sized array.
+// DWORD Buffer[100];
+// RTL_NUMBER_OF(Buffer) == 100
+// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
+//
+#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
+
+#if defined(__cplusplus) && \
+ !defined(MIDL_PASS) && \
+ !defined(RC_INVOKED) && \
+ (_MSC_FULL_VER >= 13009466) && \
+ !defined(SORTPP_PASS)
+
+// From crtdefs.h
+#if !defined(UNALIGNED)
+#if defined(_M_IA64) || defined(_M_AMD64)
+#define UNALIGNED __unaligned
+#else
+#define UNALIGNED
+#endif
+#endif
+
+// RtlpNumberOf is a function that takes a reference to an array of N Ts.
+//
+// typedef T array_of_T[N];
+// typedef array_of_T &reference_to_array_of_T;
+//
+// RtlpNumberOf returns a pointer to an array of N chars.
+// We could return a reference instead of a pointer but older compilers do not accept that.
+//
+// typedef char array_of_char[N];
+// typedef array_of_char *pointer_to_array_of_char;
+//
+// sizeof(array_of_char) == N
+// sizeof(*pointer_to_array_of_char) == N
+//
+// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
+//
+// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
+// We do not even implement RtlpNumberOf, we just decare it.
+//
+// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
+// That is the point.
+extern "C++" // templates cannot be declared to have 'C' linkage
+template <typename T, size_t N>
+char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
+
+#ifdef _PREFAST_
+// The +0 is so that we can go:
+// size = ARRAYSIZE(array) * sizeof(array[0]) without triggering a /analyze
+// warning about multiplying sizeof.
+#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A))+0)
+#else
+#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
+#endif
+
+// This does not work with:
+//
+// void Foo()
+// {
+// struct { int x; } y[2];
+// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
+// }
+//
+// You must instead do:
+//
+// struct Foo1 { int x; };
+//
+// void Foo()
+// {
+// Foo1 y[2];
+// RTL_NUMBER_OF_V2(y); // ok
+// }
+//
+// OR
+//
+// void Foo()
+// {
+// struct { int x; } y[2];
+// RTL_NUMBER_OF_V1(y); // ok
+// }
+//
+// OR
+//
+// void Foo()
+// {
+// struct { int x; } y[2];
+// _ARRAYSIZE(y); // ok
+// }
+
+#else
+#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
+#endif
+
+// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2
+// _ARRAYSIZE is a version useful for anonymous types
+#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
+#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
+
+#define Q_ARRAYSIZE(p) ARRAYSIZE(p)
+
+template< typename IndexType, typename T, unsigned int N >
+IndexType ClampedArrayIndex( const T (&buffer)[N], IndexType index )
+{
+ NOTE_UNUSED( buffer );
+ return clamp( index, 0, (IndexType)N - 1 );
+}
+
+template< typename T, unsigned int N >
+T ClampedArrayElement( const T (&buffer)[N], unsigned int uIndex )
+{
+ // Put index in an unsigned type to halve the clamping.
+ if ( uIndex >= N )
+ uIndex = N - 1;
+ return buffer[ uIndex ];
+}
+
+#endif // COMMONMACROS_H
diff --git a/sp/src/public/tier0/dbg.h b/sp/src/public/tier0/dbg.h
index 2faa26a5..ac7930a4 100644
--- a/sp/src/public/tier0/dbg.h
+++ b/sp/src/public/tier0/dbg.h
@@ -1,795 +1,795 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef DBG_H
-#define DBG_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "basetypes.h"
-#include "dbgflag.h"
-#include "platform.h"
-#include <math.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#ifdef POSIX
-#define __cdecl
-#endif
-
-//-----------------------------------------------------------------------------
-// dll export stuff
-//-----------------------------------------------------------------------------
-#ifndef STATIC_TIER0
-
-#ifdef TIER0_DLL_EXPORT
-#define DBG_INTERFACE DLL_EXPORT
-#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
-#define DBG_CLASS DLL_CLASS_EXPORT
-#else
-#define DBG_INTERFACE DLL_IMPORT
-#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
-#define DBG_CLASS DLL_CLASS_IMPORT
-#endif
-
-#else // BUILD_AS_DLL
-
-#define DBG_INTERFACE extern
-#define DBG_OVERLOAD
-#define DBG_CLASS
-#endif // BUILD_AS_DLL
-
-
-class Color;
-
-
-//-----------------------------------------------------------------------------
-// Usage model for the Dbg library
-//
-// 1. Spew.
-//
-// Spew can be used in a static and a dynamic mode. The static
-// mode allows us to display assertions and other messages either only
-// in debug builds, or in non-release builds. The dynamic mode allows us to
-// turn on and off certain spew messages while the application is running.
-//
-// Static Spew messages:
-//
-// Assertions are used to detect and warn about invalid states
-// Spews are used to display a particular status/warning message.
-//
-// To use an assertion, use
-//
-// Assert( (f == 5) );
-// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
-// AssertFunc( (f == 5), BadFunc() );
-// AssertEquals( f, 5 );
-// AssertFloatEquals( f, 5.0f, 1e-3 );
-//
-// The first will simply report that an assertion failed on a particular
-// code file and line. The second version will display a print-f formatted message
-// along with the file and line, the third will display a generic message and
-// will also cause the function BadFunc to be executed, and the last two
-// will report an error if f is not equal to 5 (the last one asserts within
-// a particular tolerance).
-//
-// To use a warning, use
-//
-// Warning("Oh I feel so %s all over\n", "yummy");
-//
-// Warning will do its magic in only Debug builds. To perform spew in *all*
-// builds, use RelWarning.
-//
-// Three other spew types, Msg, Log, and Error, are compiled into all builds.
-// These error types do *not* need two sets of parenthesis.
-//
-// Msg( "Isn't this exciting %d?", 5 );
-// Error( "I'm just thrilled" );
-//
-// Dynamic Spew messages
-//
-// It is possible to dynamically turn spew on and off. Dynamic spew is
-// identified by a spew group and priority level. To turn spew on for a
-// particular spew group, use SpewActivate( "group", level ). This will
-// cause all spew in that particular group with priority levels <= the
-// level specified in the SpewActivate function to be printed. Use DSpew
-// to perform the spew:
-//
-// DWarning( "group", level, "Oh I feel even yummier!\n" );
-//
-// Priority level 0 means that the spew will *always* be printed, and group
-// '*' is the default spew group. If a DWarning is encountered using a group
-// whose priority has not been set, it will use the priority of the default
-// group. The priority of the default group is initially set to 0.
-//
-// Spew output
-//
-// The output of the spew system can be redirected to an externally-supplied
-// function which is responsible for outputting the spew. By default, the
-// spew is simply printed using printf.
-//
-// To redirect spew output, call SpewOutput.
-//
-// SpewOutputFunc( OutputFunc );
-//
-// This will cause OutputFunc to be called every time a spew message is
-// generated. OutputFunc will be passed a spew type and a message to print.
-// It must return a value indicating whether the debugger should be invoked,
-// whether the program should continue running, or whether the program
-// should abort.
-//
-// 2. Code activation
-//
-// To cause code to be run only in debug builds, use DBG_CODE:
-// An example is below.
-//
-// DBG_CODE(
-// {
-// int x = 5;
-// ++x;
-// }
-// );
-//
-// Code can be activated based on the dynamic spew groups also. Use
-//
-// DBG_DCODE( "group", level,
-// { int x = 5; ++x; }
-// );
-//
-// 3. Breaking into the debugger.
-//
-// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
-//
-// DBG_BREAK();
-//
-// You can force a break in any build (release or debug) using
-//
-// DebuggerBreak();
-//-----------------------------------------------------------------------------
-
-/* Various types of spew messages */
-// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
-// It's because DBG_ is used all over the place in windows.h
-// For example, DBG_CONTINUE is defined. Feh.
-enum SpewType_t
-{
- SPEW_MESSAGE = 0,
- SPEW_WARNING,
- SPEW_ASSERT,
- SPEW_ERROR,
- SPEW_LOG,
-
- SPEW_TYPE_COUNT
-};
-
-enum SpewRetval_t
-{
- SPEW_DEBUGGER = 0,
- SPEW_CONTINUE,
- SPEW_ABORT
-};
-
-/* type of externally defined function used to display debug spew */
-typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg );
-
-/* Used to redirect spew output */
-DBG_INTERFACE void SpewOutputFunc( SpewOutputFunc_t func );
-
-/* Used to get the current spew output function */
-DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void );
-
-/* This is the default spew fun, which is used if you don't specify one */
-DBG_INTERFACE SpewRetval_t DefaultSpewFunc( SpewType_t type, const tchar *pMsg );
-
-/* Same as the default spew func, but returns SPEW_ABORT for asserts */
-DBG_INTERFACE SpewRetval_t DefaultSpewFuncAbortOnAsserts( SpewType_t type, const tchar *pMsg );
-
-/* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */
-DBG_INTERFACE const tchar* GetSpewOutputGroup( void );
-DBG_INTERFACE int GetSpewOutputLevel( void );
-DBG_INTERFACE const Color* GetSpewOutputColor( void );
-
-/* Used to manage spew groups and subgroups */
-DBG_INTERFACE void SpewActivate( const tchar* pGroupName, int level );
-DBG_INTERFACE bool IsSpewActive( const tchar* pGroupName, int level );
-
-/* Used to display messages, should never be called directly. */
-DBG_INTERFACE void _SpewInfo( SpewType_t type, const tchar* pFile, int line );
-DBG_INTERFACE SpewRetval_t _SpewMessage( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
-DBG_INTERFACE bool ShouldUseNewAssertDialog();
-
-DBG_INTERFACE bool SetupWin32ConsoleIO();
-
-// Returns true if they want to break in the debugger.
-DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
-
-// Allows the assert dialogs to be turned off from code
-DBG_INTERFACE bool AreAllAssertsDisabled();
-DBG_INTERFACE void SetAllAssertsDisabled( bool bAssertsEnabled );
-
-// Provides a callback that is called on asserts regardless of spew levels
-typedef void (*AssertFailedNotifyFunc_t)( const char *pchFile, int nLine, const char *pchMessage );
-DBG_INTERFACE void SetAssertFailedNotifyFunc( AssertFailedNotifyFunc_t func );
-DBG_INTERFACE void CallAssertFailedNotifyFunc( const char *pchFile, int nLine, const char *pchMessage );
-
-#if defined( USE_SDL )
-DBG_INTERFACE void SetAssertDialogParent( struct SDL_Window *window );
-DBG_INTERFACE struct SDL_Window * GetAssertDialogParent();
-#endif
-
-/* Used to define macros, never use these directly. */
-
-#ifdef _PREFAST_
- // When doing /analyze builds define _AssertMsg to be __analysis_assume. This tells
- // the compiler to assume that the condition is true, which helps to suppress many
- // warnings. This define is done in debug and release builds.
- // The unfortunate !! is necessary because otherwise /analyze is incapable of evaluating
- // all of the logical expressions that the regular compiler can handle.
- // Include _msg in the macro so that format errors in it are detected.
- #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
- #define _AssertMsgOnce( _exp, _msg, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
- // Force asserts on for /analyze so that we get a __analysis_assume of all of the constraints.
- #define DBGFLAG_ASSERT
- #define DBGFLAG_ASSERTFATAL
- #define DBGFLAG_ASSERTDEBUG
-#else
- #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
- do { \
- if (!(_exp)) \
- { \
- _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
- SpewRetval_t ret = _SpewMessage("%s", _msg); \
- CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \
- _executeExp; \
- if ( ret == SPEW_DEBUGGER) \
- { \
- if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
- { \
- DebuggerBreak(); \
- } \
- if ( _bFatal ) \
- { \
- _ExitOnFatalAssert( __TFILE__, __LINE__ ); \
- } \
- } \
- } \
- } while (0)
-
- #define _AssertMsgOnce( _exp, _msg, _bFatal ) \
- do { \
- static bool fAsserted; \
- if (!fAsserted ) \
- { \
- _AssertMsg( _exp, _msg, (fAsserted = true), _bFatal ); \
- } \
- } while (0)
-#endif
-
-/* Spew macros... */
-
-// AssertFatal macros
-// AssertFatal is used to detect an unrecoverable error condition.
-// If enabled, it may display an assert dialog (if DBGFLAG_ASSERTDLG is turned on or running under the debugger),
-// and always terminates the application
-
-#ifdef DBGFLAG_ASSERTFATAL
-
-#define AssertFatal( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true )
-#define AssertFatalOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true )
-#define AssertFatalMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), true )
-#define AssertFatalMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, true )
-#define AssertFatalFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true )
-#define AssertFatalEquals( _exp, _expectedValue ) AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
-#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) AssertFatalMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
-#define VerifyFatal( _exp ) AssertFatal( _exp )
-#define VerifyEqualsFatal( _exp, _expectedValue ) AssertFatalEquals( _exp, _expectedValue )
-
-#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )))
-#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )))
-#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )))
-#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )))
-#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )))
-#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
-#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
-#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )))
-#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )))
-#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )))
-
-#else // DBGFLAG_ASSERTFATAL
-
-#define AssertFatal( _exp ) ((void)0)
-#define AssertFatalOnce( _exp ) ((void)0)
-#define AssertFatalMsg( _exp, _msg ) ((void)0)
-#define AssertFatalMsgOnce( _exp, _msg ) ((void)0)
-#define AssertFatalFunc( _exp, _f ) ((void)0)
-#define AssertFatalEquals( _exp, _expectedValue ) ((void)0)
-#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
-#define VerifyFatal( _exp ) (_exp)
-#define VerifyEqualsFatal( _exp, _expectedValue ) (_exp)
-
-#define AssertFatalMsg1( _exp, _msg, a1 ) ((void)0)
-#define AssertFatalMsg2( _exp, _msg, a1, a2 ) ((void)0)
-#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
-#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
-#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
-#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
-#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
-#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
-#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
-#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
-
-#endif // DBGFLAG_ASSERTFATAL
-
-// Assert macros
-// Assert is used to detect an important but survivable error.
-// It's only turned on when DBGFLAG_ASSERT is true.
-
-#ifdef DBGFLAG_ASSERT
-
-#define Assert( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
-#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
-#define AssertOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false )
-#define AssertMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, false )
-#define AssertFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false )
-#define AssertEquals( _exp, _expectedValue ) AssertMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
-#define AssertFloatEquals( _exp, _expectedValue, _tol ) AssertMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
-#define Verify( _exp ) Assert( _exp )
-#define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue )
-#define DbgVerify( _exp ) Assert( _exp )
-
-#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) )
-#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) )
-#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) )
-#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) )
-#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) )
-#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) )
-#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )) )
-#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )) )
-#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )) )
-
-#else // DBGFLAG_ASSERT
-
-#define Assert( _exp ) ((void)0)
-#define AssertOnce( _exp ) ((void)0)
-#define AssertMsg( _exp, _msg ) ((void)0)
-#define AssertMsgOnce( _exp, _msg ) ((void)0)
-#define AssertFunc( _exp, _f ) ((void)0)
-#define AssertEquals( _exp, _expectedValue ) ((void)0)
-#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
-#define Verify( _exp ) (_exp)
-#define VerifyEquals( _exp, _expectedValue ) (_exp)
-#define DbgVerify( _exp ) (_exp)
-
-#define AssertMsg1( _exp, _msg, a1 ) ((void)0)
-#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0)
-#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
-#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
-#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
-#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
-#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
-#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
-#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
-#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
-
-#endif // DBGFLAG_ASSERT
-
-// The Always version of the assert macros are defined even when DBGFLAG_ASSERT is not,
-// so they will be available even in release.
-#define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
-#define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
-
-
-#if !defined( _X360 ) || !defined( _RETAIL )
-
-/* These are always compiled in */
-DBG_INTERFACE void Msg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-DBG_INTERFACE void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-DBG_INTERFACE void Log( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DLog( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-#ifdef Error
-// p4.cpp does a #define Error Warning and in that case the Error prototype needs to
-// be consistent with the Warning prototype.
-DBG_INTERFACE void Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-#else
-DBG_INTERFACE void NORETURN Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-#endif
-
-#else
-
-inline void Msg( ... ) {}
-inline void DMsg( ... ) {}
-inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {}
-inline void DWarning( ... ) {}
-inline void Log( ... ) {}
-inline void DLog( ... ) {}
-inline void Error( ... ) {}
-
-#endif
-
-// You can use this macro like a runtime assert macro.
-// If the condition fails, then Error is called with the message. This macro is called
-// like AssertMsg, where msg must be enclosed in parenthesis:
-//
-// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
-#define ErrorIfNot( condition, msg ) \
- if ( condition ) \
- ; \
- else \
- { \
- Error msg; \
- }
-
-#if !defined( _X360 ) || !defined( _RETAIL )
-
-/* A couple of super-common dynamic spew messages, here for convenience */
-/* These looked at the "developer" group */
-DBG_INTERFACE void DevMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void DevWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void DevLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-/* default level versions (level 1) */
-DBG_OVERLOAD void DevMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void DevWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void DevLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* These looked at the "console" group */
-DBG_INTERFACE void ConColorMsg( int level, const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE void ConMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-/* default console version (level 1) */
-DBG_OVERLOAD void ConColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_OVERLOAD void ConMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void ConWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void ConLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* developer console version (level 2) */
-DBG_INTERFACE void ConDColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConDMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void ConDWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void ConDLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* These looked at the "network" group */
-DBG_INTERFACE void NetMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void NetWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void NetLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-void ValidateSpew( class CValidator &validator );
-
-#else
-
-inline void DevMsg( ... ) {}
-inline void DevWarning( ... ) {}
-inline void DevLog( ... ) {}
-inline void ConMsg( ... ) {}
-inline void ConLog( ... ) {}
-inline void NetMsg( ... ) {}
-inline void NetWarning( ... ) {}
-inline void NetLog( ... ) {}
-
-#endif
-
-DBG_INTERFACE void COM_TimestampedLog( PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 1, 2 );
-
-/* Code macros, debugger interface */
-
-#ifdef DBGFLAG_ASSERT
-
-#define DBG_CODE( _code ) if (0) ; else { _code }
-#define DBG_CODE_NOSCOPE( _code ) _code
-#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
-#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */
-
-#else /* not _DEBUG */
-
-#define DBG_CODE( _code ) ((void)0)
-#define DBG_CODE_NOSCOPE( _code )
-#define DBG_DCODE( _g, _l, _code ) ((void)0)
-#define DBG_BREAK() ((void)0)
-
-#endif /* _DEBUG */
-
-//-----------------------------------------------------------------------------
-
-#ifndef _RETAIL
-class CScopeMsg
-{
-public:
- CScopeMsg( const char *pszScope )
- {
- m_pszScope = pszScope;
- Msg( "%s { ", pszScope );
- }
- ~CScopeMsg()
- {
- Msg( "} %s", m_pszScope );
- }
- const char *m_pszScope;
-};
-#define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg )
-#else
-#define SCOPE_MSG( msg )
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Macro to assist in asserting constant invariants during compilation
-
-// This implementation of compile time assert has zero cost (so it can safely be
-// included in release builds) and can be used at file scope or function scope.
-// We're using an ancient version of GCC that can't quite handle some
-// of our complicated templates properly. Use some preprocessor trickery
-// to workaround this
-#ifdef __GNUC__
- #define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
-#else
- #if _MSC_VER >= 1600
- // If available use static_assert instead of weird language tricks. This
- // leads to much more readable messages when compile time assert constraints
- // are violated.
- #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
- #else
- // Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
- // errors when used multiple times in one scope. Fix by adding extra scoping.
- #define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
- #endif
-#endif
-// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
-// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
-#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
-
-
-#ifdef _DEBUG
-template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
-inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
-{
- Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
- return static_cast<DEST_POINTER_TYPE>(pSource);
-}
-#else
-#define assert_cast static_cast
-#endif
-
-//-----------------------------------------------------------------------------
-// Templates to assist in validating pointers:
-
-// Have to use these stubs so we don't have to include windows.h here.
-
-DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
-DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
-DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
-DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF );
-
-#ifdef DBGFLAG_ASSERT
-
-FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); }
-FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); }
-FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); }
-
-#else
-
-FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { }
-FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { }
-FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { }
-#define AssertValidStringPtr AssertValidReadPtr
-
-#endif
-
-#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
-
-//-----------------------------------------------------------------------------
-// Macro to protect functions that are not reentrant
-
-#ifdef _DEBUG
-class CReentryGuard
-{
-public:
- CReentryGuard(int *pSemaphore)
- : m_pSemaphore(pSemaphore)
- {
- ++(*m_pSemaphore);
- }
-
- ~CReentryGuard()
- {
- --(*m_pSemaphore);
- }
-
-private:
- int *m_pSemaphore;
-};
-
-#define ASSERT_NO_REENTRY() \
- static int fSemaphore##__LINE__; \
- Assert( !fSemaphore##__LINE__ ); \
- CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
-#else
-#define ASSERT_NO_REENTRY()
-#endif
-
-//-----------------------------------------------------------------------------
-//
-// Purpose: Inline string formatter
-//
-
-#include "tier0/valve_off.h"
-class CDbgFmtMsg
-{
-public:
- CDbgFmtMsg(PRINTF_FORMAT_STRING const tchar *pszFormat, ...) FMTFUNCTION( 2, 3 )
- {
- va_list arg_ptr;
-
- va_start(arg_ptr, pszFormat);
- _vsntprintf(m_szBuf, sizeof(m_szBuf)-1, pszFormat, arg_ptr);
- va_end(arg_ptr);
-
- m_szBuf[sizeof(m_szBuf)-1] = 0;
- }
-
- operator const tchar *() const
- {
- return m_szBuf;
- }
-
-private:
- tchar m_szBuf[256];
-};
-#include "tier0/valve_on.h"
-
-//-----------------------------------------------------------------------------
-//
-// Purpose: Embed debug info in each file.
-//
-#if defined( _WIN32 ) && !defined( _X360 )
-
- #ifdef _DEBUG
- #pragma comment(compiler)
- #endif
-
-#endif
-
-//-----------------------------------------------------------------------------
-//
-// Purpose: Wrap around a variable to create a simple place to put a breakpoint
-//
-
-#ifdef _DEBUG
-
-template< class Type >
-class CDataWatcher
-{
-public:
- const Type& operator=( const Type &val )
- {
- return Set( val );
- }
-
- const Type& operator=( const CDataWatcher<Type> &val )
- {
- return Set( val.m_Value );
- }
-
- const Type& Set( const Type &val )
- {
- // Put your breakpoint here
- m_Value = val;
- return m_Value;
- }
-
- Type& GetForModify()
- {
- return m_Value;
- }
-
- const Type& operator+=( const Type &val )
- {
- return Set( m_Value + val );
- }
-
- const Type& operator-=( const Type &val )
- {
- return Set( m_Value - val );
- }
-
- const Type& operator/=( const Type &val )
- {
- return Set( m_Value / val );
- }
-
- const Type& operator*=( const Type &val )
- {
- return Set( m_Value * val );
- }
-
- const Type& operator^=( const Type &val )
- {
- return Set( m_Value ^ val );
- }
-
- const Type& operator|=( const Type &val )
- {
- return Set( m_Value | val );
- }
-
- const Type& operator++()
- {
- return (*this += 1);
- }
-
- Type operator--()
- {
- return (*this -= 1);
- }
-
- Type operator++( int ) // postfix version..
- {
- Type val = m_Value;
- (*this += 1);
- return val;
- }
-
- Type operator--( int ) // postfix version..
- {
- Type val = m_Value;
- (*this -= 1);
- return val;
- }
-
- // For some reason the compiler only generates type conversion warnings for this operator when used like
- // CNetworkVarBase<unsigned tchar> = 0x1
- // (it warns about converting from an int to an unsigned char).
- template< class C >
- const Type& operator&=( C val )
- {
- return Set( m_Value & val );
- }
-
- operator const Type&() const
- {
- return m_Value;
- }
-
- const Type& Get() const
- {
- return m_Value;
- }
-
- const Type* operator->() const
- {
- return &m_Value;
- }
-
- Type m_Value;
-
-};
-
-#else
-
-template< class Type >
-class CDataWatcher
-{
-private:
- CDataWatcher(); // refuse to compile in non-debug builds
-};
-
-#endif
-
-//-----------------------------------------------------------------------------
-
-#endif /* DBG_H */
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef DBG_H
+#define DBG_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "basetypes.h"
+#include "dbgflag.h"
+#include "platform.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef POSIX
+#define __cdecl
+#endif
+
+//-----------------------------------------------------------------------------
+// dll export stuff
+//-----------------------------------------------------------------------------
+#ifndef STATIC_TIER0
+
+#ifdef TIER0_DLL_EXPORT
+#define DBG_INTERFACE DLL_EXPORT
+#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
+#define DBG_CLASS DLL_CLASS_EXPORT
+#else
+#define DBG_INTERFACE DLL_IMPORT
+#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
+#define DBG_CLASS DLL_CLASS_IMPORT
+#endif
+
+#else // BUILD_AS_DLL
+
+#define DBG_INTERFACE extern
+#define DBG_OVERLOAD
+#define DBG_CLASS
+#endif // BUILD_AS_DLL
+
+
+class Color;
+
+
+//-----------------------------------------------------------------------------
+// Usage model for the Dbg library
+//
+// 1. Spew.
+//
+// Spew can be used in a static and a dynamic mode. The static
+// mode allows us to display assertions and other messages either only
+// in debug builds, or in non-release builds. The dynamic mode allows us to
+// turn on and off certain spew messages while the application is running.
+//
+// Static Spew messages:
+//
+// Assertions are used to detect and warn about invalid states
+// Spews are used to display a particular status/warning message.
+//
+// To use an assertion, use
+//
+// Assert( (f == 5) );
+// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
+// AssertFunc( (f == 5), BadFunc() );
+// AssertEquals( f, 5 );
+// AssertFloatEquals( f, 5.0f, 1e-3 );
+//
+// The first will simply report that an assertion failed on a particular
+// code file and line. The second version will display a print-f formatted message
+// along with the file and line, the third will display a generic message and
+// will also cause the function BadFunc to be executed, and the last two
+// will report an error if f is not equal to 5 (the last one asserts within
+// a particular tolerance).
+//
+// To use a warning, use
+//
+// Warning("Oh I feel so %s all over\n", "yummy");
+//
+// Warning will do its magic in only Debug builds. To perform spew in *all*
+// builds, use RelWarning.
+//
+// Three other spew types, Msg, Log, and Error, are compiled into all builds.
+// These error types do *not* need two sets of parenthesis.
+//
+// Msg( "Isn't this exciting %d?", 5 );
+// Error( "I'm just thrilled" );
+//
+// Dynamic Spew messages
+//
+// It is possible to dynamically turn spew on and off. Dynamic spew is
+// identified by a spew group and priority level. To turn spew on for a
+// particular spew group, use SpewActivate( "group", level ). This will
+// cause all spew in that particular group with priority levels <= the
+// level specified in the SpewActivate function to be printed. Use DSpew
+// to perform the spew:
+//
+// DWarning( "group", level, "Oh I feel even yummier!\n" );
+//
+// Priority level 0 means that the spew will *always* be printed, and group
+// '*' is the default spew group. If a DWarning is encountered using a group
+// whose priority has not been set, it will use the priority of the default
+// group. The priority of the default group is initially set to 0.
+//
+// Spew output
+//
+// The output of the spew system can be redirected to an externally-supplied
+// function which is responsible for outputting the spew. By default, the
+// spew is simply printed using printf.
+//
+// To redirect spew output, call SpewOutput.
+//
+// SpewOutputFunc( OutputFunc );
+//
+// This will cause OutputFunc to be called every time a spew message is
+// generated. OutputFunc will be passed a spew type and a message to print.
+// It must return a value indicating whether the debugger should be invoked,
+// whether the program should continue running, or whether the program
+// should abort.
+//
+// 2. Code activation
+//
+// To cause code to be run only in debug builds, use DBG_CODE:
+// An example is below.
+//
+// DBG_CODE(
+// {
+// int x = 5;
+// ++x;
+// }
+// );
+//
+// Code can be activated based on the dynamic spew groups also. Use
+//
+// DBG_DCODE( "group", level,
+// { int x = 5; ++x; }
+// );
+//
+// 3. Breaking into the debugger.
+//
+// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
+//
+// DBG_BREAK();
+//
+// You can force a break in any build (release or debug) using
+//
+// DebuggerBreak();
+//-----------------------------------------------------------------------------
+
+/* Various types of spew messages */
+// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
+// It's because DBG_ is used all over the place in windows.h
+// For example, DBG_CONTINUE is defined. Feh.
+enum SpewType_t
+{
+ SPEW_MESSAGE = 0,
+ SPEW_WARNING,
+ SPEW_ASSERT,
+ SPEW_ERROR,
+ SPEW_LOG,
+
+ SPEW_TYPE_COUNT
+};
+
+enum SpewRetval_t
+{
+ SPEW_DEBUGGER = 0,
+ SPEW_CONTINUE,
+ SPEW_ABORT
+};
+
+/* type of externally defined function used to display debug spew */
+typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg );
+
+/* Used to redirect spew output */
+DBG_INTERFACE void SpewOutputFunc( SpewOutputFunc_t func );
+
+/* Used to get the current spew output function */
+DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void );
+
+/* This is the default spew fun, which is used if you don't specify one */
+DBG_INTERFACE SpewRetval_t DefaultSpewFunc( SpewType_t type, const tchar *pMsg );
+
+/* Same as the default spew func, but returns SPEW_ABORT for asserts */
+DBG_INTERFACE SpewRetval_t DefaultSpewFuncAbortOnAsserts( SpewType_t type, const tchar *pMsg );
+
+/* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */
+DBG_INTERFACE const tchar* GetSpewOutputGroup( void );
+DBG_INTERFACE int GetSpewOutputLevel( void );
+DBG_INTERFACE const Color* GetSpewOutputColor( void );
+
+/* Used to manage spew groups and subgroups */
+DBG_INTERFACE void SpewActivate( const tchar* pGroupName, int level );
+DBG_INTERFACE bool IsSpewActive( const tchar* pGroupName, int level );
+
+/* Used to display messages, should never be called directly. */
+DBG_INTERFACE void _SpewInfo( SpewType_t type, const tchar* pFile, int line );
+DBG_INTERFACE SpewRetval_t _SpewMessage( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
+DBG_INTERFACE bool ShouldUseNewAssertDialog();
+
+DBG_INTERFACE bool SetupWin32ConsoleIO();
+
+// Returns true if they want to break in the debugger.
+DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
+
+// Allows the assert dialogs to be turned off from code
+DBG_INTERFACE bool AreAllAssertsDisabled();
+DBG_INTERFACE void SetAllAssertsDisabled( bool bAssertsEnabled );
+
+// Provides a callback that is called on asserts regardless of spew levels
+typedef void (*AssertFailedNotifyFunc_t)( const char *pchFile, int nLine, const char *pchMessage );
+DBG_INTERFACE void SetAssertFailedNotifyFunc( AssertFailedNotifyFunc_t func );
+DBG_INTERFACE void CallAssertFailedNotifyFunc( const char *pchFile, int nLine, const char *pchMessage );
+
+#if defined( USE_SDL )
+DBG_INTERFACE void SetAssertDialogParent( struct SDL_Window *window );
+DBG_INTERFACE struct SDL_Window * GetAssertDialogParent();
+#endif
+
+/* Used to define macros, never use these directly. */
+
+#ifdef _PREFAST_
+ // When doing /analyze builds define _AssertMsg to be __analysis_assume. This tells
+ // the compiler to assume that the condition is true, which helps to suppress many
+ // warnings. This define is done in debug and release builds.
+ // The unfortunate !! is necessary because otherwise /analyze is incapable of evaluating
+ // all of the logical expressions that the regular compiler can handle.
+ // Include _msg in the macro so that format errors in it are detected.
+ #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
+ #define _AssertMsgOnce( _exp, _msg, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
+ // Force asserts on for /analyze so that we get a __analysis_assume of all of the constraints.
+ #define DBGFLAG_ASSERT
+ #define DBGFLAG_ASSERTFATAL
+ #define DBGFLAG_ASSERTDEBUG
+#else
+ #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
+ do { \
+ if (!(_exp)) \
+ { \
+ _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
+ SpewRetval_t ret = _SpewMessage("%s", _msg); \
+ CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \
+ _executeExp; \
+ if ( ret == SPEW_DEBUGGER) \
+ { \
+ if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
+ { \
+ DebuggerBreak(); \
+ } \
+ if ( _bFatal ) \
+ { \
+ _ExitOnFatalAssert( __TFILE__, __LINE__ ); \
+ } \
+ } \
+ } \
+ } while (0)
+
+ #define _AssertMsgOnce( _exp, _msg, _bFatal ) \
+ do { \
+ static bool fAsserted; \
+ if (!fAsserted ) \
+ { \
+ _AssertMsg( _exp, _msg, (fAsserted = true), _bFatal ); \
+ } \
+ } while (0)
+#endif
+
+/* Spew macros... */
+
+// AssertFatal macros
+// AssertFatal is used to detect an unrecoverable error condition.
+// If enabled, it may display an assert dialog (if DBGFLAG_ASSERTDLG is turned on or running under the debugger),
+// and always terminates the application
+
+#ifdef DBGFLAG_ASSERTFATAL
+
+#define AssertFatal( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true )
+#define AssertFatalOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true )
+#define AssertFatalMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), true )
+#define AssertFatalMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, true )
+#define AssertFatalFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true )
+#define AssertFatalEquals( _exp, _expectedValue ) AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
+#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) AssertFatalMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
+#define VerifyFatal( _exp ) AssertFatal( _exp )
+#define VerifyEqualsFatal( _exp, _expectedValue ) AssertFatalEquals( _exp, _expectedValue )
+
+#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )))
+#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )))
+#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )))
+#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )))
+#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )))
+#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
+#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
+#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )))
+#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )))
+#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )))
+
+#else // DBGFLAG_ASSERTFATAL
+
+#define AssertFatal( _exp ) ((void)0)
+#define AssertFatalOnce( _exp ) ((void)0)
+#define AssertFatalMsg( _exp, _msg ) ((void)0)
+#define AssertFatalMsgOnce( _exp, _msg ) ((void)0)
+#define AssertFatalFunc( _exp, _f ) ((void)0)
+#define AssertFatalEquals( _exp, _expectedValue ) ((void)0)
+#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
+#define VerifyFatal( _exp ) (_exp)
+#define VerifyEqualsFatal( _exp, _expectedValue ) (_exp)
+
+#define AssertFatalMsg1( _exp, _msg, a1 ) ((void)0)
+#define AssertFatalMsg2( _exp, _msg, a1, a2 ) ((void)0)
+#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
+#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
+#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
+#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
+#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
+#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
+#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
+#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
+
+#endif // DBGFLAG_ASSERTFATAL
+
+// Assert macros
+// Assert is used to detect an important but survivable error.
+// It's only turned on when DBGFLAG_ASSERT is true.
+
+#ifdef DBGFLAG_ASSERT
+
+#define Assert( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
+#define AssertMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
+#define AssertOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false )
+#define AssertMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, false )
+#define AssertFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false )
+#define AssertEquals( _exp, _expectedValue ) AssertMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
+#define AssertFloatEquals( _exp, _expectedValue, _tol ) AssertMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
+#define Verify( _exp ) Assert( _exp )
+#define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue )
+#define DbgVerify( _exp ) Assert( _exp )
+
+#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) )
+#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) )
+#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) )
+#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) )
+#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) )
+#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) )
+#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )) )
+#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )) )
+#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )) )
+
+#else // DBGFLAG_ASSERT
+
+#define Assert( _exp ) ((void)0)
+#define AssertOnce( _exp ) ((void)0)
+#define AssertMsg( _exp, _msg ) ((void)0)
+#define AssertMsgOnce( _exp, _msg ) ((void)0)
+#define AssertFunc( _exp, _f ) ((void)0)
+#define AssertEquals( _exp, _expectedValue ) ((void)0)
+#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
+#define Verify( _exp ) (_exp)
+#define VerifyEquals( _exp, _expectedValue ) (_exp)
+#define DbgVerify( _exp ) (_exp)
+
+#define AssertMsg1( _exp, _msg, a1 ) ((void)0)
+#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0)
+#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
+#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
+#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
+#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
+#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
+#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
+#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
+#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
+
+#endif // DBGFLAG_ASSERT
+
+// The Always version of the assert macros are defined even when DBGFLAG_ASSERT is not,
+// so they will be available even in release.
+#define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
+#define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
+
+
+#if !defined( _X360 ) || !defined( _RETAIL )
+
+/* These are always compiled in */
+DBG_INTERFACE void Msg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+DBG_INTERFACE void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+DBG_INTERFACE void Log( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DLog( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+#ifdef Error
+// p4.cpp does a #define Error Warning and in that case the Error prototype needs to
+// be consistent with the Warning prototype.
+DBG_INTERFACE void Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+#else
+DBG_INTERFACE void NORETURN Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+#endif
+
+#else
+
+inline void Msg( ... ) {}
+inline void DMsg( ... ) {}
+inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {}
+inline void DWarning( ... ) {}
+inline void Log( ... ) {}
+inline void DLog( ... ) {}
+inline void Error( ... ) {}
+
+#endif
+
+// You can use this macro like a runtime assert macro.
+// If the condition fails, then Error is called with the message. This macro is called
+// like AssertMsg, where msg must be enclosed in parenthesis:
+//
+// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
+#define ErrorIfNot( condition, msg ) \
+ if ( condition ) \
+ ; \
+ else \
+ { \
+ Error msg; \
+ }
+
+#if !defined( _X360 ) || !defined( _RETAIL )
+
+/* A couple of super-common dynamic spew messages, here for convenience */
+/* These looked at the "developer" group */
+DBG_INTERFACE void DevMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void DevWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void DevLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+/* default level versions (level 1) */
+DBG_OVERLOAD void DevMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void DevWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void DevLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* These looked at the "console" group */
+DBG_INTERFACE void ConColorMsg( int level, const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE void ConMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+/* default console version (level 1) */
+DBG_OVERLOAD void ConColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_OVERLOAD void ConMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void ConWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void ConLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* developer console version (level 2) */
+DBG_INTERFACE void ConDColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConDMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void ConDWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void ConDLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* These looked at the "network" group */
+DBG_INTERFACE void NetMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void NetWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void NetLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+void ValidateSpew( class CValidator &validator );
+
+#else
+
+inline void DevMsg( ... ) {}
+inline void DevWarning( ... ) {}
+inline void DevLog( ... ) {}
+inline void ConMsg( ... ) {}
+inline void ConLog( ... ) {}
+inline void NetMsg( ... ) {}
+inline void NetWarning( ... ) {}
+inline void NetLog( ... ) {}
+
+#endif
+
+DBG_INTERFACE void COM_TimestampedLog( PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 1, 2 );
+
+/* Code macros, debugger interface */
+
+#ifdef DBGFLAG_ASSERT
+
+#define DBG_CODE( _code ) if (0) ; else { _code }
+#define DBG_CODE_NOSCOPE( _code ) _code
+#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
+#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */
+
+#else /* not _DEBUG */
+
+#define DBG_CODE( _code ) ((void)0)
+#define DBG_CODE_NOSCOPE( _code )
+#define DBG_DCODE( _g, _l, _code ) ((void)0)
+#define DBG_BREAK() ((void)0)
+
+#endif /* _DEBUG */
+
+//-----------------------------------------------------------------------------
+
+#ifndef _RETAIL
+class CScopeMsg
+{
+public:
+ CScopeMsg( const char *pszScope )
+ {
+ m_pszScope = pszScope;
+ Msg( "%s { ", pszScope );
+ }
+ ~CScopeMsg()
+ {
+ Msg( "} %s", m_pszScope );
+ }
+ const char *m_pszScope;
+};
+#define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg )
+#else
+#define SCOPE_MSG( msg )
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Macro to assist in asserting constant invariants during compilation
+
+// This implementation of compile time assert has zero cost (so it can safely be
+// included in release builds) and can be used at file scope or function scope.
+// We're using an ancient version of GCC that can't quite handle some
+// of our complicated templates properly. Use some preprocessor trickery
+// to workaround this
+#ifdef __GNUC__
+ #define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
+#else
+ #if _MSC_VER >= 1600
+ // If available use static_assert instead of weird language tricks. This
+ // leads to much more readable messages when compile time assert constraints
+ // are violated.
+ #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
+ #else
+ // Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
+ // errors when used multiple times in one scope. Fix by adding extra scoping.
+ #define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
+ #endif
+#endif
+// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
+// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
+#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
+
+
+#ifdef _DEBUG
+template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
+inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
+{
+ Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
+ return static_cast<DEST_POINTER_TYPE>(pSource);
+}
+#else
+#define assert_cast static_cast
+#endif
+
+//-----------------------------------------------------------------------------
+// Templates to assist in validating pointers:
+
+// Have to use these stubs so we don't have to include windows.h here.
+
+DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
+DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
+DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
+DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF );
+
+#ifdef DBGFLAG_ASSERT
+
+FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); }
+FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); }
+FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); }
+
+#else
+
+FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { }
+FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { }
+FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { }
+#define AssertValidStringPtr AssertValidReadPtr
+
+#endif
+
+#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
+
+//-----------------------------------------------------------------------------
+// Macro to protect functions that are not reentrant
+
+#ifdef _DEBUG
+class CReentryGuard
+{
+public:
+ CReentryGuard(int *pSemaphore)
+ : m_pSemaphore(pSemaphore)
+ {
+ ++(*m_pSemaphore);
+ }
+
+ ~CReentryGuard()
+ {
+ --(*m_pSemaphore);
+ }
+
+private:
+ int *m_pSemaphore;
+};
+
+#define ASSERT_NO_REENTRY() \
+ static int fSemaphore##__LINE__; \
+ Assert( !fSemaphore##__LINE__ ); \
+ CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
+#else
+#define ASSERT_NO_REENTRY()
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// Purpose: Inline string formatter
+//
+
+#include "tier0/valve_off.h"
+class CDbgFmtMsg
+{
+public:
+ CDbgFmtMsg(PRINTF_FORMAT_STRING const tchar *pszFormat, ...) FMTFUNCTION( 2, 3 )
+ {
+ va_list arg_ptr;
+
+ va_start(arg_ptr, pszFormat);
+ _vsntprintf(m_szBuf, sizeof(m_szBuf)-1, pszFormat, arg_ptr);
+ va_end(arg_ptr);
+
+ m_szBuf[sizeof(m_szBuf)-1] = 0;
+ }
+
+ operator const tchar *() const
+ {
+ return m_szBuf;
+ }
+
+private:
+ tchar m_szBuf[256];
+};
+#include "tier0/valve_on.h"
+
+//-----------------------------------------------------------------------------
+//
+// Purpose: Embed debug info in each file.
+//
+#if defined( _WIN32 ) && !defined( _X360 )
+
+ #ifdef _DEBUG
+ #pragma comment(compiler)
+ #endif
+
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// Purpose: Wrap around a variable to create a simple place to put a breakpoint
+//
+
+#ifdef _DEBUG
+
+template< class Type >
+class CDataWatcher
+{
+public:
+ const Type& operator=( const Type &val )
+ {
+ return Set( val );
+ }
+
+ const Type& operator=( const CDataWatcher<Type> &val )
+ {
+ return Set( val.m_Value );
+ }
+
+ const Type& Set( const Type &val )
+ {
+ // Put your breakpoint here
+ m_Value = val;
+ return m_Value;
+ }
+
+ Type& GetForModify()
+ {
+ return m_Value;
+ }
+
+ const Type& operator+=( const Type &val )
+ {
+ return Set( m_Value + val );
+ }
+
+ const Type& operator-=( const Type &val )
+ {
+ return Set( m_Value - val );
+ }
+
+ const Type& operator/=( const Type &val )
+ {
+ return Set( m_Value / val );
+ }
+
+ const Type& operator*=( const Type &val )
+ {
+ return Set( m_Value * val );
+ }
+
+ const Type& operator^=( const Type &val )
+ {
+ return Set( m_Value ^ val );
+ }
+
+ const Type& operator|=( const Type &val )
+ {
+ return Set( m_Value | val );
+ }
+
+ const Type& operator++()
+ {
+ return (*this += 1);
+ }
+
+ Type operator--()
+ {
+ return (*this -= 1);
+ }
+
+ Type operator++( int ) // postfix version..
+ {
+ Type val = m_Value;
+ (*this += 1);
+ return val;
+ }
+
+ Type operator--( int ) // postfix version..
+ {
+ Type val = m_Value;
+ (*this -= 1);
+ return val;
+ }
+
+ // For some reason the compiler only generates type conversion warnings for this operator when used like
+ // CNetworkVarBase<unsigned tchar> = 0x1
+ // (it warns about converting from an int to an unsigned char).
+ template< class C >
+ const Type& operator&=( C val )
+ {
+ return Set( m_Value & val );
+ }
+
+ operator const Type&() const
+ {
+ return m_Value;
+ }
+
+ const Type& Get() const
+ {
+ return m_Value;
+ }
+
+ const Type* operator->() const
+ {
+ return &m_Value;
+ }
+
+ Type m_Value;
+
+};
+
+#else
+
+template< class Type >
+class CDataWatcher
+{
+private:
+ CDataWatcher(); // refuse to compile in non-debug builds
+};
+
+#endif
+
+//-----------------------------------------------------------------------------
+
+#endif /* DBG_H */
diff --git a/sp/src/public/tier0/dbgflag.h b/sp/src/public/tier0/dbgflag.h
index 5d9b2bb7..05f84c9d 100644
--- a/sp/src/public/tier0/dbgflag.h
+++ b/sp/src/public/tier0/dbgflag.h
@@ -1,65 +1,65 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This file sets all of our debugging flags. It should be
-// called before all other header files.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef DBGFLAG_H
-#define DBGFLAG_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-// Here are all the flags we support:
-// DBGFLAG_MEMORY: Enables our memory debugging system, which overrides malloc & free
-// DBGFLAG_MEMORY_NEWDEL: Enables new / delete tracking for memory debug system. Requires DBGFLAG_MEMORY to be enabled.
-// DBGFLAG_VALIDATE: Enables our recursive validation system for checking integrity and memory leaks
-// DBGFLAG_ASSERT: Turns Assert on or off (when off, it isn't compiled at all)
-// DBGFLAG_ASSERTFATAL: Turns AssertFatal on or off (when off, it isn't compiled at all)
-// DBGFLAG_ASSERTDLG: Turns assert dialogs on or off and debug breaks on or off when not under the debugger.
-// (Dialogs will always be on when process is being debugged.)
-// DBGFLAG_STRINGS: Turns on hardcore string validation (slow but safe)
-
-#undef DBGFLAG_MEMORY
-#undef DBGFLAG_MEMORY_NEWDEL
-#undef DBGFLAG_VALIDATE
-#undef DBGFLAG_ASSERT
-#undef DBGFLAG_ASSERTFATAL
-#undef DBGFLAG_ASSERTDLG
-#undef DBGFLAG_STRINGS
-
-//-----------------------------------------------------------------------------
-// Default flags for debug builds
-//-----------------------------------------------------------------------------
-#if (defined( _DEBUG ) || defined( RELEASEASSERTS ) )
-
-#define DBGFLAG_MEMORY
-#ifdef _SERVER // only enable new & delete tracking for server; on client it conflicts with CRT mem leak tracking
-#define DBGFLAG_MEMORY_NEWDEL
-#endif
-#ifdef STEAM
-#define DBGFLAG_VALIDATE
-#endif
-#define DBGFLAG_ASSERT
-#define DBGFLAG_ASSERTFATAL
-#define DBGFLAG_ASSERTDLG
-#define DBGFLAG_STRINGS
-
-
-//-----------------------------------------------------------------------------
-// Default flags for release builds
-//-----------------------------------------------------------------------------
-#else // _DEBUG
-
-#ifdef STEAM
-#define DBGFLAG_ASSERT
-#endif
-#define DBGFLAG_ASSERTFATAL // note: fatal asserts are enabled in release builds
-#define DBGFLAG_ASSERTDLG
-
-#endif // _DEBUG
-
-#endif // DBGFLAG_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This file sets all of our debugging flags. It should be
+// called before all other header files.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef DBGFLAG_H
+#define DBGFLAG_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+// Here are all the flags we support:
+// DBGFLAG_MEMORY: Enables our memory debugging system, which overrides malloc & free
+// DBGFLAG_MEMORY_NEWDEL: Enables new / delete tracking for memory debug system. Requires DBGFLAG_MEMORY to be enabled.
+// DBGFLAG_VALIDATE: Enables our recursive validation system for checking integrity and memory leaks
+// DBGFLAG_ASSERT: Turns Assert on or off (when off, it isn't compiled at all)
+// DBGFLAG_ASSERTFATAL: Turns AssertFatal on or off (when off, it isn't compiled at all)
+// DBGFLAG_ASSERTDLG: Turns assert dialogs on or off and debug breaks on or off when not under the debugger.
+// (Dialogs will always be on when process is being debugged.)
+// DBGFLAG_STRINGS: Turns on hardcore string validation (slow but safe)
+
+#undef DBGFLAG_MEMORY
+#undef DBGFLAG_MEMORY_NEWDEL
+#undef DBGFLAG_VALIDATE
+#undef DBGFLAG_ASSERT
+#undef DBGFLAG_ASSERTFATAL
+#undef DBGFLAG_ASSERTDLG
+#undef DBGFLAG_STRINGS
+
+//-----------------------------------------------------------------------------
+// Default flags for debug builds
+//-----------------------------------------------------------------------------
+#if (defined( _DEBUG ) || defined( RELEASEASSERTS ) )
+
+#define DBGFLAG_MEMORY
+#ifdef _SERVER // only enable new & delete tracking for server; on client it conflicts with CRT mem leak tracking
+#define DBGFLAG_MEMORY_NEWDEL
+#endif
+#ifdef STEAM
+#define DBGFLAG_VALIDATE
+#endif
+#define DBGFLAG_ASSERT
+#define DBGFLAG_ASSERTFATAL
+#define DBGFLAG_ASSERTDLG
+#define DBGFLAG_STRINGS
+
+
+//-----------------------------------------------------------------------------
+// Default flags for release builds
+//-----------------------------------------------------------------------------
+#else // _DEBUG
+
+#ifdef STEAM
+#define DBGFLAG_ASSERT
+#endif
+#define DBGFLAG_ASSERTFATAL // note: fatal asserts are enabled in release builds
+#define DBGFLAG_ASSERTDLG
+
+#endif // _DEBUG
+
+#endif // DBGFLAG_H
diff --git a/sp/src/public/tier0/dynfunction.h b/sp/src/public/tier0/dynfunction.h
index 918817a5..bd976b73 100644
--- a/sp/src/public/tier0/dynfunction.h
+++ b/sp/src/public/tier0/dynfunction.h
@@ -1,136 +1,136 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-
-// This makes it easy to dynamically load a shared library and lookup a
-// function in that library.
-//
-// Usage:
-// CDynamicFunction<void (*)(const char *)> MyPuts(libname, "puts");
-// if (MyPuts)
-// MyPuts("Hello world!");
-//
-// Please note that this interface does not distinguish between functions and
-// data. If you look up a global variable in your shared library, or simply
-// mess up the function signature, you'll get a valid pointer and a crash
-// if you call it as a function.
-
-#ifndef DYNFUNCTION_H
-#define DYNFUNCTION_H
-#pragma once
-
-#include "tier0/platform.h"
-
-// The heavy lifting isn't template-specific, so we move it out of the header.
-DLL_EXPORT void *VoidFnPtrLookup_Tier0(const char *libname, const char *fn, void *fallback);
-
-template < class FunctionType >
-class CDynamicFunction
-{
-public:
- // Construct with a NULL function pointer. You must manually call
- // Lookup() before you can call a dynamic function through this interface.
- CDynamicFunction() : m_pFn(NULL) {}
-
- // Construct and do a lookup right away. You will need to make sure that
- // the lookup actually succeeded, as (libname) might have failed to load
- // or (fn) might not exist in it.
- CDynamicFunction(const char *libname, const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
- {
- Lookup(libname, fn, fallback);
- }
-
- // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
- CDynamicFunction(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
- {
- Lookup(libname, fn, okay, fallback);
- }
-
- // Load library if necessary, look up symbol. Returns true and sets
- // m_pFn on successful lookup, returns false otherwise. If the
- // function pointer is already looked up, this return true immediately.
- // Use Reset() first if you want to look up the symbol again.
- // This function will return false immediately unless (okay) is true.
- // This allows you to chain lookups like this:
- // bool okay = true;
- // x.Lookup(lib, "x", okay);
- // y.Lookup(lib, "y", okay);
- // z.Lookup(lib, "z", okay);
- // if (okay) { printf("All functions were loaded successfully!\n"); }
- // If you supply a fallback, it'll be used if the lookup fails (and if
- // non-NULL, means this will always return (okay)).
- bool Lookup(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
- {
- if (!okay)
- return false;
- else if (m_pFn == NULL)
- m_pFn = (FunctionType) VoidFnPtrLookup_Tier0(libname, fn, (void *) fallback);
- okay = m_pFn != NULL;
- return okay;
- }
-
- // Load library if necessary, look up symbol. Returns true and sets
- // m_pFn on successful lookup, returns false otherwise. If the
- // function pointer is already looked up, this return true immediately.
- // Use Reset() first if you want to look up the symbol again.
- // This function will return false immediately unless (okay) is true.
- // If you supply a fallback, it'll be used if the lookup fails (and if
- // non-NULL, means this will always return true).
- bool Lookup(const char *libname, const char *fn, FunctionType fallback=NULL)
- {
- bool okay = true;
- return Lookup(libname, fn, okay, fallback);
- }
-
- // Invalidates the current lookup. Makes the function pointer NULL. You
- // will need to call Lookup() before you can call a dynamic function
- // through this interface again.
- void Reset() { m_pFn = NULL; }
-
- // Force this to be a specific function pointer.
- void Force(FunctionType ptr) { m_pFn = ptr; }
-
- // Retrieve the actual function pointer.
- FunctionType Pointer() const { return m_pFn; }
- operator FunctionType() const { return m_pFn; }
-
- // Can be used to verify that we have an actual function looked up and
- // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
- operator bool () const { return m_pFn != NULL; }
- bool operator !() const { return m_pFn == NULL; }
-
-protected:
- FunctionType m_pFn;
-};
-
-
-// This is the same as CDynamicFunction, but we made the default constructor
-// private, forcing you to do loading/lookup during construction.
-// The usage pattern is to have a list of dynamic functions that are
-// constructed en masse as part of another class's constructor, with the
-// possibility of human error removed (the compiler will complain if you
-// forget to initialize one).
-template < class FunctionType >
-class CDynamicFunctionMustInit : public CDynamicFunction < FunctionType >
-{
-private: // forbid default constructor.
- CDynamicFunctionMustInit() {}
-
-public:
- CDynamicFunctionMustInit(const char *libname, const char *fn, FunctionType fallback=NULL)
- : CDynamicFunction< FunctionType >(libname, fn, fallback)
- {
- }
-
- CDynamicFunctionMustInit(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
- : CDynamicFunction< FunctionType >(libname, fn, okay, fallback)
- {
- }
-};
-
-#endif // DYNFUNCTION_H
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+// This makes it easy to dynamically load a shared library and lookup a
+// function in that library.
+//
+// Usage:
+// CDynamicFunction<void (*)(const char *)> MyPuts(libname, "puts");
+// if (MyPuts)
+// MyPuts("Hello world!");
+//
+// Please note that this interface does not distinguish between functions and
+// data. If you look up a global variable in your shared library, or simply
+// mess up the function signature, you'll get a valid pointer and a crash
+// if you call it as a function.
+
+#ifndef DYNFUNCTION_H
+#define DYNFUNCTION_H
+#pragma once
+
+#include "tier0/platform.h"
+
+// The heavy lifting isn't template-specific, so we move it out of the header.
+DLL_EXPORT void *VoidFnPtrLookup_Tier0(const char *libname, const char *fn, void *fallback);
+
+template < class FunctionType >
+class CDynamicFunction
+{
+public:
+ // Construct with a NULL function pointer. You must manually call
+ // Lookup() before you can call a dynamic function through this interface.
+ CDynamicFunction() : m_pFn(NULL) {}
+
+ // Construct and do a lookup right away. You will need to make sure that
+ // the lookup actually succeeded, as (libname) might have failed to load
+ // or (fn) might not exist in it.
+ CDynamicFunction(const char *libname, const char *fn, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(libname, fn, fallback);
+ }
+
+ // Construct and do a lookup right away. See comments in Lookup() about what (okay) does.
+ CDynamicFunction(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL)
+ {
+ Lookup(libname, fn, okay, fallback);
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // This allows you to chain lookups like this:
+ // bool okay = true;
+ // x.Lookup(lib, "x", okay);
+ // y.Lookup(lib, "y", okay);
+ // z.Lookup(lib, "z", okay);
+ // if (okay) { printf("All functions were loaded successfully!\n"); }
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return (okay)).
+ bool Lookup(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
+ {
+ if (!okay)
+ return false;
+ else if (m_pFn == NULL)
+ m_pFn = (FunctionType) VoidFnPtrLookup_Tier0(libname, fn, (void *) fallback);
+ okay = m_pFn != NULL;
+ return okay;
+ }
+
+ // Load library if necessary, look up symbol. Returns true and sets
+ // m_pFn on successful lookup, returns false otherwise. If the
+ // function pointer is already looked up, this return true immediately.
+ // Use Reset() first if you want to look up the symbol again.
+ // This function will return false immediately unless (okay) is true.
+ // If you supply a fallback, it'll be used if the lookup fails (and if
+ // non-NULL, means this will always return true).
+ bool Lookup(const char *libname, const char *fn, FunctionType fallback=NULL)
+ {
+ bool okay = true;
+ return Lookup(libname, fn, okay, fallback);
+ }
+
+ // Invalidates the current lookup. Makes the function pointer NULL. You
+ // will need to call Lookup() before you can call a dynamic function
+ // through this interface again.
+ void Reset() { m_pFn = NULL; }
+
+ // Force this to be a specific function pointer.
+ void Force(FunctionType ptr) { m_pFn = ptr; }
+
+ // Retrieve the actual function pointer.
+ FunctionType Pointer() const { return m_pFn; }
+ operator FunctionType() const { return m_pFn; }
+
+ // Can be used to verify that we have an actual function looked up and
+ // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); }
+ operator bool () const { return m_pFn != NULL; }
+ bool operator !() const { return m_pFn == NULL; }
+
+protected:
+ FunctionType m_pFn;
+};
+
+
+// This is the same as CDynamicFunction, but we made the default constructor
+// private, forcing you to do loading/lookup during construction.
+// The usage pattern is to have a list of dynamic functions that are
+// constructed en masse as part of another class's constructor, with the
+// possibility of human error removed (the compiler will complain if you
+// forget to initialize one).
+template < class FunctionType >
+class CDynamicFunctionMustInit : public CDynamicFunction < FunctionType >
+{
+private: // forbid default constructor.
+ CDynamicFunctionMustInit() {}
+
+public:
+ CDynamicFunctionMustInit(const char *libname, const char *fn, FunctionType fallback=NULL)
+ : CDynamicFunction< FunctionType >(libname, fn, fallback)
+ {
+ }
+
+ CDynamicFunctionMustInit(const char *libname, const char *fn, bool &okay, FunctionType fallback=NULL)
+ : CDynamicFunction< FunctionType >(libname, fn, okay, fallback)
+ {
+ }
+};
+
+#endif // DYNFUNCTION_H
+
diff --git a/sp/src/public/tier0/etwprof.h b/sp/src/public/tier0/etwprof.h
index 840286d3..c1d42822 100644
--- a/sp/src/public/tier0/etwprof.h
+++ b/sp/src/public/tier0/etwprof.h
@@ -1,157 +1,157 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// ETW (Event Tracing for Windows) profiling helpers.
-// This allows easy insertion of Generic Event markers into ETW/xperf tracing
-// which then aids in analyzing the traces and finding performance problems.
-// The usage patterns are to use ETWBegin and ETWEnd (typically through the
-// convenience class CETWScope) to bracket time-consuming operations. In addition
-// ETWFrameMark marks the beginning of each frame, and ETWMark can be used to
-// mark other notable events. More event types and providers can be added as needed.
-// When recording xperf profiles add Valve-Main+Valve-FrameRate to the list of
-// user-mode providers and be sure to register the providers with this sequence
-// of commands:
-// xcopy /y game\bin\tier0.dll %temp%
-// wevtutil um src\tier0\ValveETWProvider.man
-// wevtutil im src\tier0\ValveETWProvider.man
-//
-//===============================================================================
-
-#ifndef ETWPROF_H
-#define ETWPROF_H
-#if defined( COMPILER_MSVC )
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-
-#ifdef IS_WINDOWS_PC
-// ETW support should be compiled in for all Windows PC platforms. It isn't
-// supported on Windows XP but that is determined at run-time.
-#define ETW_MARKS_ENABLED
-#endif
-
-#ifdef ETW_MARKS_ENABLED
-
-// Insert a single event to mark a point in an ETW trace. The return value is a 64-bit
-// time stamp.
-PLATFORM_INTERFACE int64 ETWMark( const char *pMessage );
-// Optionally do full printf formatting of the mark string. This will be more expensive,
-// but only when tracing is enabled.
-PLATFORM_INTERFACE void ETWMarkPrintf( PRINTF_FORMAT_STRING const char *pMessage, ... ) FMTFUNCTION( 1, 2 );
-// Optionally specify one to four floats. They will show up in separate columns in
-// summary tables to allow sorting and easier transfer to spreadsheets.
-PLATFORM_INTERFACE void ETWMark1F( const char *pMessage, float data1 );
-PLATFORM_INTERFACE void ETWMark2F( const char *pMessage, float data1, float data2 );
-PLATFORM_INTERFACE void ETWMark3F( const char *pMessage, float data1, float data2, float data3 );
-PLATFORM_INTERFACE void ETWMark4F( const char *pMessage, float data1, float data2, float data3, float data4 );
-// Optionally specify one to four ints. They will show up in separate columns in
-// summary tables to allow sorting and easier transfer to spreadsheets.
-PLATFORM_INTERFACE void ETWMark1I( const char *pMessage, int data1 );
-PLATFORM_INTERFACE void ETWMark2I( const char *pMessage, int data1, int data2 );
-PLATFORM_INTERFACE void ETWMark3I( const char *pMessage, int data1, int data2, int data3 );
-PLATFORM_INTERFACE void ETWMark4I( const char *pMessage, int data1, int data2, int data3, int data4 );
-// Optionally specify one to two strings. They will show up in separate columns in
-// summary tables to allow sorting and easier transfer to spreadsheets.
-PLATFORM_INTERFACE void ETWMark1S( const char *pMessage, const char* data1 );
-PLATFORM_INTERFACE void ETWMark2S( const char *pMessage, const char* data1, const char* data2 );
-
-// Insert a begin event to mark the start of some work. The return value is a 64-bit
-// time stamp which should be passed to the corresponding ETWEnd function.
-PLATFORM_INTERFACE int64 ETWBegin( const char *pMessage );
-
-// Insert a paired end event to mark the end of some work.
-PLATFORM_INTERFACE int64 ETWEnd( const char *pMessage, int64 nStartTime );
-
-// Mark the start of the next render frame. bIsServerProcess must be passed
-// in consistently for a particular process.
-PLATFORM_INTERFACE void ETWRenderFrameMark( bool bIsServerProcess );
-// Mark the start of the next simulation frame. bIsServerProcess must be passed
-// in consistently for a particular process.
-PLATFORM_INTERFACE void ETWSimFrameMark( bool bIsServerProcess );
-// Return the frame number recorded in the ETW trace -- useful for synchronizing
-// other profile information to the ETW trace.
-PLATFORM_INTERFACE int ETWGetRenderFrameNumber();
-
-PLATFORM_INTERFACE void ETWMouseDown( int nWhichButton, int nX, int nY );
-PLATFORM_INTERFACE void ETWMouseUp( int nWhichButton, int nX, int nY );
-PLATFORM_INTERFACE void ETWMouseMove( int nX, int nY );
-PLATFORM_INTERFACE void ETWMouseWheel( int nWheelDelta, int nX, int nY );
-PLATFORM_INTERFACE void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar );
-
-PLATFORM_INTERFACE void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck );
-PLATFORM_INTERFACE void ETWThrottled();
-PLATFORM_INTERFACE void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck );
-
-// This class calls the ETW Begin and End functions in order to insert a
-// pair of events to bracket some work.
-class CETWScope
-{
-public:
- CETWScope( const char *pMessage )
- : m_pMessage( pMessage )
- {
- m_nStartTime = ETWBegin( pMessage );
- }
- ~CETWScope()
- {
- ETWEnd( m_pMessage, m_nStartTime );
- }
-private:
- // Private and unimplemented to disable copying.
- CETWScope( const CETWScope& rhs );
- CETWScope& operator=( const CETWScope& rhs );
-
- const char* m_pMessage;
- int64 m_nStartTime;
-};
-
-#else
-
-inline int64 ETWMark( const char* ) { return 0; }
-inline void ETWMarkPrintf( const char *, ... ) { return; }
-inline void ETWMark1F( const char *, float ) { }
-inline void ETWMark2F( const char *, float , float ) { }
-inline void ETWMark3F( const char *, float , float , float ) { }
-inline void ETWMark4F( const char *, float , float , float , float ) { }
-inline void ETWMark1I( const char *, int ) { }
-inline void ETWMark2I( const char *, int , int ) { }
-inline void ETWMark3I( const char *, int , int , int ) { }
-inline void ETWMark4I( const char *, int , int , int , int ) { }
-// Optionally specify one to two strings. They will show up in separate columns in
-// summary tables to allow sorting and easier transfer to spreadsheets.
-inline void ETWMark1S( const char *, const char* ) { }
-inline void ETWMark2S( const char *, const char* , const char* ) { }
-
-inline int64 ETWBegin( const char* ) { return 0; }
-inline int64 ETWEnd( const char*, int64 ) { return 0; }
-inline void ETWRenderFrameMark( bool ) {}
-inline void ETWSimFrameMark( bool ) {}
-inline int ETWGetRenderFrameNumber() { return 0; }
-
-inline void ETWMouseDown( int nWhichButton, int nX, int nY ) {}
-inline void ETWMouseUp( int nWhichButton, int nX, int nY ) {}
-inline void ETWMouseMove( int nX, int nY ) {}
-inline void ETWMouseWheel( int nWheelDelta, int nX, int nY ) {}
-inline void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar ) {}
-
-inline void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck ) {}
-inline void ETWThrottled() {}
-inline void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck ) {}
-
-// This class calls the ETW Begin and End functions in order to insert a
-// pair of events to bracket some work.
-class CETWScope
-{
-public:
- CETWScope( const char* )
- {
- }
-private:
- // Private and unimplemented to disable copying.
- CETWScope( const CETWScope& rhs );
- CETWScope& operator=( const CETWScope& rhs );
-};
-
-#endif
-
-#endif // ETWPROF_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// ETW (Event Tracing for Windows) profiling helpers.
+// This allows easy insertion of Generic Event markers into ETW/xperf tracing
+// which then aids in analyzing the traces and finding performance problems.
+// The usage patterns are to use ETWBegin and ETWEnd (typically through the
+// convenience class CETWScope) to bracket time-consuming operations. In addition
+// ETWFrameMark marks the beginning of each frame, and ETWMark can be used to
+// mark other notable events. More event types and providers can be added as needed.
+// When recording xperf profiles add Valve-Main+Valve-FrameRate to the list of
+// user-mode providers and be sure to register the providers with this sequence
+// of commands:
+// xcopy /y game\bin\tier0.dll %temp%
+// wevtutil um src\tier0\ValveETWProvider.man
+// wevtutil im src\tier0\ValveETWProvider.man
+//
+//===============================================================================
+
+#ifndef ETWPROF_H
+#define ETWPROF_H
+#if defined( COMPILER_MSVC )
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+
+#ifdef IS_WINDOWS_PC
+// ETW support should be compiled in for all Windows PC platforms. It isn't
+// supported on Windows XP but that is determined at run-time.
+#define ETW_MARKS_ENABLED
+#endif
+
+#ifdef ETW_MARKS_ENABLED
+
+// Insert a single event to mark a point in an ETW trace. The return value is a 64-bit
+// time stamp.
+PLATFORM_INTERFACE int64 ETWMark( const char *pMessage );
+// Optionally do full printf formatting of the mark string. This will be more expensive,
+// but only when tracing is enabled.
+PLATFORM_INTERFACE void ETWMarkPrintf( PRINTF_FORMAT_STRING const char *pMessage, ... ) FMTFUNCTION( 1, 2 );
+// Optionally specify one to four floats. They will show up in separate columns in
+// summary tables to allow sorting and easier transfer to spreadsheets.
+PLATFORM_INTERFACE void ETWMark1F( const char *pMessage, float data1 );
+PLATFORM_INTERFACE void ETWMark2F( const char *pMessage, float data1, float data2 );
+PLATFORM_INTERFACE void ETWMark3F( const char *pMessage, float data1, float data2, float data3 );
+PLATFORM_INTERFACE void ETWMark4F( const char *pMessage, float data1, float data2, float data3, float data4 );
+// Optionally specify one to four ints. They will show up in separate columns in
+// summary tables to allow sorting and easier transfer to spreadsheets.
+PLATFORM_INTERFACE void ETWMark1I( const char *pMessage, int data1 );
+PLATFORM_INTERFACE void ETWMark2I( const char *pMessage, int data1, int data2 );
+PLATFORM_INTERFACE void ETWMark3I( const char *pMessage, int data1, int data2, int data3 );
+PLATFORM_INTERFACE void ETWMark4I( const char *pMessage, int data1, int data2, int data3, int data4 );
+// Optionally specify one to two strings. They will show up in separate columns in
+// summary tables to allow sorting and easier transfer to spreadsheets.
+PLATFORM_INTERFACE void ETWMark1S( const char *pMessage, const char* data1 );
+PLATFORM_INTERFACE void ETWMark2S( const char *pMessage, const char* data1, const char* data2 );
+
+// Insert a begin event to mark the start of some work. The return value is a 64-bit
+// time stamp which should be passed to the corresponding ETWEnd function.
+PLATFORM_INTERFACE int64 ETWBegin( const char *pMessage );
+
+// Insert a paired end event to mark the end of some work.
+PLATFORM_INTERFACE int64 ETWEnd( const char *pMessage, int64 nStartTime );
+
+// Mark the start of the next render frame. bIsServerProcess must be passed
+// in consistently for a particular process.
+PLATFORM_INTERFACE void ETWRenderFrameMark( bool bIsServerProcess );
+// Mark the start of the next simulation frame. bIsServerProcess must be passed
+// in consistently for a particular process.
+PLATFORM_INTERFACE void ETWSimFrameMark( bool bIsServerProcess );
+// Return the frame number recorded in the ETW trace -- useful for synchronizing
+// other profile information to the ETW trace.
+PLATFORM_INTERFACE int ETWGetRenderFrameNumber();
+
+PLATFORM_INTERFACE void ETWMouseDown( int nWhichButton, int nX, int nY );
+PLATFORM_INTERFACE void ETWMouseUp( int nWhichButton, int nX, int nY );
+PLATFORM_INTERFACE void ETWMouseMove( int nX, int nY );
+PLATFORM_INTERFACE void ETWMouseWheel( int nWheelDelta, int nX, int nY );
+PLATFORM_INTERFACE void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar );
+
+PLATFORM_INTERFACE void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck );
+PLATFORM_INTERFACE void ETWThrottled();
+PLATFORM_INTERFACE void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck );
+
+// This class calls the ETW Begin and End functions in order to insert a
+// pair of events to bracket some work.
+class CETWScope
+{
+public:
+ CETWScope( const char *pMessage )
+ : m_pMessage( pMessage )
+ {
+ m_nStartTime = ETWBegin( pMessage );
+ }
+ ~CETWScope()
+ {
+ ETWEnd( m_pMessage, m_nStartTime );
+ }
+private:
+ // Private and unimplemented to disable copying.
+ CETWScope( const CETWScope& rhs );
+ CETWScope& operator=( const CETWScope& rhs );
+
+ const char* m_pMessage;
+ int64 m_nStartTime;
+};
+
+#else
+
+inline int64 ETWMark( const char* ) { return 0; }
+inline void ETWMarkPrintf( const char *, ... ) { return; }
+inline void ETWMark1F( const char *, float ) { }
+inline void ETWMark2F( const char *, float , float ) { }
+inline void ETWMark3F( const char *, float , float , float ) { }
+inline void ETWMark4F( const char *, float , float , float , float ) { }
+inline void ETWMark1I( const char *, int ) { }
+inline void ETWMark2I( const char *, int , int ) { }
+inline void ETWMark3I( const char *, int , int , int ) { }
+inline void ETWMark4I( const char *, int , int , int , int ) { }
+// Optionally specify one to two strings. They will show up in separate columns in
+// summary tables to allow sorting and easier transfer to spreadsheets.
+inline void ETWMark1S( const char *, const char* ) { }
+inline void ETWMark2S( const char *, const char* , const char* ) { }
+
+inline int64 ETWBegin( const char* ) { return 0; }
+inline int64 ETWEnd( const char*, int64 ) { return 0; }
+inline void ETWRenderFrameMark( bool ) {}
+inline void ETWSimFrameMark( bool ) {}
+inline int ETWGetRenderFrameNumber() { return 0; }
+
+inline void ETWMouseDown( int nWhichButton, int nX, int nY ) {}
+inline void ETWMouseUp( int nWhichButton, int nX, int nY ) {}
+inline void ETWMouseMove( int nX, int nY ) {}
+inline void ETWMouseWheel( int nWheelDelta, int nX, int nY ) {}
+inline void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar ) {}
+
+inline void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck ) {}
+inline void ETWThrottled() {}
+inline void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck ) {}
+
+// This class calls the ETW Begin and End functions in order to insert a
+// pair of events to bracket some work.
+class CETWScope
+{
+public:
+ CETWScope( const char* )
+ {
+ }
+private:
+ // Private and unimplemented to disable copying.
+ CETWScope( const CETWScope& rhs );
+ CETWScope& operator=( const CETWScope& rhs );
+};
+
+#endif
+
+#endif // ETWPROF_H
diff --git a/sp/src/public/tier0/fasttimer.h b/sp/src/public/tier0/fasttimer.h
index e9833b29..0f49a43e 100644
--- a/sp/src/public/tier0/fasttimer.h
+++ b/sp/src/public/tier0/fasttimer.h
@@ -1,571 +1,571 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef FASTTIMER_H
-#define FASTTIMER_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#ifdef _WIN32
-#include <intrin.h>
-#endif
-
-#include <assert.h>
-#include "tier0/platform.h"
-
-PLATFORM_INTERFACE uint64 g_ClockSpeed;
-#if defined( _X360 ) && defined( _CERT )
-PLATFORM_INTERFACE unsigned long g_dwFakeFastCounter;
-#endif
-
-PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier;
-PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier;
-PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier;
-
-class CCycleCount
-{
-friend class CFastTimer;
-
-public:
- CCycleCount();
- CCycleCount( uint64 cycles );
-
- void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900).
-
- void Init(); // Set to zero.
- void Init( float initTimeMsec );
- void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); }
- void Init( uint64 cycles );
- bool IsLessThan( CCycleCount const &other ) const; // Compare two counts.
-
- // Convert to other time representations. These functions are slow, so it's preferable to call them
- // during display rather than inside a timing block.
- unsigned long GetCycles() const;
- uint64 GetLongCycles() const;
-
- unsigned long GetMicroseconds() const;
- uint64 GetUlMicroseconds() const;
- double GetMicrosecondsF() const;
- void SetMicroseconds( unsigned long nMicroseconds );
-
- unsigned long GetMilliseconds() const;
- double GetMillisecondsF() const;
-
- double GetSeconds() const;
-
- CCycleCount& operator+=( CCycleCount const &other );
-
- // dest = rSrc1 + rSrc2
- static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
-
- // dest = rSrc1 - rSrc2
- static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
-
- static uint64 GetTimestamp();
-
- uint64 m_Int64;
-};
-
-class PLATFORM_CLASS CClockSpeedInit
-{
-public:
- CClockSpeedInit()
- {
- Init();
- }
-
- static void Init();
-};
-
-class CFastTimer
-{
-public:
- // These functions are fast to call and should be called from your sampling code.
- void Start();
- void End();
-
- const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls.
- CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap.
-
- // Return number of cycles per second on this processor.
- static inline int64 GetClockSpeed();
-
-private:
- CCycleCount m_Duration;
-#ifdef DEBUG_FASTTIMER
- bool m_bRunning; // Are we currently running?
-#endif
-};
-
-
-// This is a helper class that times whatever block of code it's in
-class CTimeScope
-{
-public:
- CTimeScope( CFastTimer *pTimer );
- ~CTimeScope();
-
-private:
- CFastTimer *m_pTimer;
-};
-
-inline CTimeScope::CTimeScope( CFastTimer *pTotal )
-{
- m_pTimer = pTotal;
- m_pTimer->Start();
-}
-
-inline CTimeScope::~CTimeScope()
-{
- m_pTimer->End();
-}
-
-// This is a helper class that times whatever block of code it's in and
-// adds the total (int microseconds) to a global counter.
-class CTimeAdder
-{
-public:
- CTimeAdder( CCycleCount *pTotal );
- ~CTimeAdder();
-
- void End();
-
-private:
- CCycleCount *m_pTotal;
- CFastTimer m_Timer;
-};
-
-inline CTimeAdder::CTimeAdder( CCycleCount *pTotal )
-{
- m_pTotal = pTotal;
- m_Timer.Start();
-}
-
-inline CTimeAdder::~CTimeAdder()
-{
- End();
-}
-
-inline void CTimeAdder::End()
-{
- if( m_pTotal )
- {
- m_Timer.End();
- *m_pTotal += m_Timer.GetDuration();
- m_pTotal = 0;
- }
-}
-
-
-
-// -------------------------------------------------------------------------- //
-// Simple tool to support timing a block of code, and reporting the results on
-// program exit or at each iteration
-//
-// Macros used because dbg.h uses this header, thus Msg() is unavailable
-// -------------------------------------------------------------------------- //
-
-#define PROFILE_SCOPE(name) \
- class C##name##ACC : public CAverageCycleCounter \
- { \
- public: \
- ~C##name##ACC() \
- { \
- Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \
- #name, \
- GetAverageMilliseconds(), \
- GetTotalMilliseconds(), \
- GetPeakMilliseconds(), \
- GetIters() ); \
- } \
- }; \
- static C##name##ACC name##_ACC; \
- CAverageTimeMarker name##_ATM( &name##_ACC )
-
-#define TIME_SCOPE(name) \
- class CTimeScopeMsg_##name \
- { \
- public: \
- CTimeScopeMsg_##name() { m_Timer.Start(); } \
- ~CTimeScopeMsg_##name() \
- { \
- m_Timer.End(); \
- Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \
- } \
- private: \
- CFastTimer m_Timer; \
- } name##_TSM;
-
-
-// -------------------------------------------------------------------------- //
-
-class CAverageCycleCounter
-{
-public:
- CAverageCycleCounter();
-
- void Init();
- void MarkIter( const CCycleCount &duration );
-
- unsigned GetIters() const;
-
- double GetAverageMilliseconds() const;
- double GetTotalMilliseconds() const;
- double GetPeakMilliseconds() const;
-
-private:
- unsigned m_nIters;
- CCycleCount m_Total;
- CCycleCount m_Peak;
- bool m_fReport;
- const tchar *m_pszName;
-};
-
-// -------------------------------------------------------------------------- //
-
-class CAverageTimeMarker
-{
-public:
- CAverageTimeMarker( CAverageCycleCounter *pCounter );
- ~CAverageTimeMarker();
-
-private:
- CAverageCycleCounter *m_pCounter;
- CFastTimer m_Timer;
-};
-
-
-// -------------------------------------------------------------------------- //
-// CCycleCount inlines.
-// -------------------------------------------------------------------------- //
-
-inline CCycleCount::CCycleCount()
-{
- Init( (uint64)0 );
-}
-
-inline CCycleCount::CCycleCount( uint64 cycles )
-{
- Init( cycles );
-}
-
-inline void CCycleCount::Init()
-{
- Init( (uint64)0 );
-}
-
-inline void CCycleCount::Init( float initTimeMsec )
-{
- if ( g_ClockSpeedMillisecondsMultiplier > 0 )
- Init( (uint64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) );
- else
- Init( (uint64)0 );
-}
-
-inline void CCycleCount::Init( uint64 cycles )
-{
- m_Int64 = cycles;
-}
-
-inline void CCycleCount::Sample()
-{
- m_Int64 = Plat_Rdtsc();
-}
-
-inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other )
-{
- m_Int64 += other.m_Int64;
- return *this;
-}
-
-
-inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
-{
- dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64;
-}
-
-inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
-{
- dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64;
-}
-
-inline uint64 CCycleCount::GetTimestamp()
-{
- CCycleCount c;
- c.Sample();
- return c.GetLongCycles();
-}
-
-inline bool CCycleCount::IsLessThan(CCycleCount const &other) const
-{
- return m_Int64 < other.m_Int64;
-}
-
-
-inline unsigned long CCycleCount::GetCycles() const
-{
- return (unsigned long)m_Int64;
-}
-
-inline uint64 CCycleCount::GetLongCycles() const
-{
- return m_Int64;
-}
-
-inline unsigned long CCycleCount::GetMicroseconds() const
-{
- return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed);
-}
-
-inline uint64 CCycleCount::GetUlMicroseconds() const
-{
- return ((m_Int64 * 1000000) / g_ClockSpeed);
-}
-
-
-inline double CCycleCount::GetMicrosecondsF() const
-{
- return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier );
-}
-
-
-inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds )
-{
- m_Int64 = ((uint64)nMicroseconds * g_ClockSpeed) / 1000000;
-}
-
-
-inline unsigned long CCycleCount::GetMilliseconds() const
-{
- return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed);
-}
-
-
-inline double CCycleCount::GetMillisecondsF() const
-{
- return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier );
-}
-
-
-inline double CCycleCount::GetSeconds() const
-{
- return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier );
-}
-
-
-// -------------------------------------------------------------------------- //
-// CFastTimer inlines.
-// -------------------------------------------------------------------------- //
-inline void CFastTimer::Start()
-{
- m_Duration.Sample();
-#ifdef DEBUG_FASTTIMER
- m_bRunning = true;
-#endif
-}
-
-
-inline void CFastTimer::End()
-{
- CCycleCount cnt;
- cnt.Sample();
- if ( IsX360() )
- {
- // have to handle rollover, hires timer is only accurate to 32 bits
- // more than one overflow should not have occurred, otherwise caller should use a slower timer
- if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
- {
- // rollover occurred
- cnt.m_Int64 += 0x100000000LL;
- }
- }
-
- m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
-
-#ifdef DEBUG_FASTTIMER
- m_bRunning = false;
-#endif
-}
-
-inline CCycleCount CFastTimer::GetDurationInProgress() const
-{
- CCycleCount cnt;
- cnt.Sample();
- if ( IsX360() )
- {
- // have to handle rollover, hires timer is only accurate to 32 bits
- // more than one overflow should not have occurred, otherwise caller should use a slower timer
- if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
- {
- // rollover occurred
- cnt.m_Int64 += 0x100000000LL;
- }
- }
-
- CCycleCount result;
- result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
-
- return result;
-}
-
-
-inline int64 CFastTimer::GetClockSpeed()
-{
- return g_ClockSpeed;
-}
-
-
-inline CCycleCount const& CFastTimer::GetDuration() const
-{
-#ifdef DEBUG_FASTTIMER
- assert( !m_bRunning );
-#endif
- return m_Duration;
-}
-
-
-// -------------------------------------------------------------------------- //
-// CAverageCycleCounter inlines
-
-inline CAverageCycleCounter::CAverageCycleCounter()
- : m_nIters( 0 )
-{
-}
-
-inline void CAverageCycleCounter::Init()
-{
- m_Total.Init();
- m_Peak.Init();
- m_nIters = 0;
-}
-
-inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration )
-{
- ++m_nIters;
- m_Total += duration;
- if ( m_Peak.IsLessThan( duration ) )
- m_Peak = duration;
-}
-
-inline unsigned CAverageCycleCounter::GetIters() const
-{
- return m_nIters;
-}
-
-inline double CAverageCycleCounter::GetAverageMilliseconds() const
-{
- if ( m_nIters )
- return (m_Total.GetMillisecondsF() / (double)m_nIters);
- else
- return 0;
-}
-
-inline double CAverageCycleCounter::GetTotalMilliseconds() const
-{
- return m_Total.GetMillisecondsF();
-}
-
-inline double CAverageCycleCounter::GetPeakMilliseconds() const
-{
- return m_Peak.GetMillisecondsF();
-}
-
-// -------------------------------------------------------------------------- //
-
-inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter )
-{
- m_pCounter = pCounter;
- m_Timer.Start();
-}
-
-inline CAverageTimeMarker::~CAverageTimeMarker()
-{
- m_Timer.End();
- m_pCounter->MarkIter( m_Timer.GetDuration() );
-}
-
-
-// CLimitTimer
-// Use this to time whether a desired interval of time has passed. It's extremely fast
-// to check while running. NOTE: CMicroSecOverage() and CMicroSecLeft() are not as fast to check.
-class CLimitTimer
-{
-public:
- CLimitTimer() {}
- CLimitTimer( uint64 cMicroSecDuration ) { SetLimit( cMicroSecDuration ); }
- void SetLimit( uint64 m_cMicroSecDuration );
- bool BLimitReached();
-
- int CMicroSecOverage();
- uint64 CMicroSecLeft();
-
-private:
- uint64 m_lCycleLimit;
-};
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Initializes the limit timer with a period of time to measure.
-// Input : cMicroSecDuration - How long a time period to measure
-//-----------------------------------------------------------------------------
-inline void CLimitTimer::SetLimit( uint64 cMicroSecDuration )
-{
- uint64 dlCycles = ( ( uint64 ) cMicroSecDuration * g_ClockSpeed ) / ( uint64 ) 1000000L;
- CCycleCount cycleCount;
- cycleCount.Sample( );
- m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Determines whether our specified time period has passed
-// Output: true if at least the specified time period has passed
-//-----------------------------------------------------------------------------
-inline bool CLimitTimer::BLimitReached( )
-{
- CCycleCount cycleCount;
- cycleCount.Sample( );
- return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: If we're over our specified time period, return the amount of the overage.
-// Output: # of microseconds since we reached our specified time period.
-//-----------------------------------------------------------------------------
-inline int CLimitTimer::CMicroSecOverage()
-{
- CCycleCount cycleCount;
- cycleCount.Sample();
- uint64 lcCycles = cycleCount.GetLongCycles();
-
- if ( lcCycles < m_lCycleLimit )
- return 0;
-
- return( ( int ) ( ( lcCycles - m_lCycleLimit ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: If we're under our specified time period, return the amount under.
-// Output: # of microseconds until we reached our specified time period, 0 if we've passed it
-//-----------------------------------------------------------------------------
-inline uint64 CLimitTimer::CMicroSecLeft()
-{
- CCycleCount cycleCount;
- cycleCount.Sample();
- uint64 lcCycles = cycleCount.GetLongCycles();
-
- if ( lcCycles >= m_lCycleLimit )
- return 0;
-
- return( ( uint64 ) ( ( m_lCycleLimit - lcCycles ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
-}
-
-
-#endif // FASTTIMER_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef FASTTIMER_H
+#define FASTTIMER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifdef _WIN32
+#include <intrin.h>
+#endif
+
+#include <assert.h>
+#include "tier0/platform.h"
+
+PLATFORM_INTERFACE uint64 g_ClockSpeed;
+#if defined( _X360 ) && defined( _CERT )
+PLATFORM_INTERFACE unsigned long g_dwFakeFastCounter;
+#endif
+
+PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier;
+PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier;
+PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier;
+
+class CCycleCount
+{
+friend class CFastTimer;
+
+public:
+ CCycleCount();
+ CCycleCount( uint64 cycles );
+
+ void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900).
+
+ void Init(); // Set to zero.
+ void Init( float initTimeMsec );
+ void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); }
+ void Init( uint64 cycles );
+ bool IsLessThan( CCycleCount const &other ) const; // Compare two counts.
+
+ // Convert to other time representations. These functions are slow, so it's preferable to call them
+ // during display rather than inside a timing block.
+ unsigned long GetCycles() const;
+ uint64 GetLongCycles() const;
+
+ unsigned long GetMicroseconds() const;
+ uint64 GetUlMicroseconds() const;
+ double GetMicrosecondsF() const;
+ void SetMicroseconds( unsigned long nMicroseconds );
+
+ unsigned long GetMilliseconds() const;
+ double GetMillisecondsF() const;
+
+ double GetSeconds() const;
+
+ CCycleCount& operator+=( CCycleCount const &other );
+
+ // dest = rSrc1 + rSrc2
+ static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
+
+ // dest = rSrc1 - rSrc2
+ static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
+
+ static uint64 GetTimestamp();
+
+ uint64 m_Int64;
+};
+
+class PLATFORM_CLASS CClockSpeedInit
+{
+public:
+ CClockSpeedInit()
+ {
+ Init();
+ }
+
+ static void Init();
+};
+
+class CFastTimer
+{
+public:
+ // These functions are fast to call and should be called from your sampling code.
+ void Start();
+ void End();
+
+ const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls.
+ CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap.
+
+ // Return number of cycles per second on this processor.
+ static inline int64 GetClockSpeed();
+
+private:
+ CCycleCount m_Duration;
+#ifdef DEBUG_FASTTIMER
+ bool m_bRunning; // Are we currently running?
+#endif
+};
+
+
+// This is a helper class that times whatever block of code it's in
+class CTimeScope
+{
+public:
+ CTimeScope( CFastTimer *pTimer );
+ ~CTimeScope();
+
+private:
+ CFastTimer *m_pTimer;
+};
+
+inline CTimeScope::CTimeScope( CFastTimer *pTotal )
+{
+ m_pTimer = pTotal;
+ m_pTimer->Start();
+}
+
+inline CTimeScope::~CTimeScope()
+{
+ m_pTimer->End();
+}
+
+// This is a helper class that times whatever block of code it's in and
+// adds the total (int microseconds) to a global counter.
+class CTimeAdder
+{
+public:
+ CTimeAdder( CCycleCount *pTotal );
+ ~CTimeAdder();
+
+ void End();
+
+private:
+ CCycleCount *m_pTotal;
+ CFastTimer m_Timer;
+};
+
+inline CTimeAdder::CTimeAdder( CCycleCount *pTotal )
+{
+ m_pTotal = pTotal;
+ m_Timer.Start();
+}
+
+inline CTimeAdder::~CTimeAdder()
+{
+ End();
+}
+
+inline void CTimeAdder::End()
+{
+ if( m_pTotal )
+ {
+ m_Timer.End();
+ *m_pTotal += m_Timer.GetDuration();
+ m_pTotal = 0;
+ }
+}
+
+
+
+// -------------------------------------------------------------------------- //
+// Simple tool to support timing a block of code, and reporting the results on
+// program exit or at each iteration
+//
+// Macros used because dbg.h uses this header, thus Msg() is unavailable
+// -------------------------------------------------------------------------- //
+
+#define PROFILE_SCOPE(name) \
+ class C##name##ACC : public CAverageCycleCounter \
+ { \
+ public: \
+ ~C##name##ACC() \
+ { \
+ Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \
+ #name, \
+ GetAverageMilliseconds(), \
+ GetTotalMilliseconds(), \
+ GetPeakMilliseconds(), \
+ GetIters() ); \
+ } \
+ }; \
+ static C##name##ACC name##_ACC; \
+ CAverageTimeMarker name##_ATM( &name##_ACC )
+
+#define TIME_SCOPE(name) \
+ class CTimeScopeMsg_##name \
+ { \
+ public: \
+ CTimeScopeMsg_##name() { m_Timer.Start(); } \
+ ~CTimeScopeMsg_##name() \
+ { \
+ m_Timer.End(); \
+ Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \
+ } \
+ private: \
+ CFastTimer m_Timer; \
+ } name##_TSM;
+
+
+// -------------------------------------------------------------------------- //
+
+class CAverageCycleCounter
+{
+public:
+ CAverageCycleCounter();
+
+ void Init();
+ void MarkIter( const CCycleCount &duration );
+
+ unsigned GetIters() const;
+
+ double GetAverageMilliseconds() const;
+ double GetTotalMilliseconds() const;
+ double GetPeakMilliseconds() const;
+
+private:
+ unsigned m_nIters;
+ CCycleCount m_Total;
+ CCycleCount m_Peak;
+ bool m_fReport;
+ const tchar *m_pszName;
+};
+
+// -------------------------------------------------------------------------- //
+
+class CAverageTimeMarker
+{
+public:
+ CAverageTimeMarker( CAverageCycleCounter *pCounter );
+ ~CAverageTimeMarker();
+
+private:
+ CAverageCycleCounter *m_pCounter;
+ CFastTimer m_Timer;
+};
+
+
+// -------------------------------------------------------------------------- //
+// CCycleCount inlines.
+// -------------------------------------------------------------------------- //
+
+inline CCycleCount::CCycleCount()
+{
+ Init( (uint64)0 );
+}
+
+inline CCycleCount::CCycleCount( uint64 cycles )
+{
+ Init( cycles );
+}
+
+inline void CCycleCount::Init()
+{
+ Init( (uint64)0 );
+}
+
+inline void CCycleCount::Init( float initTimeMsec )
+{
+ if ( g_ClockSpeedMillisecondsMultiplier > 0 )
+ Init( (uint64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) );
+ else
+ Init( (uint64)0 );
+}
+
+inline void CCycleCount::Init( uint64 cycles )
+{
+ m_Int64 = cycles;
+}
+
+inline void CCycleCount::Sample()
+{
+ m_Int64 = Plat_Rdtsc();
+}
+
+inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other )
+{
+ m_Int64 += other.m_Int64;
+ return *this;
+}
+
+
+inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
+{
+ dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64;
+}
+
+inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
+{
+ dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64;
+}
+
+inline uint64 CCycleCount::GetTimestamp()
+{
+ CCycleCount c;
+ c.Sample();
+ return c.GetLongCycles();
+}
+
+inline bool CCycleCount::IsLessThan(CCycleCount const &other) const
+{
+ return m_Int64 < other.m_Int64;
+}
+
+
+inline unsigned long CCycleCount::GetCycles() const
+{
+ return (unsigned long)m_Int64;
+}
+
+inline uint64 CCycleCount::GetLongCycles() const
+{
+ return m_Int64;
+}
+
+inline unsigned long CCycleCount::GetMicroseconds() const
+{
+ return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed);
+}
+
+inline uint64 CCycleCount::GetUlMicroseconds() const
+{
+ return ((m_Int64 * 1000000) / g_ClockSpeed);
+}
+
+
+inline double CCycleCount::GetMicrosecondsF() const
+{
+ return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier );
+}
+
+
+inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds )
+{
+ m_Int64 = ((uint64)nMicroseconds * g_ClockSpeed) / 1000000;
+}
+
+
+inline unsigned long CCycleCount::GetMilliseconds() const
+{
+ return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed);
+}
+
+
+inline double CCycleCount::GetMillisecondsF() const
+{
+ return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier );
+}
+
+
+inline double CCycleCount::GetSeconds() const
+{
+ return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier );
+}
+
+
+// -------------------------------------------------------------------------- //
+// CFastTimer inlines.
+// -------------------------------------------------------------------------- //
+inline void CFastTimer::Start()
+{
+ m_Duration.Sample();
+#ifdef DEBUG_FASTTIMER
+ m_bRunning = true;
+#endif
+}
+
+
+inline void CFastTimer::End()
+{
+ CCycleCount cnt;
+ cnt.Sample();
+ if ( IsX360() )
+ {
+ // have to handle rollover, hires timer is only accurate to 32 bits
+ // more than one overflow should not have occurred, otherwise caller should use a slower timer
+ if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
+ {
+ // rollover occurred
+ cnt.m_Int64 += 0x100000000LL;
+ }
+ }
+
+ m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
+
+#ifdef DEBUG_FASTTIMER
+ m_bRunning = false;
+#endif
+}
+
+inline CCycleCount CFastTimer::GetDurationInProgress() const
+{
+ CCycleCount cnt;
+ cnt.Sample();
+ if ( IsX360() )
+ {
+ // have to handle rollover, hires timer is only accurate to 32 bits
+ // more than one overflow should not have occurred, otherwise caller should use a slower timer
+ if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
+ {
+ // rollover occurred
+ cnt.m_Int64 += 0x100000000LL;
+ }
+ }
+
+ CCycleCount result;
+ result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
+
+ return result;
+}
+
+
+inline int64 CFastTimer::GetClockSpeed()
+{
+ return g_ClockSpeed;
+}
+
+
+inline CCycleCount const& CFastTimer::GetDuration() const
+{
+#ifdef DEBUG_FASTTIMER
+ assert( !m_bRunning );
+#endif
+ return m_Duration;
+}
+
+
+// -------------------------------------------------------------------------- //
+// CAverageCycleCounter inlines
+
+inline CAverageCycleCounter::CAverageCycleCounter()
+ : m_nIters( 0 )
+{
+}
+
+inline void CAverageCycleCounter::Init()
+{
+ m_Total.Init();
+ m_Peak.Init();
+ m_nIters = 0;
+}
+
+inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration )
+{
+ ++m_nIters;
+ m_Total += duration;
+ if ( m_Peak.IsLessThan( duration ) )
+ m_Peak = duration;
+}
+
+inline unsigned CAverageCycleCounter::GetIters() const
+{
+ return m_nIters;
+}
+
+inline double CAverageCycleCounter::GetAverageMilliseconds() const
+{
+ if ( m_nIters )
+ return (m_Total.GetMillisecondsF() / (double)m_nIters);
+ else
+ return 0;
+}
+
+inline double CAverageCycleCounter::GetTotalMilliseconds() const
+{
+ return m_Total.GetMillisecondsF();
+}
+
+inline double CAverageCycleCounter::GetPeakMilliseconds() const
+{
+ return m_Peak.GetMillisecondsF();
+}
+
+// -------------------------------------------------------------------------- //
+
+inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter )
+{
+ m_pCounter = pCounter;
+ m_Timer.Start();
+}
+
+inline CAverageTimeMarker::~CAverageTimeMarker()
+{
+ m_Timer.End();
+ m_pCounter->MarkIter( m_Timer.GetDuration() );
+}
+
+
+// CLimitTimer
+// Use this to time whether a desired interval of time has passed. It's extremely fast
+// to check while running. NOTE: CMicroSecOverage() and CMicroSecLeft() are not as fast to check.
+class CLimitTimer
+{
+public:
+ CLimitTimer() {}
+ CLimitTimer( uint64 cMicroSecDuration ) { SetLimit( cMicroSecDuration ); }
+ void SetLimit( uint64 m_cMicroSecDuration );
+ bool BLimitReached();
+
+ int CMicroSecOverage();
+ uint64 CMicroSecLeft();
+
+private:
+ uint64 m_lCycleLimit;
+};
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Initializes the limit timer with a period of time to measure.
+// Input : cMicroSecDuration - How long a time period to measure
+//-----------------------------------------------------------------------------
+inline void CLimitTimer::SetLimit( uint64 cMicroSecDuration )
+{
+ uint64 dlCycles = ( ( uint64 ) cMicroSecDuration * g_ClockSpeed ) / ( uint64 ) 1000000L;
+ CCycleCount cycleCount;
+ cycleCount.Sample( );
+ m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Determines whether our specified time period has passed
+// Output: true if at least the specified time period has passed
+//-----------------------------------------------------------------------------
+inline bool CLimitTimer::BLimitReached( )
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample( );
+ return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: If we're over our specified time period, return the amount of the overage.
+// Output: # of microseconds since we reached our specified time period.
+//-----------------------------------------------------------------------------
+inline int CLimitTimer::CMicroSecOverage()
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample();
+ uint64 lcCycles = cycleCount.GetLongCycles();
+
+ if ( lcCycles < m_lCycleLimit )
+ return 0;
+
+ return( ( int ) ( ( lcCycles - m_lCycleLimit ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: If we're under our specified time period, return the amount under.
+// Output: # of microseconds until we reached our specified time period, 0 if we've passed it
+//-----------------------------------------------------------------------------
+inline uint64 CLimitTimer::CMicroSecLeft()
+{
+ CCycleCount cycleCount;
+ cycleCount.Sample();
+ uint64 lcCycles = cycleCount.GetLongCycles();
+
+ if ( lcCycles >= m_lCycleLimit )
+ return 0;
+
+ return( ( uint64 ) ( ( m_lCycleLimit - lcCycles ) * ( uint64 ) 1000000L / g_ClockSpeed ) );
+}
+
+
+#endif // FASTTIMER_H
diff --git a/sp/src/public/tier0/ia32detect.h b/sp/src/public/tier0/ia32detect.h
index 1a91fe6f..dd603d17 100644
--- a/sp/src/public/tier0/ia32detect.h
+++ b/sp/src/public/tier0/ia32detect.h
@@ -1,377 +1,377 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef IA32DETECT_H
-#define IA32DETECT_H
-
-#ifdef PLATFORM_WINDOWS_PC
-#include <intrin.h>
-#endif
-
-/*
- This section from http://iss.cs.cornell.edu/ia32.htm
-
-
- */
-typedef unsigned bit;
-
-enum CPUVendor
-{
- INTEL,
- AMD,
- UNKNOWN_VENDOR
-};
-class ia32detect
-{
-public:
-
- enum type_t
- {
- type_OEM,
- type_OverDrive,
- type_Dual,
- type_reserved
- };
-
- enum brand_t
- {
- brand_na,
- brand_Celeron,
- brand_PentiumIII,
- brand_PentiumIIIXeon,
- brand_reserved1,
- brand_reserved2,
- brand_PentiumIIIMobile,
- brand_reserved3,
- brand_Pentium4,
- brand_invalid
- };
-
-# pragma pack(push, 1)
-
- struct version_t
- {
- bit Stepping : 4;
- bit Model : 4;
- bit Family : 4;
- bit Type : 2;
- bit Reserved1 : 2;
- bit XModel : 4;
- bit XFamily : 8;
- bit Reserved2 : 4;
- };
-
- struct misc_t
- {
- byte Brand;
- byte CLFLUSH;
- byte Reserved;
- byte APICId;
- };
-
- struct feature_t
- {
- bit FPU : 1; // Floating Point Unit On-Chip
- bit VME : 1; // Virtual 8086 Mode Enhancements
- bit DE : 1; // Debugging Extensions
- bit PSE : 1; // Page Size Extensions
- bit TSC : 1; // Time Stamp Counter
- bit MSR : 1; // Model Specific Registers
- bit PAE : 1; // Physical Address Extension
- bit MCE : 1; // Machine Check Exception
- bit CX8 : 1; // CMPXCHG8 Instruction
- bit APIC : 1; // APIC On-Chip
- bit Reserved1 : 1;
- bit SEP : 1; // SYSENTER and SYSEXIT instructions
- bit MTRR : 1; // Memory Type Range Registers
- bit PGE : 1; // PTE Global Bit
- bit MCA : 1; // Machine Check Architecture
- bit CMOV : 1; // Conditional Move Instructions
- bit PAT : 1; // Page Attribute Table
- bit PSE36 : 1; // 32-bit Page Size Extension
- bit PSN : 1; // Processor Serial Number
- bit CLFSH : 1; // CLFLUSH Instruction
- bit Reserved2 : 1;
- bit DS : 1; // Debug Store
- bit ACPI : 1; // Thermal Monitor and Software Controlled Clock Facilities
- bit MMX : 1; // Intel MMX Technology
- bit FXSR : 1; // FXSAVE and FXRSTOR Instructions
- bit SSE : 1; // Intel SSE Technology
- bit SSE2 : 1; // Intel SSE2 Technology
- bit SS : 1; // Self Snoop
- bit HTT : 1; // Hyper Threading
- bit TM : 1; // Thermal Monitor
- bit Reserved3 : 1;
- bit PBE : 1; // Pending Brk. EN.
- };
-
-# pragma pack(pop)
-
- tstring vendor_name;
- CPUVendor vendor;
- tstring brand;
- version_t version;
- misc_t misc;
- feature_t feature;
- byte *cache;
-
- ia32detect ()
- {
-
- cache = 0;
- uint32 m = init0();
-
- uint32 *d = new uint32[m * 4];
-
- for (uint32 i = 1; i <= m; i++)
- {
-#ifdef COMPILER_MSVC64
- __cpuid((int *) (d + (i-1) * 4), i);
-
-#else
- uint32 *t = d + (i - 1) * 4;
-
- __asm
- {
- mov eax, i;
- mov esi, t;
-
- cpuid;
-
- mov dword ptr [esi + 0x0], eax;
- mov dword ptr [esi + 0x4], ebx;
- mov dword ptr [esi + 0x8], ecx;
- mov dword ptr [esi + 0xC], edx;
- }
-#endif
- }
-
- if (m >= 1)
- init1(d);
-
- if (m >= 2)
- init2(d[4] & 0xFF);
-
- delete [] d;
-
- init0x80000000();
-
-
- //-----------------------------------------------------------------------
- // Get the vendor of the processor
- //-----------------------------------------------------------------------
- if (_tcscmp(vendor_name.c_str(), _T("GenuineIntel")) == 0)
- {
- vendor = INTEL;
-
- }
- else if (_tcscmp(vendor_name.c_str(), _T("AuthenticAMD")) == 0)
- {
- vendor = AMD;
-
- }
- else
- {
- vendor = UNKNOWN_VENDOR;
- }
- }
-
- const tstring version_text () const
- {
- tchar b[128];
-
- _stprintf(b, _T("%d.%d.%d %s XVersion(%d.%d)"),
- version.Family, version.Model, version.Stepping, type_text(), version.XFamily, version.XModel);
-
- return tstring(b);
- }
-
-protected:
-
- const tchar * type_text () const
- {
- static const tchar *text[] =
- {
- _T("Intel OEM Processor"),
- _T("Intel OverDrive(R) Processor"),
- _T("Intel Dual Processor"),
- _T("reserved")
- };
-
- return text[version.Type];
- }
-
- const tstring brand_text () const
- {
- static const tchar *text[] =
- {
- _T("n/a"),
- _T("Celeron"),
- _T("Pentium III"),
- _T("Pentium III Xeon"),
- _T("reserved (4)"),
- _T("reserved (5)"),
- _T("Pentium III Mobile"),
- _T("reserved (7)"),
- _T("Pentium 4")
- };
-
- if (misc.Brand < brand_invalid)
- return tstring(text[misc.Brand]);
- else
- {
- tchar b[32];
-
- _stprintf(b, _T("Brand %d (Update)"), misc.Brand);
-
- return tstring(b);
- }
- }
-
-private:
-
- uint32 init0 ()
- {
- uint32 m;
-
- int data[4 + 1];
- tchar * s1;
-
- s1 = (tchar *) &data[1];
- __cpuid(data, 0);
- data[4] = 0;
- // Returns something like this:
- // data[0] = 0x0000000b
- // data[1] = 0x756e6547 Genu
- // data[2] = 0x6c65746e ntel
- // data[3] = 0x49656e69 ineI
- // data[4] = 0x00000000
-
- m = data[0];
- int t = data[2];
- data[2] = data[3];
- data[3] = t;
- vendor_name = s1;
- return m;
- }
-
- void init1 (uint32 *d)
- {
- version = *(version_t *)&d[0];
- misc = *(misc_t *)&d[1];
- feature = *(feature_t *)&d[3];
- }
-
- void process2 (uint32 d, bool c[])
- {
- if ((d & 0x80000000) == 0)
- for (int i = 0; i < 32; i += 8)
- c[(d >> i) & 0xFF] = true;
- }
-
- void init2 (byte count)
- {
- uint32 d[4];
- bool c[256];
-
- for (int ci1 = 0; ci1 < 256; ci1++)
- c[ci1] = false;
-
- for (int i = 0; i < count; i++)
- {
-#ifdef COMPILER_MSVC64
- __cpuid((int *) d, 2);
-#else
- __asm
- {
- mov eax, 2;
- lea esi, d;
- cpuid;
- mov [esi + 0x0], eax;
- mov [esi + 0x4], ebx;
- mov [esi + 0x8], ecx;
- mov [esi + 0xC], edx;
- }
-#endif
-
- if (i == 0)
- d[0] &= 0xFFFFFF00;
-
- process2(d[0], c);
- process2(d[1], c);
- process2(d[2], c);
- process2(d[3], c);
- }
-
- int m = 0;
-
- for (int ci2 = 0; ci2 < 256; ci2++)
- if (c[ci2])
- m++;
-
- cache = new byte[m];
-
- m = 0;
-
- for (int ci3 = 1; ci3 < 256; ci3++)
- if (c[ci3])
- cache[m++] = ci3;
-
- cache[m] = 0;
- }
-
- void init0x80000000 ()
- {
- uint32 m;
-
-#ifdef COMPILER_MSVC64
- int data[4];
- __cpuid(data, 0x80000000);
- m = data[0];
-#else
- __asm
- {
- mov eax, 0x80000000;
- cpuid;
- mov m, eax
- }
-#endif
-
- if ((m & 0x80000000) != 0)
- {
- uint32 *d = new uint32[(m - 0x80000000) * 4];
-
- for (uint32 i = 0x80000001; i <= m; i++)
- {
- uint32 *t = d + (i - 0x80000001) * 4;
-
-#ifdef COMPILER_MSVC64
- __cpuid((int *) (d + (i - 0x80000001) * 4), i);
-#else
- __asm
- {
- mov eax, i;
- mov esi, t;
- cpuid;
- mov dword ptr [esi + 0x0], eax;
- mov dword ptr [esi + 0x4], ebx;
- mov dword ptr [esi + 0x8], ecx;
- mov dword ptr [esi + 0xC], edx;
- }
-#endif
- }
-
- if (m >= 0x80000002)
- brand = (tchar *)(d + 4);
-
- // note the assignment to brand above does a copy, we need to delete
- delete[] d;
- }
- }
-};
-
-#endif // IA32DETECT_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef IA32DETECT_H
+#define IA32DETECT_H
+
+#ifdef PLATFORM_WINDOWS_PC
+#include <intrin.h>
+#endif
+
+/*
+ This section from http://iss.cs.cornell.edu/ia32.htm
+
+
+ */
+typedef unsigned bit;
+
+enum CPUVendor
+{
+ INTEL,
+ AMD,
+ UNKNOWN_VENDOR
+};
+class ia32detect
+{
+public:
+
+ enum type_t
+ {
+ type_OEM,
+ type_OverDrive,
+ type_Dual,
+ type_reserved
+ };
+
+ enum brand_t
+ {
+ brand_na,
+ brand_Celeron,
+ brand_PentiumIII,
+ brand_PentiumIIIXeon,
+ brand_reserved1,
+ brand_reserved2,
+ brand_PentiumIIIMobile,
+ brand_reserved3,
+ brand_Pentium4,
+ brand_invalid
+ };
+
+# pragma pack(push, 1)
+
+ struct version_t
+ {
+ bit Stepping : 4;
+ bit Model : 4;
+ bit Family : 4;
+ bit Type : 2;
+ bit Reserved1 : 2;
+ bit XModel : 4;
+ bit XFamily : 8;
+ bit Reserved2 : 4;
+ };
+
+ struct misc_t
+ {
+ byte Brand;
+ byte CLFLUSH;
+ byte Reserved;
+ byte APICId;
+ };
+
+ struct feature_t
+ {
+ bit FPU : 1; // Floating Point Unit On-Chip
+ bit VME : 1; // Virtual 8086 Mode Enhancements
+ bit DE : 1; // Debugging Extensions
+ bit PSE : 1; // Page Size Extensions
+ bit TSC : 1; // Time Stamp Counter
+ bit MSR : 1; // Model Specific Registers
+ bit PAE : 1; // Physical Address Extension
+ bit MCE : 1; // Machine Check Exception
+ bit CX8 : 1; // CMPXCHG8 Instruction
+ bit APIC : 1; // APIC On-Chip
+ bit Reserved1 : 1;
+ bit SEP : 1; // SYSENTER and SYSEXIT instructions
+ bit MTRR : 1; // Memory Type Range Registers
+ bit PGE : 1; // PTE Global Bit
+ bit MCA : 1; // Machine Check Architecture
+ bit CMOV : 1; // Conditional Move Instructions
+ bit PAT : 1; // Page Attribute Table
+ bit PSE36 : 1; // 32-bit Page Size Extension
+ bit PSN : 1; // Processor Serial Number
+ bit CLFSH : 1; // CLFLUSH Instruction
+ bit Reserved2 : 1;
+ bit DS : 1; // Debug Store
+ bit ACPI : 1; // Thermal Monitor and Software Controlled Clock Facilities
+ bit MMX : 1; // Intel MMX Technology
+ bit FXSR : 1; // FXSAVE and FXRSTOR Instructions
+ bit SSE : 1; // Intel SSE Technology
+ bit SSE2 : 1; // Intel SSE2 Technology
+ bit SS : 1; // Self Snoop
+ bit HTT : 1; // Hyper Threading
+ bit TM : 1; // Thermal Monitor
+ bit Reserved3 : 1;
+ bit PBE : 1; // Pending Brk. EN.
+ };
+
+# pragma pack(pop)
+
+ tstring vendor_name;
+ CPUVendor vendor;
+ tstring brand;
+ version_t version;
+ misc_t misc;
+ feature_t feature;
+ byte *cache;
+
+ ia32detect ()
+ {
+
+ cache = 0;
+ uint32 m = init0();
+
+ uint32 *d = new uint32[m * 4];
+
+ for (uint32 i = 1; i <= m; i++)
+ {
+#ifdef COMPILER_MSVC64
+ __cpuid((int *) (d + (i-1) * 4), i);
+
+#else
+ uint32 *t = d + (i - 1) * 4;
+
+ __asm
+ {
+ mov eax, i;
+ mov esi, t;
+
+ cpuid;
+
+ mov dword ptr [esi + 0x0], eax;
+ mov dword ptr [esi + 0x4], ebx;
+ mov dword ptr [esi + 0x8], ecx;
+ mov dword ptr [esi + 0xC], edx;
+ }
+#endif
+ }
+
+ if (m >= 1)
+ init1(d);
+
+ if (m >= 2)
+ init2(d[4] & 0xFF);
+
+ delete [] d;
+
+ init0x80000000();
+
+
+ //-----------------------------------------------------------------------
+ // Get the vendor of the processor
+ //-----------------------------------------------------------------------
+ if (_tcscmp(vendor_name.c_str(), _T("GenuineIntel")) == 0)
+ {
+ vendor = INTEL;
+
+ }
+ else if (_tcscmp(vendor_name.c_str(), _T("AuthenticAMD")) == 0)
+ {
+ vendor = AMD;
+
+ }
+ else
+ {
+ vendor = UNKNOWN_VENDOR;
+ }
+ }
+
+ const tstring version_text () const
+ {
+ tchar b[128];
+
+ _stprintf(b, _T("%d.%d.%d %s XVersion(%d.%d)"),
+ version.Family, version.Model, version.Stepping, type_text(), version.XFamily, version.XModel);
+
+ return tstring(b);
+ }
+
+protected:
+
+ const tchar * type_text () const
+ {
+ static const tchar *text[] =
+ {
+ _T("Intel OEM Processor"),
+ _T("Intel OverDrive(R) Processor"),
+ _T("Intel Dual Processor"),
+ _T("reserved")
+ };
+
+ return text[version.Type];
+ }
+
+ const tstring brand_text () const
+ {
+ static const tchar *text[] =
+ {
+ _T("n/a"),
+ _T("Celeron"),
+ _T("Pentium III"),
+ _T("Pentium III Xeon"),
+ _T("reserved (4)"),
+ _T("reserved (5)"),
+ _T("Pentium III Mobile"),
+ _T("reserved (7)"),
+ _T("Pentium 4")
+ };
+
+ if (misc.Brand < brand_invalid)
+ return tstring(text[misc.Brand]);
+ else
+ {
+ tchar b[32];
+
+ _stprintf(b, _T("Brand %d (Update)"), misc.Brand);
+
+ return tstring(b);
+ }
+ }
+
+private:
+
+ uint32 init0 ()
+ {
+ uint32 m;
+
+ int data[4 + 1];
+ tchar * s1;
+
+ s1 = (tchar *) &data[1];
+ __cpuid(data, 0);
+ data[4] = 0;
+ // Returns something like this:
+ // data[0] = 0x0000000b
+ // data[1] = 0x756e6547 Genu
+ // data[2] = 0x6c65746e ntel
+ // data[3] = 0x49656e69 ineI
+ // data[4] = 0x00000000
+
+ m = data[0];
+ int t = data[2];
+ data[2] = data[3];
+ data[3] = t;
+ vendor_name = s1;
+ return m;
+ }
+
+ void init1 (uint32 *d)
+ {
+ version = *(version_t *)&d[0];
+ misc = *(misc_t *)&d[1];
+ feature = *(feature_t *)&d[3];
+ }
+
+ void process2 (uint32 d, bool c[])
+ {
+ if ((d & 0x80000000) == 0)
+ for (int i = 0; i < 32; i += 8)
+ c[(d >> i) & 0xFF] = true;
+ }
+
+ void init2 (byte count)
+ {
+ uint32 d[4];
+ bool c[256];
+
+ for (int ci1 = 0; ci1 < 256; ci1++)
+ c[ci1] = false;
+
+ for (int i = 0; i < count; i++)
+ {
+#ifdef COMPILER_MSVC64
+ __cpuid((int *) d, 2);
+#else
+ __asm
+ {
+ mov eax, 2;
+ lea esi, d;
+ cpuid;
+ mov [esi + 0x0], eax;
+ mov [esi + 0x4], ebx;
+ mov [esi + 0x8], ecx;
+ mov [esi + 0xC], edx;
+ }
+#endif
+
+ if (i == 0)
+ d[0] &= 0xFFFFFF00;
+
+ process2(d[0], c);
+ process2(d[1], c);
+ process2(d[2], c);
+ process2(d[3], c);
+ }
+
+ int m = 0;
+
+ for (int ci2 = 0; ci2 < 256; ci2++)
+ if (c[ci2])
+ m++;
+
+ cache = new byte[m];
+
+ m = 0;
+
+ for (int ci3 = 1; ci3 < 256; ci3++)
+ if (c[ci3])
+ cache[m++] = ci3;
+
+ cache[m] = 0;
+ }
+
+ void init0x80000000 ()
+ {
+ uint32 m;
+
+#ifdef COMPILER_MSVC64
+ int data[4];
+ __cpuid(data, 0x80000000);
+ m = data[0];
+#else
+ __asm
+ {
+ mov eax, 0x80000000;
+ cpuid;
+ mov m, eax
+ }
+#endif
+
+ if ((m & 0x80000000) != 0)
+ {
+ uint32 *d = new uint32[(m - 0x80000000) * 4];
+
+ for (uint32 i = 0x80000001; i <= m; i++)
+ {
+ uint32 *t = d + (i - 0x80000001) * 4;
+
+#ifdef COMPILER_MSVC64
+ __cpuid((int *) (d + (i - 0x80000001) * 4), i);
+#else
+ __asm
+ {
+ mov eax, i;
+ mov esi, t;
+ cpuid;
+ mov dword ptr [esi + 0x0], eax;
+ mov dword ptr [esi + 0x4], ebx;
+ mov dword ptr [esi + 0x8], ecx;
+ mov dword ptr [esi + 0xC], edx;
+ }
+#endif
+ }
+
+ if (m >= 0x80000002)
+ brand = (tchar *)(d + 4);
+
+ // note the assignment to brand above does a copy, we need to delete
+ delete[] d;
+ }
+ }
+};
+
+#endif // IA32DETECT_H
diff --git a/sp/src/public/tier0/icommandline.h b/sp/src/public/tier0/icommandline.h
index abe21340..cbe9cb59 100644
--- a/sp/src/public/tier0/icommandline.h
+++ b/sp/src/public/tier0/icommandline.h
@@ -1,57 +1,57 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//===========================================================================//
-
-#ifndef TIER0_ICOMMANDLINE_H
-#define TIER0_ICOMMANDLINE_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Interface to engine command line
-//-----------------------------------------------------------------------------
-abstract_class ICommandLine
-{
-public:
- virtual void CreateCmdLine( const char *commandline ) = 0;
- virtual void CreateCmdLine( int argc, char **argv ) = 0;
- virtual const char *GetCmdLine( void ) const = 0;
-
- // Check whether a particular parameter exists
- virtual const char *CheckParm( const char *psz, const char **ppszValue = 0 ) const = 0;
- virtual void RemoveParm( const char *parm ) = 0;
- virtual void AppendParm( const char *pszParm, const char *pszValues ) = 0;
-
- // Returns the argument after the one specified, or the default if not found
- virtual const char *ParmValue( const char *psz, const char *pDefaultVal = 0 ) const = 0;
- virtual int ParmValue( const char *psz, int nDefaultVal ) const = 0;
- virtual float ParmValue( const char *psz, float flDefaultVal ) const = 0;
-
- // Gets at particular parameters
- virtual int ParmCount() const = 0;
- virtual int FindParm( const char *psz ) const = 0; // Returns 0 if not found.
- virtual const char* GetParm( int nIndex ) const = 0;
-
- // copies the string passwed
- virtual void SetParm( int nIndex, char const *pNewParm ) =0;
-};
-
-//-----------------------------------------------------------------------------
-// Gets a singleton to the commandline interface
-// NOTE: The #define trickery here is necessary for backwards compat:
-// this interface used to lie in the vstdlib library.
-//-----------------------------------------------------------------------------
-PLATFORM_INTERFACE ICommandLine *CommandLine_Tier0();
-
-#if !defined( VSTDLIB_BACKWARD_COMPAT )
-#define CommandLine CommandLine_Tier0
-#endif
-
-#endif // TIER0_ICOMMANDLINE_H
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//===========================================================================//
+
+#ifndef TIER0_ICOMMANDLINE_H
+#define TIER0_ICOMMANDLINE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Interface to engine command line
+//-----------------------------------------------------------------------------
+abstract_class ICommandLine
+{
+public:
+ virtual void CreateCmdLine( const char *commandline ) = 0;
+ virtual void CreateCmdLine( int argc, char **argv ) = 0;
+ virtual const char *GetCmdLine( void ) const = 0;
+
+ // Check whether a particular parameter exists
+ virtual const char *CheckParm( const char *psz, const char **ppszValue = 0 ) const = 0;
+ virtual void RemoveParm( const char *parm ) = 0;
+ virtual void AppendParm( const char *pszParm, const char *pszValues ) = 0;
+
+ // Returns the argument after the one specified, or the default if not found
+ virtual const char *ParmValue( const char *psz, const char *pDefaultVal = 0 ) const = 0;
+ virtual int ParmValue( const char *psz, int nDefaultVal ) const = 0;
+ virtual float ParmValue( const char *psz, float flDefaultVal ) const = 0;
+
+ // Gets at particular parameters
+ virtual int ParmCount() const = 0;
+ virtual int FindParm( const char *psz ) const = 0; // Returns 0 if not found.
+ virtual const char* GetParm( int nIndex ) const = 0;
+
+ // copies the string passwed
+ virtual void SetParm( int nIndex, char const *pNewParm ) =0;
+};
+
+//-----------------------------------------------------------------------------
+// Gets a singleton to the commandline interface
+// NOTE: The #define trickery here is necessary for backwards compat:
+// this interface used to lie in the vstdlib library.
+//-----------------------------------------------------------------------------
+PLATFORM_INTERFACE ICommandLine *CommandLine_Tier0();
+
+#if !defined( VSTDLIB_BACKWARD_COMPAT )
+#define CommandLine CommandLine_Tier0
+#endif
+
+#endif // TIER0_ICOMMANDLINE_H
+
diff --git a/sp/src/public/tier0/l2cache.h b/sp/src/public/tier0/l2cache.h
index 74d7cc78..2ee88331 100644
--- a/sp/src/public/tier0/l2cache.h
+++ b/sp/src/public/tier0/l2cache.h
@@ -1,46 +1,46 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-#ifndef CL2CACHE_H
-#define CL2CACHE_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-class P4Event_BSQ_cache_reference;
-
-class CL2Cache
-{
-public:
-
- CL2Cache();
- ~CL2Cache();
-
- void Start( void );
- void End( void );
-
- //-------------------------------------------------------------------------
- // GetL2CacheMisses
- //-------------------------------------------------------------------------
- int GetL2CacheMisses( void )
- {
- return m_iL2CacheMissCount;
- }
-
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-#endif // DBGFLAG_VALIDATE
-
-private:
-
- int m_nID;
-
- P4Event_BSQ_cache_reference *m_pL2CacheEvent;
- int64 m_i64Start;
- int64 m_i64End;
- int m_iL2CacheMissCount;
-};
-
-#endif // CL2CACHE_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#ifndef CL2CACHE_H
+#define CL2CACHE_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+class P4Event_BSQ_cache_reference;
+
+class CL2Cache
+{
+public:
+
+ CL2Cache();
+ ~CL2Cache();
+
+ void Start( void );
+ void End( void );
+
+ //-------------------------------------------------------------------------
+ // GetL2CacheMisses
+ //-------------------------------------------------------------------------
+ int GetL2CacheMisses( void )
+ {
+ return m_iL2CacheMissCount;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+#endif // DBGFLAG_VALIDATE
+
+private:
+
+ int m_nID;
+
+ P4Event_BSQ_cache_reference *m_pL2CacheEvent;
+ int64 m_i64Start;
+ int64 m_i64End;
+ int m_iL2CacheMissCount;
+};
+
+#endif // CL2CACHE_H
diff --git a/sp/src/public/tier0/mem.h b/sp/src/public/tier0/mem.h
index 90434b85..fc8807ac 100644
--- a/sp/src/public/tier0/mem.h
+++ b/sp/src/public/tier0/mem.h
@@ -1,50 +1,50 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Memory allocation!
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef TIER0_MEM_H
-#define TIER0_MEM_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include <stddef.h>
-#ifdef LINUX
-#undef offsetof
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#endif
-
-#include "tier0/platform.h"
-
-#if !defined(STATIC_TIER0) && !defined(_STATIC_LINKED)
-
-#ifdef TIER0_DLL_EXPORT
-# define MEM_INTERFACE DLL_EXPORT
-#else
-# define MEM_INTERFACE DLL_IMPORT
-#endif
-
-#else // BUILD_AS_DLL
-
-#define MEM_INTERFACE extern
-
-#endif // BUILD_AS_DLL
-
-
-
-//-----------------------------------------------------------------------------
-// DLL-exported methods for particular kinds of memory
-//-----------------------------------------------------------------------------
-MEM_INTERFACE void *MemAllocScratch( int nMemSize );
-MEM_INTERFACE void MemFreeScratch();
-
-#ifdef _LINUX
-MEM_INTERFACE void ZeroMemory( void *mem, size_t length );
-#endif
-
-
-#endif /* TIER0_MEM_H */
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Memory allocation!
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef TIER0_MEM_H
+#define TIER0_MEM_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include <stddef.h>
+#ifdef LINUX
+#undef offsetof
+#define offsetof(s,m) (size_t)&(((s *)0)->m)
+#endif
+
+#include "tier0/platform.h"
+
+#if !defined(STATIC_TIER0) && !defined(_STATIC_LINKED)
+
+#ifdef TIER0_DLL_EXPORT
+# define MEM_INTERFACE DLL_EXPORT
+#else
+# define MEM_INTERFACE DLL_IMPORT
+#endif
+
+#else // BUILD_AS_DLL
+
+#define MEM_INTERFACE extern
+
+#endif // BUILD_AS_DLL
+
+
+
+//-----------------------------------------------------------------------------
+// DLL-exported methods for particular kinds of memory
+//-----------------------------------------------------------------------------
+MEM_INTERFACE void *MemAllocScratch( int nMemSize );
+MEM_INTERFACE void MemFreeScratch();
+
+#ifdef _LINUX
+MEM_INTERFACE void ZeroMemory( void *mem, size_t length );
+#endif
+
+
+#endif /* TIER0_MEM_H */
diff --git a/sp/src/public/tier0/memalloc.h b/sp/src/public/tier0/memalloc.h
index 2840d095..e0f9c16a 100644
--- a/sp/src/public/tier0/memalloc.h
+++ b/sp/src/public/tier0/memalloc.h
@@ -1,654 +1,654 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This header should never be used directly from leaf code!!!
-// Instead, just add the file memoverride.cpp into your project and all this
-// will automagically be used
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef TIER0_MEMALLOC_H
-#define TIER0_MEMALLOC_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-// These memory debugging switches aren't relevant under Linux builds since memoverride.cpp
-// isn't built into Linux projects
-#ifndef POSIX
-// Define this in release to get memory tracking even in release builds
-//#define USE_MEM_DEBUG 1
-#endif
-
-#if defined( _MEMTEST )
-#ifdef _WIN32
-#define USE_MEM_DEBUG 1
-#endif
-#endif
-
-// Undefine this if using a compiler lacking threadsafe RTTI (like vc6)
-#define MEM_DEBUG_CLASSNAME 1
-
-#include <stddef.h>
-#if defined( OSX )
-#include <malloc/malloc.h>
-#endif
-
-#include "tier0/mem.h"
-
-#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
-
-struct _CrtMemState;
-
-#define MEMALLOC_VERSION 1
-
-typedef size_t (*MemAllocFailHandler_t)( size_t );
-
-//-----------------------------------------------------------------------------
-// NOTE! This should never be called directly from leaf code
-// Just use new,delete,malloc,free etc. They will call into this eventually
-//-----------------------------------------------------------------------------
-abstract_class IMemAlloc
-{
-public:
- // Release versions
- virtual void *Alloc( size_t nSize ) = 0;
- virtual void *Realloc( void *pMem, size_t nSize ) = 0;
- virtual void Free( void *pMem ) = 0;
- virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0;
-
- // Debug versions
- virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0;
- virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
- virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0;
- virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
-
- // Returns size of a particular allocation
- virtual size_t GetSize( void *pMem ) = 0;
-
- // Force file + line information for an allocation
- virtual void PushAllocDbgInfo( const char *pFileName, int nLine ) = 0;
- virtual void PopAllocDbgInfo() = 0;
-
- // FIXME: Remove when we have our own allocator
- // these methods of the Crt debug code is used in our codebase currently
- virtual long CrtSetBreakAlloc( long lNewBreakAlloc ) = 0;
- virtual int CrtSetReportMode( int nReportType, int nReportMode ) = 0;
- virtual int CrtIsValidHeapPointer( const void *pMem ) = 0;
- virtual int CrtIsValidPointer( const void *pMem, unsigned int size, int access ) = 0;
- virtual int CrtCheckMemory( void ) = 0;
- virtual int CrtSetDbgFlag( int nNewFlag ) = 0;
- virtual void CrtMemCheckpoint( _CrtMemState *pState ) = 0;
-
- // FIXME: Make a better stats interface
- virtual void DumpStats() = 0;
- virtual void DumpStatsFileBase( char const *pchFileBase ) = 0;
-
- // FIXME: Remove when we have our own allocator
- virtual void* CrtSetReportFile( int nRptType, void* hFile ) = 0;
- virtual void* CrtSetReportHook( void* pfnNewHook ) = 0;
- virtual int CrtDbgReport( int nRptType, const char * szFile,
- int nLine, const char * szModule, const char * pMsg ) = 0;
-
- virtual int heapchk() = 0;
-
- virtual bool IsDebugHeap() = 0;
-
- virtual void GetActualDbgInfo( const char *&pFileName, int &nLine ) = 0;
- virtual void RegisterAllocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
- virtual void RegisterDeallocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
-
- virtual int GetVersion() = 0;
-
- virtual void CompactHeap() = 0;
-
- // Function called when malloc fails or memory limits hit to attempt to free up memory (can come in any thread)
- virtual MemAllocFailHandler_t SetAllocFailHandler( MemAllocFailHandler_t pfnMemAllocFailHandler ) = 0;
-
- virtual void DumpBlockStats( void * ) = 0;
-
-#if defined( _MEMTEST )
- virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0;
-#endif
-
- // Returns 0 if no failure, otherwise the size_t of the last requested chunk
- // "I'm sure this is completely thread safe!" Brian Deen 7/19/2012.
- virtual size_t MemoryAllocFailed() = 0;
-
- // handles storing allocation info for coroutines
- virtual uint32 GetDebugInfoSize() = 0;
- virtual void SaveDebugInfo( void *pvDebugInfo ) = 0;
- virtual void RestoreDebugInfo( const void *pvDebugInfo ) = 0;
- virtual void InitDebugInfo( void *pvDebugInfo, const char *pchRootFileName, int nLine ) = 0;
-
- // Replacement for ::GlobalMemoryStatus which accounts for unused memory in our system
- virtual void GlobalMemoryStatus( size_t *pUsedMemory, size_t *pFreeMemory ) = 0;
-};
-
-//-----------------------------------------------------------------------------
-// Singleton interface
-//-----------------------------------------------------------------------------
-MEM_INTERFACE IMemAlloc *g_pMemAlloc;
-
-//-----------------------------------------------------------------------------
-
-#ifdef MEMALLOC_REGIONS
-#ifndef MEMALLOC_REGION
-#define MEMALLOC_REGION 0
-#endif
-inline void *MemAlloc_Alloc( size_t nSize )
-{
- return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize );
-}
-
-inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize, pFileName, nLine );
-}
-#else
-#undef MEMALLOC_REGION
-inline void *MemAlloc_Alloc( size_t nSize )
-{
- return g_pMemAlloc->Alloc( nSize );
-}
-
-inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->Alloc( nSize, pFileName, nLine );
-}
-#endif
-inline void MemAlloc_Free( void *ptr )
-{
- g_pMemAlloc->Free( ptr );
-}
-inline void MemAlloc_Free( void *ptr, const char *pFileName, int nLine )
-{
- g_pMemAlloc->Free( ptr, pFileName, nLine );
-}
-
-//-----------------------------------------------------------------------------
-
-inline bool ValueIsPowerOfTwo( size_t value ) // don't clash with mathlib definition
-{
- return (value & ( value - 1 )) == 0;
-}
-
-inline void *MemAlloc_AllocAligned( size_t size, size_t align )
-{
- unsigned char *pAlloc, *pResult;
-
- if (!IsPowerOfTwo(align))
- return NULL;
-
- align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
-
- if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
- return NULL;
-
- pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
- ((unsigned char**)(pResult))[-1] = pAlloc;
-
- return (void *)pResult;
-}
-
-inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile, int nLine )
-{
- unsigned char *pAlloc, *pResult;
-
- if (!IsPowerOfTwo(align))
- return NULL;
-
- align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
-
- if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
- return NULL;
-
- pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
- ((unsigned char**)(pResult))[-1] = pAlloc;
-
- return (void *)pResult;
-}
-
-inline void *MemAlloc_AllocAlignedUnattributed( size_t size, size_t align )
-{
- unsigned char *pAlloc, *pResult;
-
- if (!ValueIsPowerOfTwo(align))
- return NULL;
-
- align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
-
- if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
- return NULL;
-
- pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
- ((unsigned char**)(pResult))[-1] = pAlloc;
-
- return (void *)pResult;
-}
-
-inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile, int nLine )
-{
- unsigned char *pAlloc, *pResult;
-
- if (!ValueIsPowerOfTwo(align))
- return NULL;
-
- align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
-
- if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
- return NULL;
-
- pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
- ((unsigned char**)(pResult))[-1] = pAlloc;
-
- return (void *)pResult;
-}
-
-inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
-{
- if ( !IsPowerOfTwo( align ) )
- return NULL;
-
- // Don't change alignment between allocation + reallocation.
- if ( ( (size_t)ptr & ( align - 1 ) ) != 0 )
- return NULL;
-
- if ( !ptr )
- return MemAlloc_AllocAligned( size, align );
-
- void *pAlloc, *pResult;
-
- // Figure out the actual allocation point
- pAlloc = ptr;
- pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
- pAlloc = *( (void **)pAlloc );
-
- // See if we have enough space
- size_t nOffset = (size_t)ptr - (size_t)pAlloc;
- size_t nOldSize = g_pMemAlloc->GetSize( pAlloc );
- if ( nOldSize >= size + nOffset )
- return ptr;
-
- pResult = MemAlloc_AllocAligned( size, align );
- memcpy( pResult, ptr, nOldSize - nOffset );
- g_pMemAlloc->Free( pAlloc );
- return pResult;
-}
-
-inline void MemAlloc_FreeAligned( void *pMemBlock )
-{
- void *pAlloc;
-
- if ( pMemBlock == NULL )
- return;
-
- pAlloc = pMemBlock;
-
- // pAlloc points to the pointer to starting of the memory block
- pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
-
- // pAlloc is the pointer to the start of memory block
- pAlloc = *( (void **)pAlloc );
- g_pMemAlloc->Free( pAlloc );
-}
-
-inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pFileName, int nLine )
-{
- void *pAlloc;
-
- if ( pMemBlock == NULL )
- return;
-
- pAlloc = pMemBlock;
-
- // pAlloc points to the pointer to starting of the memory block
- pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
-
- // pAlloc is the pointer to the start of memory block
- pAlloc = *( (void **)pAlloc );
- g_pMemAlloc->Free( pAlloc, pFileName, nLine );
-}
-
-inline size_t MemAlloc_GetSizeAligned( void *pMemBlock )
-{
- void *pAlloc;
-
- if ( pMemBlock == NULL )
- return 0;
-
- pAlloc = pMemBlock;
-
- // pAlloc points to the pointer to starting of the memory block
- pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
-
- // pAlloc is the pointer to the start of memory block
- pAlloc = *((void **)pAlloc );
- return g_pMemAlloc->GetSize( pAlloc ) - ( (byte *)pMemBlock - (byte *)pAlloc );
-}
-
-//-----------------------------------------------------------------------------
-
-#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
-#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ )
-#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line )
-#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo()
-#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
-#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
-#else
-#define MEM_ALLOC_CREDIT_(tag) ((void)0)
-#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0)
-#define MemAlloc_PopAllocDbgInfo() ((void)0)
-#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
-#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
-#endif
-
-#define MemAlloc_DumpStats() g_pMemAlloc->DumpStats()
-#define MemAlloc_CompactHeap() g_pMemAlloc->CompactHeap()
-#define MemAlloc_OutOfMemory() g_pMemAlloc->OutOfMemory()
-#define MemAlloc_CompactIncremental() g_pMemAlloc->CompactIncremental()
-#define MemAlloc_DumpStatsFileBase( _filename ) g_pMemAlloc->DumpStatsFileBase( _filename )
-#define MemAlloc_CrtCheckMemory() g_pMemAlloc->CrtCheckMemory()
-#define MemAlloc_GlobalMemoryStatus( _usedMemory, _freeMemory ) g_pMemAlloc->GlobalMemoryStatus( _usedMemory, _freeMemory )
-#define MemAlloc_MemoryAllocFailed() g_pMemAlloc->MemoryAllocFailed()
-
-#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
-#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
-#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
-#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
-#define MemAlloc_GetSize( x ) g_pMemAlloc->GetSize( x );
-//-----------------------------------------------------------------------------
-
-class CMemAllocAttributeAlloction
-{
-public:
- CMemAllocAttributeAlloction( const char *pszFile, int line )
- {
- MemAlloc_PushAllocDbgInfo( pszFile, line );
- }
-
- ~CMemAllocAttributeAlloction()
- {
- MemAlloc_PopAllocDbgInfo();
- }
-};
-
-#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
-
-//-----------------------------------------------------------------------------
-
-#if defined(_WIN32) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
-
- #pragma warning(disable:4290)
- #pragma warning(push)
- #include <typeinfo.h>
-
- // MEM_DEBUG_CLASSNAME is opt-in.
- // Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
- // simultaneously, it'll need a mutex.
- #if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
- #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() )
- #define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
- #else
- #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
- #define MEM_ALLOC_CLASSNAME(type) (__FILE__)
- #endif
-
- // MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example )
- #ifdef _MSC_VER
- #define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ )
- #else
- #define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__)
- #endif
-
- #pragma warning(pop)
-#else
- #define MEM_ALLOC_CREDIT_CLASS()
- #define MEM_ALLOC_CLASSNAME(type) NULL
- #define MEM_ALLOC_CREDIT_FUNCTION()
-#endif
-
-//-----------------------------------------------------------------------------
-
-#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
-struct MemAllocFileLine_t
-{
- const char *pszFile;
- int line;
-};
-
-#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \
- static CUtlMap<void *, MemAllocFileLine_t, int> g_##tag##Allocs( DefLessFunc( void *) ); \
- static const char *g_psz##tag##Alloc = strcpy( (char *)g_pMemAlloc->Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" );
-
-#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \
- if ( !p ) \
- ; \
- else \
- { \
- MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
- g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \
- if ( fileLine.pszFile != g_psz##tag##Alloc ) \
- { \
- g_##tag##Allocs.Insert( p, fileLine ); \
- } \
- \
- MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \
- }
-
-#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) \
- if ( !p ) \
- ; \
- else \
- { \
- MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
- CUtlMap<void *, MemAllocFileLine_t, int>::IndexType_t iRecordedFileLine = g_##tag##Allocs.Find( p ); \
- if ( iRecordedFileLine != g_##tag##Allocs.InvalidIndex() ) \
- { \
- fileLine = g_##tag##Allocs[iRecordedFileLine]; \
- g_##tag##Allocs.RemoveAt( iRecordedFileLine ); \
- } \
- \
- MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \
- }
-
-#else
-
-#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
-#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
-#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
-
-#endif
-
-//-----------------------------------------------------------------------------
-
-#elif defined( POSIX )
-
-#if defined( OSX )
-// Mac always aligns allocs, don't need to call posix_memalign which doesn't exist in 10.5.8 which TF2 still needs to run on
-//inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; posix_memalign(&pTmp, alignment, size); return pTmp;}
-inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; pTmp = malloc(size); return pTmp;}
-#endif
-
-inline void *_aligned_malloc( size_t nSize, size_t align ) { return memalign( align, nSize ); }
-inline void _aligned_free( void *ptr ) { free( ptr ); }
-
-inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName = NULL, int nLine = 0 ) { return malloc( nSize ); }
-inline void MemAlloc_Free( void *ptr, const char *pFileName = NULL, int nLine = 0 ) { free( ptr ); }
-
-inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile = NULL, int nLine = 0 ) { return memalign( align, size ); }
-inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile = NULL, int nLine = 0 ) { return memalign( align, size ); }
-inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pszFile = NULL, int nLine = 0 ) { free( pMemBlock ); }
-
-#if defined( OSX )
-inline size_t _msize( void *ptr ) { return malloc_size( ptr ); }
-#else
-inline size_t _msize( void *ptr ) { return malloc_usable_size( ptr ); }
-#endif
-
-inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
-{
- void *ptr_new_aligned = memalign( align, size );
-
- if( ptr_new_aligned )
- {
- size_t old_size = _msize( ptr );
- size_t copy_size = ( size < old_size ) ? size : old_size;
-
- memcpy( ptr_new_aligned, ptr, copy_size );
- free( ptr );
- }
-
- return ptr_new_aligned;
-}
-#else
-#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
-#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
-#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
-#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
-
-#endif // !STEAM && !NO_MALLOC_OVERRIDE
-
-//-----------------------------------------------------------------------------
-
-#if !defined(STEAM) && defined(NO_MALLOC_OVERRIDE)
-
-#define MEM_ALLOC_CREDIT_(tag) ((void)0)
-#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
-#define MEM_ALLOC_CREDIT_FUNCTION()
-#define MEM_ALLOC_CREDIT_CLASS()
-#define MEM_ALLOC_CLASSNAME(type) NULL
-
-#define MemAlloc_PushAllocDbgInfo( pszFile, line )
-#define MemAlloc_PopAllocDbgInfo()
-#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
-#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
-#define MemAlloc_DumpStats() ((void)0)
-#define MemAlloc_CompactHeap() ((void)0)
-#define MemAlloc_OutOfMemory() ((void)0)
-#define MemAlloc_CompactIncremental() ((void)0)
-#define MemAlloc_DumpStatsFileBase( _filename ) ((void)0)
-inline bool MemAlloc_CrtCheckMemory() { return true; }
-inline void MemAlloc_GlobalMemoryStatus( size_t *pusedMemory, size_t *pfreeMemory )
-{
- *pusedMemory = 0;
- *pfreeMemory = 0;
-}
-#define MemAlloc_MemoryAllocFailed() 0
-
-#define MemAlloc_GetDebugInfoSize() 0
-#define MemAlloc_SaveDebugInfo( pvDebugInfo ) ((void)0)
-#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) ((void)0)
-#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) ((void)0)
-
-
-#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
-#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
-#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
-
-#endif // !STEAM && NO_MALLOC_OVERRIDE
-
-//-----------------------------------------------------------------------------
-
-
-
-// linux memory tracking via hooks.
-#if defined( POSIX ) && !defined( NO_HOOK_MALLOC )
-PLATFORM_INTERFACE void MemoryLogMessage( char const *s ); // throw a message into the memory log
-PLATFORM_INTERFACE void EnableMemoryLogging( bool bOnOff );
-PLATFORM_INTERFACE void DumpMemoryLog( int nThresh );
-PLATFORM_INTERFACE void DumpMemorySummary( void );
-PLATFORM_INTERFACE void SetMemoryMark( void );
-PLATFORM_INTERFACE void DumpChangedMemory( int nThresh );
-
-#else
-FORCEINLINE void MemoryLogMessage( char const *s )
-{
-}
-
-FORCEINLINE void EnableMemoryLogging( bool bOnOff )
-{
-}
-FORCEINLINE void DumpMemoryLog( int nThresh )
-{
-}
-FORCEINLINE void DumpMemorySummary( void )
-{
-}
-FORCEINLINE void SetMemoryMark( void )
-{
-}
-FORCEINLINE void DumpChangedMemory( int nThresh )
-{
-}
-
-#endif
-
-#ifdef POSIX
-// ApproximateProcessMemoryUsage returns the approximate memory footprint of this process.
-PLATFORM_INTERFACE size_t ApproximateProcessMemoryUsage( void );
-#else
-FORCEINLINE size_t ApproximateProcessMemoryUsage( void )
-{
- return 0;
-}
-
-#endif
-
-struct aligned_tmp_t
-{
- // empty base class
-};
-
-/*
-This class used to be required if you wanted an object to be allocated with a specific
-alignment. ALIGN16 and ALIGN16_POST are not actually sufficient for this because they
-guarantee that the globals, statics, locals, and function parameters are appropriately
-aligned they do not affect memory allocation alignment.
-However this class is usually not needed because as of 2012 our policy is that our
-allocator should take care of this automatically. Any object whose size is a multiple
-of 16 will be 16-byte aligned. Existing uses of this class were not changed because
-the cost/benefit did not justify it.
-*/
-// template here to allow adding alignment at levels of hierarchy that aren't the base
-template< int bytesAlignment = 16, class T = aligned_tmp_t >
-class CAlignedNewDelete : public T
-{
-
-public:
- /*
- Note that this class does not overload operator new[] and delete[] which means that
- classes that depend on this for alignment may end up misaligned if an array is
- allocated. This problem is now mostly theoretical because this class is mostly
- obsolete.
- */
- void *operator new( size_t nSize )
- {
- return MemAlloc_AllocAligned( nSize, bytesAlignment );
- }
-
- void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
- {
- return MemAlloc_AllocAlignedFileLine( nSize, bytesAlignment, pFileName, nLine );
- }
-
- void operator delete(void *pData)
- {
- if ( pData )
- {
- MemAlloc_FreeAligned( pData );
- }
- }
-
- void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine )
- {
- if ( pData )
- {
- MemAlloc_FreeAligned( pData, pFileName, nLine );
- }
- }
-};
-
-
-#endif /* TIER0_MEMALLOC_H */
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This header should never be used directly from leaf code!!!
+// Instead, just add the file memoverride.cpp into your project and all this
+// will automagically be used
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef TIER0_MEMALLOC_H
+#define TIER0_MEMALLOC_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+// These memory debugging switches aren't relevant under Linux builds since memoverride.cpp
+// isn't built into Linux projects
+#ifndef POSIX
+// Define this in release to get memory tracking even in release builds
+//#define USE_MEM_DEBUG 1
+#endif
+
+#if defined( _MEMTEST )
+#ifdef _WIN32
+#define USE_MEM_DEBUG 1
+#endif
+#endif
+
+// Undefine this if using a compiler lacking threadsafe RTTI (like vc6)
+#define MEM_DEBUG_CLASSNAME 1
+
+#include <stddef.h>
+#if defined( OSX )
+#include <malloc/malloc.h>
+#endif
+
+#include "tier0/mem.h"
+
+#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
+
+struct _CrtMemState;
+
+#define MEMALLOC_VERSION 1
+
+typedef size_t (*MemAllocFailHandler_t)( size_t );
+
+//-----------------------------------------------------------------------------
+// NOTE! This should never be called directly from leaf code
+// Just use new,delete,malloc,free etc. They will call into this eventually
+//-----------------------------------------------------------------------------
+abstract_class IMemAlloc
+{
+public:
+ // Release versions
+ virtual void *Alloc( size_t nSize ) = 0;
+ virtual void *Realloc( void *pMem, size_t nSize ) = 0;
+ virtual void Free( void *pMem ) = 0;
+ virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0;
+
+ // Debug versions
+ virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0;
+ virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
+ virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0;
+ virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
+
+ // Returns size of a particular allocation
+ virtual size_t GetSize( void *pMem ) = 0;
+
+ // Force file + line information for an allocation
+ virtual void PushAllocDbgInfo( const char *pFileName, int nLine ) = 0;
+ virtual void PopAllocDbgInfo() = 0;
+
+ // FIXME: Remove when we have our own allocator
+ // these methods of the Crt debug code is used in our codebase currently
+ virtual long CrtSetBreakAlloc( long lNewBreakAlloc ) = 0;
+ virtual int CrtSetReportMode( int nReportType, int nReportMode ) = 0;
+ virtual int CrtIsValidHeapPointer( const void *pMem ) = 0;
+ virtual int CrtIsValidPointer( const void *pMem, unsigned int size, int access ) = 0;
+ virtual int CrtCheckMemory( void ) = 0;
+ virtual int CrtSetDbgFlag( int nNewFlag ) = 0;
+ virtual void CrtMemCheckpoint( _CrtMemState *pState ) = 0;
+
+ // FIXME: Make a better stats interface
+ virtual void DumpStats() = 0;
+ virtual void DumpStatsFileBase( char const *pchFileBase ) = 0;
+
+ // FIXME: Remove when we have our own allocator
+ virtual void* CrtSetReportFile( int nRptType, void* hFile ) = 0;
+ virtual void* CrtSetReportHook( void* pfnNewHook ) = 0;
+ virtual int CrtDbgReport( int nRptType, const char * szFile,
+ int nLine, const char * szModule, const char * pMsg ) = 0;
+
+ virtual int heapchk() = 0;
+
+ virtual bool IsDebugHeap() = 0;
+
+ virtual void GetActualDbgInfo( const char *&pFileName, int &nLine ) = 0;
+ virtual void RegisterAllocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
+ virtual void RegisterDeallocation( const char *pFileName, int nLine, int nLogicalSize, int nActualSize, unsigned nTime ) = 0;
+
+ virtual int GetVersion() = 0;
+
+ virtual void CompactHeap() = 0;
+
+ // Function called when malloc fails or memory limits hit to attempt to free up memory (can come in any thread)
+ virtual MemAllocFailHandler_t SetAllocFailHandler( MemAllocFailHandler_t pfnMemAllocFailHandler ) = 0;
+
+ virtual void DumpBlockStats( void * ) = 0;
+
+#if defined( _MEMTEST )
+ virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0;
+#endif
+
+ // Returns 0 if no failure, otherwise the size_t of the last requested chunk
+ // "I'm sure this is completely thread safe!" Brian Deen 7/19/2012.
+ virtual size_t MemoryAllocFailed() = 0;
+
+ // handles storing allocation info for coroutines
+ virtual uint32 GetDebugInfoSize() = 0;
+ virtual void SaveDebugInfo( void *pvDebugInfo ) = 0;
+ virtual void RestoreDebugInfo( const void *pvDebugInfo ) = 0;
+ virtual void InitDebugInfo( void *pvDebugInfo, const char *pchRootFileName, int nLine ) = 0;
+
+ // Replacement for ::GlobalMemoryStatus which accounts for unused memory in our system
+ virtual void GlobalMemoryStatus( size_t *pUsedMemory, size_t *pFreeMemory ) = 0;
+};
+
+//-----------------------------------------------------------------------------
+// Singleton interface
+//-----------------------------------------------------------------------------
+MEM_INTERFACE IMemAlloc *g_pMemAlloc;
+
+//-----------------------------------------------------------------------------
+
+#ifdef MEMALLOC_REGIONS
+#ifndef MEMALLOC_REGION
+#define MEMALLOC_REGION 0
+#endif
+inline void *MemAlloc_Alloc( size_t nSize )
+{
+ return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize );
+}
+
+inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize, pFileName, nLine );
+}
+#else
+#undef MEMALLOC_REGION
+inline void *MemAlloc_Alloc( size_t nSize )
+{
+ return g_pMemAlloc->Alloc( nSize );
+}
+
+inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->Alloc( nSize, pFileName, nLine );
+}
+#endif
+inline void MemAlloc_Free( void *ptr )
+{
+ g_pMemAlloc->Free( ptr );
+}
+inline void MemAlloc_Free( void *ptr, const char *pFileName, int nLine )
+{
+ g_pMemAlloc->Free( ptr, pFileName, nLine );
+}
+
+//-----------------------------------------------------------------------------
+
+inline bool ValueIsPowerOfTwo( size_t value ) // don't clash with mathlib definition
+{
+ return (value & ( value - 1 )) == 0;
+}
+
+inline void *MemAlloc_AllocAligned( size_t size, size_t align )
+{
+ unsigned char *pAlloc, *pResult;
+
+ if (!IsPowerOfTwo(align))
+ return NULL;
+
+ align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
+
+ if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
+ return NULL;
+
+ pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
+ ((unsigned char**)(pResult))[-1] = pAlloc;
+
+ return (void *)pResult;
+}
+
+inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile, int nLine )
+{
+ unsigned char *pAlloc, *pResult;
+
+ if (!IsPowerOfTwo(align))
+ return NULL;
+
+ align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
+
+ if ( (pAlloc = (unsigned char*)g_pMemAlloc->Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
+ return NULL;
+
+ pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
+ ((unsigned char**)(pResult))[-1] = pAlloc;
+
+ return (void *)pResult;
+}
+
+inline void *MemAlloc_AllocAlignedUnattributed( size_t size, size_t align )
+{
+ unsigned char *pAlloc, *pResult;
+
+ if (!ValueIsPowerOfTwo(align))
+ return NULL;
+
+ align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
+
+ if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
+ return NULL;
+
+ pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
+ ((unsigned char**)(pResult))[-1] = pAlloc;
+
+ return (void *)pResult;
+}
+
+inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile, int nLine )
+{
+ unsigned char *pAlloc, *pResult;
+
+ if (!ValueIsPowerOfTwo(align))
+ return NULL;
+
+ align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
+
+ if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
+ return NULL;
+
+ pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
+ ((unsigned char**)(pResult))[-1] = pAlloc;
+
+ return (void *)pResult;
+}
+
+inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
+{
+ if ( !IsPowerOfTwo( align ) )
+ return NULL;
+
+ // Don't change alignment between allocation + reallocation.
+ if ( ( (size_t)ptr & ( align - 1 ) ) != 0 )
+ return NULL;
+
+ if ( !ptr )
+ return MemAlloc_AllocAligned( size, align );
+
+ void *pAlloc, *pResult;
+
+ // Figure out the actual allocation point
+ pAlloc = ptr;
+ pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
+ pAlloc = *( (void **)pAlloc );
+
+ // See if we have enough space
+ size_t nOffset = (size_t)ptr - (size_t)pAlloc;
+ size_t nOldSize = g_pMemAlloc->GetSize( pAlloc );
+ if ( nOldSize >= size + nOffset )
+ return ptr;
+
+ pResult = MemAlloc_AllocAligned( size, align );
+ memcpy( pResult, ptr, nOldSize - nOffset );
+ g_pMemAlloc->Free( pAlloc );
+ return pResult;
+}
+
+inline void MemAlloc_FreeAligned( void *pMemBlock )
+{
+ void *pAlloc;
+
+ if ( pMemBlock == NULL )
+ return;
+
+ pAlloc = pMemBlock;
+
+ // pAlloc points to the pointer to starting of the memory block
+ pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
+
+ // pAlloc is the pointer to the start of memory block
+ pAlloc = *( (void **)pAlloc );
+ g_pMemAlloc->Free( pAlloc );
+}
+
+inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pFileName, int nLine )
+{
+ void *pAlloc;
+
+ if ( pMemBlock == NULL )
+ return;
+
+ pAlloc = pMemBlock;
+
+ // pAlloc points to the pointer to starting of the memory block
+ pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
+
+ // pAlloc is the pointer to the start of memory block
+ pAlloc = *( (void **)pAlloc );
+ g_pMemAlloc->Free( pAlloc, pFileName, nLine );
+}
+
+inline size_t MemAlloc_GetSizeAligned( void *pMemBlock )
+{
+ void *pAlloc;
+
+ if ( pMemBlock == NULL )
+ return 0;
+
+ pAlloc = pMemBlock;
+
+ // pAlloc points to the pointer to starting of the memory block
+ pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
+
+ // pAlloc is the pointer to the start of memory block
+ pAlloc = *((void **)pAlloc );
+ return g_pMemAlloc->GetSize( pAlloc ) - ( (byte *)pMemBlock - (byte *)pAlloc );
+}
+
+//-----------------------------------------------------------------------------
+
+#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
+#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ )
+#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line )
+#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo()
+#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
+#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
+#else
+#define MEM_ALLOC_CREDIT_(tag) ((void)0)
+#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0)
+#define MemAlloc_PopAllocDbgInfo() ((void)0)
+#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
+#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
+#endif
+
+#define MemAlloc_DumpStats() g_pMemAlloc->DumpStats()
+#define MemAlloc_CompactHeap() g_pMemAlloc->CompactHeap()
+#define MemAlloc_OutOfMemory() g_pMemAlloc->OutOfMemory()
+#define MemAlloc_CompactIncremental() g_pMemAlloc->CompactIncremental()
+#define MemAlloc_DumpStatsFileBase( _filename ) g_pMemAlloc->DumpStatsFileBase( _filename )
+#define MemAlloc_CrtCheckMemory() g_pMemAlloc->CrtCheckMemory()
+#define MemAlloc_GlobalMemoryStatus( _usedMemory, _freeMemory ) g_pMemAlloc->GlobalMemoryStatus( _usedMemory, _freeMemory )
+#define MemAlloc_MemoryAllocFailed() g_pMemAlloc->MemoryAllocFailed()
+
+#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
+#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
+#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
+#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
+#define MemAlloc_GetSize( x ) g_pMemAlloc->GetSize( x );
+//-----------------------------------------------------------------------------
+
+class CMemAllocAttributeAlloction
+{
+public:
+ CMemAllocAttributeAlloction( const char *pszFile, int line )
+ {
+ MemAlloc_PushAllocDbgInfo( pszFile, line );
+ }
+
+ ~CMemAllocAttributeAlloction()
+ {
+ MemAlloc_PopAllocDbgInfo();
+ }
+};
+
+#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
+
+//-----------------------------------------------------------------------------
+
+#if defined(_WIN32) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
+
+ #pragma warning(disable:4290)
+ #pragma warning(push)
+ #include <typeinfo.h>
+
+ // MEM_DEBUG_CLASSNAME is opt-in.
+ // Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
+ // simultaneously, it'll need a mutex.
+ #if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
+ #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( typeid(*this).name() )
+ #define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
+ #else
+ #define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
+ #define MEM_ALLOC_CLASSNAME(type) (__FILE__)
+ #endif
+
+ // MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example )
+ #ifdef _MSC_VER
+ #define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ )
+ #else
+ #define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__)
+ #endif
+
+ #pragma warning(pop)
+#else
+ #define MEM_ALLOC_CREDIT_CLASS()
+ #define MEM_ALLOC_CLASSNAME(type) NULL
+ #define MEM_ALLOC_CREDIT_FUNCTION()
+#endif
+
+//-----------------------------------------------------------------------------
+
+#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
+struct MemAllocFileLine_t
+{
+ const char *pszFile;
+ int line;
+};
+
+#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \
+ static CUtlMap<void *, MemAllocFileLine_t, int> g_##tag##Allocs( DefLessFunc( void *) ); \
+ static const char *g_psz##tag##Alloc = strcpy( (char *)g_pMemAlloc->Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" );
+
+#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \
+ if ( !p ) \
+ ; \
+ else \
+ { \
+ MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
+ g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \
+ if ( fileLine.pszFile != g_psz##tag##Alloc ) \
+ { \
+ g_##tag##Allocs.Insert( p, fileLine ); \
+ } \
+ \
+ MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \
+ }
+
+#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) \
+ if ( !p ) \
+ ; \
+ else \
+ { \
+ MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
+ CUtlMap<void *, MemAllocFileLine_t, int>::IndexType_t iRecordedFileLine = g_##tag##Allocs.Find( p ); \
+ if ( iRecordedFileLine != g_##tag##Allocs.InvalidIndex() ) \
+ { \
+ fileLine = g_##tag##Allocs[iRecordedFileLine]; \
+ g_##tag##Allocs.RemoveAt( iRecordedFileLine ); \
+ } \
+ \
+ MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \
+ }
+
+#else
+
+#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
+#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
+#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
+
+#endif
+
+//-----------------------------------------------------------------------------
+
+#elif defined( POSIX )
+
+#if defined( OSX )
+// Mac always aligns allocs, don't need to call posix_memalign which doesn't exist in 10.5.8 which TF2 still needs to run on
+//inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; posix_memalign(&pTmp, alignment, size); return pTmp;}
+inline void *memalign(size_t alignment, size_t size) {void *pTmp=NULL; pTmp = malloc(size); return pTmp;}
+#endif
+
+inline void *_aligned_malloc( size_t nSize, size_t align ) { return memalign( align, nSize ); }
+inline void _aligned_free( void *ptr ) { free( ptr ); }
+
+inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName = NULL, int nLine = 0 ) { return malloc( nSize ); }
+inline void MemAlloc_Free( void *ptr, const char *pFileName = NULL, int nLine = 0 ) { free( ptr ); }
+
+inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile = NULL, int nLine = 0 ) { return memalign( align, size ); }
+inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile = NULL, int nLine = 0 ) { return memalign( align, size ); }
+inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pszFile = NULL, int nLine = 0 ) { free( pMemBlock ); }
+
+#if defined( OSX )
+inline size_t _msize( void *ptr ) { return malloc_size( ptr ); }
+#else
+inline size_t _msize( void *ptr ) { return malloc_usable_size( ptr ); }
+#endif
+
+inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
+{
+ void *ptr_new_aligned = memalign( align, size );
+
+ if( ptr_new_aligned )
+ {
+ size_t old_size = _msize( ptr );
+ size_t copy_size = ( size < old_size ) ? size : old_size;
+
+ memcpy( ptr_new_aligned, ptr, copy_size );
+ free( ptr );
+ }
+
+ return ptr_new_aligned;
+}
+#else
+#define MemAlloc_GetDebugInfoSize() g_pMemAlloc->GetDebugInfoSize()
+#define MemAlloc_SaveDebugInfo( pvDebugInfo ) g_pMemAlloc->SaveDebugInfo( pvDebugInfo )
+#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) g_pMemAlloc->RestoreDebugInfo( pvDebugInfo )
+#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) g_pMemAlloc->InitDebugInfo( pvDebugInfo, pchRootFileName, nLine )
+
+#endif // !STEAM && !NO_MALLOC_OVERRIDE
+
+//-----------------------------------------------------------------------------
+
+#if !defined(STEAM) && defined(NO_MALLOC_OVERRIDE)
+
+#define MEM_ALLOC_CREDIT_(tag) ((void)0)
+#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
+#define MEM_ALLOC_CREDIT_FUNCTION()
+#define MEM_ALLOC_CREDIT_CLASS()
+#define MEM_ALLOC_CLASSNAME(type) NULL
+
+#define MemAlloc_PushAllocDbgInfo( pszFile, line )
+#define MemAlloc_PopAllocDbgInfo()
+#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
+#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
+#define MemAlloc_DumpStats() ((void)0)
+#define MemAlloc_CompactHeap() ((void)0)
+#define MemAlloc_OutOfMemory() ((void)0)
+#define MemAlloc_CompactIncremental() ((void)0)
+#define MemAlloc_DumpStatsFileBase( _filename ) ((void)0)
+inline bool MemAlloc_CrtCheckMemory() { return true; }
+inline void MemAlloc_GlobalMemoryStatus( size_t *pusedMemory, size_t *pfreeMemory )
+{
+ *pusedMemory = 0;
+ *pfreeMemory = 0;
+}
+#define MemAlloc_MemoryAllocFailed() 0
+
+#define MemAlloc_GetDebugInfoSize() 0
+#define MemAlloc_SaveDebugInfo( pvDebugInfo ) ((void)0)
+#define MemAlloc_RestoreDebugInfo( pvDebugInfo ) ((void)0)
+#define MemAlloc_InitDebugInfo( pvDebugInfo, pchRootFileName, nLine ) ((void)0)
+
+
+#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
+#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
+#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
+
+#endif // !STEAM && NO_MALLOC_OVERRIDE
+
+//-----------------------------------------------------------------------------
+
+
+
+// linux memory tracking via hooks.
+#if defined( POSIX ) && !defined( NO_HOOK_MALLOC )
+PLATFORM_INTERFACE void MemoryLogMessage( char const *s ); // throw a message into the memory log
+PLATFORM_INTERFACE void EnableMemoryLogging( bool bOnOff );
+PLATFORM_INTERFACE void DumpMemoryLog( int nThresh );
+PLATFORM_INTERFACE void DumpMemorySummary( void );
+PLATFORM_INTERFACE void SetMemoryMark( void );
+PLATFORM_INTERFACE void DumpChangedMemory( int nThresh );
+
+#else
+FORCEINLINE void MemoryLogMessage( char const *s )
+{
+}
+
+FORCEINLINE void EnableMemoryLogging( bool bOnOff )
+{
+}
+FORCEINLINE void DumpMemoryLog( int nThresh )
+{
+}
+FORCEINLINE void DumpMemorySummary( void )
+{
+}
+FORCEINLINE void SetMemoryMark( void )
+{
+}
+FORCEINLINE void DumpChangedMemory( int nThresh )
+{
+}
+
+#endif
+
+#ifdef POSIX
+// ApproximateProcessMemoryUsage returns the approximate memory footprint of this process.
+PLATFORM_INTERFACE size_t ApproximateProcessMemoryUsage( void );
+#else
+FORCEINLINE size_t ApproximateProcessMemoryUsage( void )
+{
+ return 0;
+}
+
+#endif
+
+struct aligned_tmp_t
+{
+ // empty base class
+};
+
+/*
+This class used to be required if you wanted an object to be allocated with a specific
+alignment. ALIGN16 and ALIGN16_POST are not actually sufficient for this because they
+guarantee that the globals, statics, locals, and function parameters are appropriately
+aligned they do not affect memory allocation alignment.
+However this class is usually not needed because as of 2012 our policy is that our
+allocator should take care of this automatically. Any object whose size is a multiple
+of 16 will be 16-byte aligned. Existing uses of this class were not changed because
+the cost/benefit did not justify it.
+*/
+// template here to allow adding alignment at levels of hierarchy that aren't the base
+template< int bytesAlignment = 16, class T = aligned_tmp_t >
+class CAlignedNewDelete : public T
+{
+
+public:
+ /*
+ Note that this class does not overload operator new[] and delete[] which means that
+ classes that depend on this for alignment may end up misaligned if an array is
+ allocated. This problem is now mostly theoretical because this class is mostly
+ obsolete.
+ */
+ void *operator new( size_t nSize )
+ {
+ return MemAlloc_AllocAligned( nSize, bytesAlignment );
+ }
+
+ void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
+ {
+ return MemAlloc_AllocAlignedFileLine( nSize, bytesAlignment, pFileName, nLine );
+ }
+
+ void operator delete(void *pData)
+ {
+ if ( pData )
+ {
+ MemAlloc_FreeAligned( pData );
+ }
+ }
+
+ void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine )
+ {
+ if ( pData )
+ {
+ MemAlloc_FreeAligned( pData, pFileName, nLine );
+ }
+ }
+};
+
+
+#endif /* TIER0_MEMALLOC_H */
diff --git a/sp/src/public/tier0/memdbgoff.h b/sp/src/public/tier0/memdbgoff.h
index 44dda778..1cd09dae 100644
--- a/sp/src/public/tier0/memdbgoff.h
+++ b/sp/src/public/tier0/memdbgoff.h
@@ -1,25 +1,25 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This header, which must be the final line of a .h file,
-// causes all crt methods to stop using debugging versions of the memory allocators.
-// NOTE: Use memdbgon.h to re-enable memory debugging.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifdef MEM_OVERRIDE_ON
-
-#undef malloc
-#undef realloc
-#undef calloc
-#undef free
-#undef _expand
-#undef _msize
-#undef new
-#undef _aligned_malloc
-#undef _aligned_free
-#undef _malloc_dbg
-
-#undef MEM_OVERRIDE_ON
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This header, which must be the final line of a .h file,
+// causes all crt methods to stop using debugging versions of the memory allocators.
+// NOTE: Use memdbgon.h to re-enable memory debugging.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifdef MEM_OVERRIDE_ON
+
+#undef malloc
+#undef realloc
+#undef calloc
+#undef free
+#undef _expand
+#undef _msize
+#undef new
+#undef _aligned_malloc
+#undef _aligned_free
+#undef _malloc_dbg
+
+#undef MEM_OVERRIDE_ON
+
+#endif
diff --git a/sp/src/public/tier0/memdbgon.h b/sp/src/public/tier0/memdbgon.h
index fff3f470..7fd6e9ca 100644
--- a/sp/src/public/tier0/memdbgon.h
+++ b/sp/src/public/tier0/memdbgon.h
@@ -1,248 +1,248 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This header, which must be the final include in a .cpp (or .h) file,
-// causes all crt methods to use debugging versions of the memory allocators.
-// NOTE: Use memdbgoff.h to disable memory debugging.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-// SPECIAL NOTE! This file must *not* use include guards; we need to be able
-// to include this potentially multiple times (since we can deactivate debugging
-// by including memdbgoff.h)
-
-#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
-
-// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
-
-#if defined(_DEBUG) && !defined(USE_MEM_DEBUG)
-#define USE_MEM_DEBUG 1
-#endif
-
-#if defined(NO_HOOK_MALLOC)
-#undef USE_MEM_DEBUG
-#endif
-
-// If debug build or ndebug and not already included MS custom alloc files, or already included this file
-#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H)
-
-#include "basetypes.h"
-#ifdef _WIN32
-#include <tchar.h>
-#else
-#include <wchar.h>
-#endif
-#include <string.h>
-#include <malloc.h>
-#include "commonmacros.h"
-#include "memalloc.h"
-
-#if defined(USE_MEM_DEBUG)
- #if defined( POSIX )
-
- #define _NORMAL_BLOCK 1
-
- #include <cstddef>
- #include <glob.h>
- #include <new>
- #include <sys/types.h>
- #if !defined( DID_THE_OPERATOR_NEW )
- #define DID_THE_OPERATOR_NEW
- // posix doesn't have a new of this form, so we impl our own
- void* operator new( size_t nSize, int blah, const char *pFileName, int nLine );
- void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine );
- #endif
-
- #else // defined(POSIX)
-
- // Include crtdbg.h and make sure _DEBUG is set to 1.
- #if !defined(_DEBUG)
- #define _DEBUG 1
- #include <crtdbg.h>
- #undef _DEBUG
- #else
- #include <crtdbg.h>
- #endif // !defined(_DEBUG)
-
- #endif // defined(POSIX)
-#endif
-
-#include "tier0/memdbgoff.h"
-
-// --------------------------------------------------------
-// Debug/non-debug agnostic elements
-
-#define MEM_OVERRIDE_ON 1
-
-#undef malloc
-#undef realloc
-#undef calloc
-#undef _expand
-#undef free
-#undef _msize
-#undef _aligned_malloc
-#undef _aligned_free
-
-#ifndef MEMDBGON_H
-inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nElementSize)
-{
- memset(pMem, 0, nElementSize * nCount);
- return pMem;
-}
-#endif
-
-#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s)
-#define free(p) g_pMemAlloc->Free( p )
-#define _msize(p) g_pMemAlloc->GetSize( p )
-#define _expand(p, s) _expand_NoLongerSupported(p, s)
-#define _aligned_free( p ) MemAlloc_FreeAligned( p )
-
-// --------------------------------------------------------
-// Debug path
-#if defined(USE_MEM_DEBUG)
-
-#define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__)
-#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ )
-#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ )
-
-#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
-
-#if !defined( LINUX )
-#if defined(__AFX_H__) && defined(DEBUG_NEW)
- #define new DEBUG_NEW
-#else
- #undef new
- #define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
- #define new MEMALL_DEBUG_NEW
-#endif
-#endif
-
-#undef _strdup
-#undef strdup
-#undef _wcsdup
-#undef wcsdup
-
-#define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
-#define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
-#define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
-#define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
-
-// Make sure we don't define strdup twice
-#if !defined(MEMDBGON_H)
-
-inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigned nLine)
-{
- char *pMemory;
-
- if (!pString)
- return NULL;
-
- size_t len = strlen(pString) + 1;
- if ((pMemory = (char *)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL)
- {
- return strcpy( pMemory, pString );
- }
-
- return NULL;
-}
-
-inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName, unsigned nLine)
-{
- wchar_t *pMemory;
-
- if (!pString)
- return NULL;
-
- size_t len = (wcslen(pString) + 1);
- if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL)
- {
- return wcscpy( pMemory, pString );
- }
-
- return NULL;
-}
-
-#endif // DBMEM_DEFINED_STRDUP
-
-#else
-// --------------------------------------------------------
-// Release path
-
-#define malloc(s) g_pMemAlloc->Alloc( s )
-#define realloc(p, s) g_pMemAlloc->Realloc( p, s )
-#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a )
-
-#ifndef _malloc_dbg
-#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
-#endif
-
-#undef new
-
-#undef _strdup
-#undef strdup
-#undef _wcsdup
-#undef wcsdup
-
-#define _strdup(s) MemAlloc_StrDup(s)
-#define strdup(s) MemAlloc_StrDup(s)
-#define _wcsdup(s) MemAlloc_WcStrDup(s)
-#define wcsdup(s) MemAlloc_WcStrDup(s)
-
-// Make sure we don't define strdup twice
-#if !defined(MEMDBGON_H)
-
-inline char *MemAlloc_StrDup(const char *pString)
-{
- char *pMemory;
-
- if (!pString)
- return NULL;
-
- size_t len = strlen(pString) + 1;
- if ((pMemory = (char *)g_pMemAlloc->Alloc(len)) != NULL)
- {
- return strcpy( pMemory, pString );
- }
-
- return NULL;
-}
-
-inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
-{
- wchar_t *pMemory;
-
- if (!pString)
- return NULL;
-
- size_t len = (wcslen(pString) + 1);
- if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL)
- {
- return wcscpy( pMemory, pString );
- }
-
- return NULL;
-}
-
-#endif // DBMEM_DEFINED_STRDUP
-
-#endif // USE_MEM_DEBUG
-
-#define MEMDBGON_H // Defined here so can be used above
-
-#else
-
-#if defined(USE_MEM_DEBUG)
-#ifndef _STATIC_LINKED
-#pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build")
-#else
-#error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build"
-#endif
-#endif
-#endif // _INC_CRTDBG
-
-#else
-
-// Needed for MEM_ALLOC_CREDIT(), MemAlloc_Alloc(), etc.
-#include "memalloc.h"
-
-#endif // !STEAM && !NO_MALLOC_OVERRIDE
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This header, which must be the final include in a .cpp (or .h) file,
+// causes all crt methods to use debugging versions of the memory allocators.
+// NOTE: Use memdbgoff.h to disable memory debugging.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+// SPECIAL NOTE! This file must *not* use include guards; we need to be able
+// to include this potentially multiple times (since we can deactivate debugging
+// by including memdbgoff.h)
+
+#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
+
+// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
+
+#if defined(_DEBUG) && !defined(USE_MEM_DEBUG)
+#define USE_MEM_DEBUG 1
+#endif
+
+#if defined(NO_HOOK_MALLOC)
+#undef USE_MEM_DEBUG
+#endif
+
+// If debug build or ndebug and not already included MS custom alloc files, or already included this file
+#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H)
+
+#include "basetypes.h"
+#ifdef _WIN32
+#include <tchar.h>
+#else
+#include <wchar.h>
+#endif
+#include <string.h>
+#include <malloc.h>
+#include "commonmacros.h"
+#include "memalloc.h"
+
+#if defined(USE_MEM_DEBUG)
+ #if defined( POSIX )
+
+ #define _NORMAL_BLOCK 1
+
+ #include <cstddef>
+ #include <glob.h>
+ #include <new>
+ #include <sys/types.h>
+ #if !defined( DID_THE_OPERATOR_NEW )
+ #define DID_THE_OPERATOR_NEW
+ // posix doesn't have a new of this form, so we impl our own
+ void* operator new( size_t nSize, int blah, const char *pFileName, int nLine );
+ void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine );
+ #endif
+
+ #else // defined(POSIX)
+
+ // Include crtdbg.h and make sure _DEBUG is set to 1.
+ #if !defined(_DEBUG)
+ #define _DEBUG 1
+ #include <crtdbg.h>
+ #undef _DEBUG
+ #else
+ #include <crtdbg.h>
+ #endif // !defined(_DEBUG)
+
+ #endif // defined(POSIX)
+#endif
+
+#include "tier0/memdbgoff.h"
+
+// --------------------------------------------------------
+// Debug/non-debug agnostic elements
+
+#define MEM_OVERRIDE_ON 1
+
+#undef malloc
+#undef realloc
+#undef calloc
+#undef _expand
+#undef free
+#undef _msize
+#undef _aligned_malloc
+#undef _aligned_free
+
+#ifndef MEMDBGON_H
+inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nElementSize)
+{
+ memset(pMem, 0, nElementSize * nCount);
+ return pMem;
+}
+#endif
+
+#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s)
+#define free(p) g_pMemAlloc->Free( p )
+#define _msize(p) g_pMemAlloc->GetSize( p )
+#define _expand(p, s) _expand_NoLongerSupported(p, s)
+#define _aligned_free( p ) MemAlloc_FreeAligned( p )
+
+// --------------------------------------------------------
+// Debug path
+#if defined(USE_MEM_DEBUG)
+
+#define malloc(s) g_pMemAlloc->Alloc( s, __FILE__, __LINE__)
+#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ )
+#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a, __FILE__, __LINE__ )
+
+#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
+
+#if !defined( LINUX )
+#if defined(__AFX_H__) && defined(DEBUG_NEW)
+ #define new DEBUG_NEW
+#else
+ #undef new
+ #define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
+ #define new MEMALL_DEBUG_NEW
+#endif
+#endif
+
+#undef _strdup
+#undef strdup
+#undef _wcsdup
+#undef wcsdup
+
+#define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
+#define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
+#define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
+#define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
+
+// Make sure we don't define strdup twice
+#if !defined(MEMDBGON_H)
+
+inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigned nLine)
+{
+ char *pMemory;
+
+ if (!pString)
+ return NULL;
+
+ size_t len = strlen(pString) + 1;
+ if ((pMemory = (char *)g_pMemAlloc->Alloc(len, pFileName, nLine)) != NULL)
+ {
+ return strcpy( pMemory, pString );
+ }
+
+ return NULL;
+}
+
+inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName, unsigned nLine)
+{
+ wchar_t *pMemory;
+
+ if (!pString)
+ return NULL;
+
+ size_t len = (wcslen(pString) + 1);
+ if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL)
+ {
+ return wcscpy( pMemory, pString );
+ }
+
+ return NULL;
+}
+
+#endif // DBMEM_DEFINED_STRDUP
+
+#else
+// --------------------------------------------------------
+// Release path
+
+#define malloc(s) g_pMemAlloc->Alloc( s )
+#define realloc(p, s) g_pMemAlloc->Realloc( p, s )
+#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a )
+
+#ifndef _malloc_dbg
+#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
+#endif
+
+#undef new
+
+#undef _strdup
+#undef strdup
+#undef _wcsdup
+#undef wcsdup
+
+#define _strdup(s) MemAlloc_StrDup(s)
+#define strdup(s) MemAlloc_StrDup(s)
+#define _wcsdup(s) MemAlloc_WcStrDup(s)
+#define wcsdup(s) MemAlloc_WcStrDup(s)
+
+// Make sure we don't define strdup twice
+#if !defined(MEMDBGON_H)
+
+inline char *MemAlloc_StrDup(const char *pString)
+{
+ char *pMemory;
+
+ if (!pString)
+ return NULL;
+
+ size_t len = strlen(pString) + 1;
+ if ((pMemory = (char *)g_pMemAlloc->Alloc(len)) != NULL)
+ {
+ return strcpy( pMemory, pString );
+ }
+
+ return NULL;
+}
+
+inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
+{
+ wchar_t *pMemory;
+
+ if (!pString)
+ return NULL;
+
+ size_t len = (wcslen(pString) + 1);
+ if ((pMemory = (wchar_t *)g_pMemAlloc->Alloc(len * sizeof(wchar_t))) != NULL)
+ {
+ return wcscpy( pMemory, pString );
+ }
+
+ return NULL;
+}
+
+#endif // DBMEM_DEFINED_STRDUP
+
+#endif // USE_MEM_DEBUG
+
+#define MEMDBGON_H // Defined here so can be used above
+
+#else
+
+#if defined(USE_MEM_DEBUG)
+#ifndef _STATIC_LINKED
+#pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build")
+#else
+#error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build"
+#endif
+#endif
+#endif // _INC_CRTDBG
+
+#else
+
+// Needed for MEM_ALLOC_CREDIT(), MemAlloc_Alloc(), etc.
+#include "memalloc.h"
+
+#endif // !STEAM && !NO_MALLOC_OVERRIDE
diff --git a/sp/src/public/tier0/memoverride.cpp b/sp/src/public/tier0/memoverride.cpp
index 29495903..5c679e45 100644
--- a/sp/src/public/tier0/memoverride.cpp
+++ b/sp/src/public/tier0/memoverride.cpp
@@ -1,1658 +1,1658 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Insert this file into all projects using the memory system
-// It will cause that project to use the shader memory allocator
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
-
-#undef PROTECTED_THINGS_ENABLE // allow use of _vsnprintf
-
-#if defined( _WIN32 ) && !defined( _X360 )
-#define WIN_32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "tier0/dbg.h"
-#include "tier0/memalloc.h"
-#include <string.h>
-#include <stdio.h>
-#include "memdbgoff.h"
-
-#ifdef _WIN32
-// ARG: crtdbg is necessary for certain definitions below,
-// but it also redefines malloc as a macro in release.
-// To disable this, we gotta define _DEBUG before including it.. BLEAH!
-#define _DEBUG 1
-#include "crtdbg.h"
-#ifdef NDEBUG
-#undef _DEBUG
-#endif
-
-// Turn this back off in release mode.
-#ifdef NDEBUG
-#undef _DEBUG
-#endif
-#elif POSIX
-#define __cdecl
-#endif
-
-#if defined( _WIN32 ) && !defined( _X360 )
-const char *MakeModuleFileName()
-{
- if ( g_pMemAlloc->IsDebugHeap() )
- {
- char *pszModuleName = (char *)HeapAlloc( GetProcessHeap(), 0, MAX_PATH ); // small leak, debug only
-
- MEMORY_BASIC_INFORMATION mbi;
- static int dummy;
- VirtualQuery( &dummy, &mbi, sizeof(mbi) );
-
- GetModuleFileName( reinterpret_cast<HMODULE>(mbi.AllocationBase), pszModuleName, MAX_PATH );
- char *pDot = strrchr( pszModuleName, '.' );
- if ( pDot )
- {
- char *pSlash = strrchr( pszModuleName, '\\' );
- if ( pSlash )
- {
- pszModuleName = pSlash + 1;
- *pDot = 0;
- }
- }
-
- return pszModuleName;
- }
- return NULL;
-}
-
-static void *AllocUnattributed( size_t nSize )
-{
- static const char *pszOwner = MakeModuleFileName();
-
- if ( !pszOwner )
- return g_pMemAlloc->Alloc(nSize);
- else
- return g_pMemAlloc->Alloc(nSize, pszOwner, 0);
-}
-
-static void *ReallocUnattributed( void *pMem, size_t nSize )
-{
- static const char *pszOwner = MakeModuleFileName();
-
- if ( !pszOwner )
- return g_pMemAlloc->Realloc(pMem, nSize);
- else
- return g_pMemAlloc->Realloc(pMem, nSize, pszOwner, 0);
-}
-
-#else
-#define MakeModuleFileName() NULL
-inline void *AllocUnattributed( size_t nSize )
-{
- return g_pMemAlloc->Alloc(nSize);
-}
-
-inline void *ReallocUnattributed( void *pMem, size_t nSize )
-{
- return g_pMemAlloc->Realloc(pMem, nSize);
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Standard functions in the CRT that we're going to override to call our allocator
-//-----------------------------------------------------------------------------
-#if defined(_WIN32) && !defined(_STATIC_LINKED)
-// this magic only works under win32
-// under linux this malloc() overrides the libc malloc() and so we
-// end up in a recursion (as g_pMemAlloc->Alloc() calls malloc)
-#if _MSC_VER >= 1400
-#define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT
-#define FREE_CALL _CRTNOALIAS
-#else
-#define ALLOC_CALL
-#define FREE_CALL
-#endif
-
-extern "C"
-{
-
-ALLOC_CALL void *malloc( size_t nSize )
-{
- return AllocUnattributed( nSize );
-}
-
-FREE_CALL void free( void *pMem )
-{
- g_pMemAlloc->Free(pMem);
-}
-
-ALLOC_CALL void *realloc( void *pMem, size_t nSize )
-{
- return ReallocUnattributed( pMem, nSize );
-}
-
-ALLOC_CALL void *calloc( size_t nCount, size_t nElementSize )
-{
- void *pMem = AllocUnattributed( nElementSize * nCount );
- memset(pMem, 0, nElementSize * nCount);
- return pMem;
-}
-
-} // end extern "C"
-
-//-----------------------------------------------------------------------------
-// Non-standard MSVC functions that we're going to override to call our allocator
-//-----------------------------------------------------------------------------
-extern "C"
-{
-
-// 64-bit
-#ifdef _WIN64
-void* __cdecl _malloc_base( size_t nSize )
-{
- return AllocUnattributed( nSize );
-}
-#else
-void *_malloc_base( size_t nSize )
-{
- return AllocUnattributed( nSize );
-}
-#endif
-
-void *_calloc_base( size_t nSize )
-{
- void *pMem = AllocUnattributed( nSize );
- memset(pMem, 0, nSize);
- return pMem;
-}
-
-void *_realloc_base( void *pMem, size_t nSize )
-{
- return ReallocUnattributed( pMem, nSize );
-}
-
-void *_recalloc_base( void *pMem, size_t nSize )
-{
- void *pMemOut = ReallocUnattributed( pMem, nSize );
- memset(pMemOut, 0, nSize);
- return pMemOut;
-}
-
-void _free_base( void *pMem )
-{
- g_pMemAlloc->Free(pMem);
-}
-
-void *__cdecl _expand_base( void *pMem, size_t nNewSize, int nBlockUse )
-{
- Assert( 0 );
- return NULL;
-}
-
-// crt
-void * __cdecl _malloc_crt(size_t size)
-{
- return AllocUnattributed( size );
-}
-
-void * __cdecl _calloc_crt(size_t count, size_t size)
-{
- return _calloc_base( count * size );
-}
-
-void * __cdecl _realloc_crt(void *ptr, size_t size)
-{
- return _realloc_base( ptr, size );
-}
-
-void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size)
-{
- return _recalloc_base( ptr, size * count );
-}
-
-ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size )
-{
- void *pMem = ReallocUnattributed( memblock, size * count );
- memset( pMem, 0, size * count );
- return pMem;
-}
-
-size_t _msize_base( void *pMem )
-{
- return g_pMemAlloc->GetSize(pMem);
-}
-
-size_t _msize( void *pMem )
-{
- return _msize_base(pMem);
-}
-
-size_t msize( void *pMem )
-{
- return g_pMemAlloc->GetSize(pMem);
-}
-
-void *__cdecl _heap_alloc( size_t nSize )
-{
- return AllocUnattributed( nSize );
-}
-
-void *__cdecl _nh_malloc( size_t nSize, int )
-{
- return AllocUnattributed( nSize );
-}
-
-void *__cdecl _expand( void *pMem, size_t nSize )
-{
- Assert( 0 );
- return NULL;
-}
-
-unsigned int _amblksiz = 16; //BYTES_PER_PARA;
-
-#if _MSC_VER >= 1400
-HANDLE _crtheap = (HANDLE)1; // PatM Can't be 0 or CRT pukes
-int __active_heap = 1;
-#endif // _MSC_VER >= 1400
-
-size_t __cdecl _get_sbh_threshold( void )
-{
- return 0;
-}
-
-int __cdecl _set_sbh_threshold( size_t )
-{
- return 0;
-}
-
-int _heapchk()
-{
- return g_pMemAlloc->heapchk();
-}
-
-int _heapmin()
-{
- return 1;
-}
-
-int __cdecl _heapadd( void *, size_t )
-{
- return 0;
-}
-
-int __cdecl _heapset( unsigned int )
-{
- return 0;
-}
-
-size_t __cdecl _heapused( size_t *, size_t * )
-{
- return 0;
-}
-
-#ifdef _WIN32
-int __cdecl _heapwalk( _HEAPINFO * )
-{
- return 0;
-}
-#endif
-
-} // end extern "C"
-
-
-//-----------------------------------------------------------------------------
-// Debugging functions that we're going to override to call our allocator
-// NOTE: These have to be here for release + debug builds in case we
-// link to a debug static lib!!!
-//-----------------------------------------------------------------------------
-
-extern "C"
-{
-
-void *malloc_db( size_t nSize, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
-}
-
-void free_db( void *pMem, const char *pFileName, int nLine )
-{
- g_pMemAlloc->Free(pMem, pFileName, nLine);
-}
-
-void *realloc_db( void *pMem, size_t nSize, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->Realloc(pMem, nSize, pFileName, nLine);
-}
-
-} // end extern "C"
-
-//-----------------------------------------------------------------------------
-// These methods are standard MSVC heap initialization + shutdown methods
-//-----------------------------------------------------------------------------
-extern "C"
-{
-
-#if !defined( _X360 )
- int __cdecl _heap_init()
- {
- return g_pMemAlloc != NULL;
- }
-
- void __cdecl _heap_term()
- {
- }
-#endif
-
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Prevents us from using an inappropriate new or delete method,
-// ensures they are here even when linking against debug or release static libs
-//-----------------------------------------------------------------------------
-#ifndef NO_MEMOVERRIDE_NEW_DELETE
-#ifdef OSX
-void *__cdecl operator new( size_t nSize ) throw (std::bad_alloc)
-#else
-void *__cdecl operator new( size_t nSize )
-#endif
-{
- return AllocUnattributed( nSize );
-}
-
-void *__cdecl operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
-}
-
-#ifdef OSX
-void __cdecl operator delete( void *pMem ) throw()
-#else
-void __cdecl operator delete( void *pMem )
-#endif
-{
- g_pMemAlloc->Free( pMem );
-}
-
-#ifdef OSX
-void *__cdecl operator new[]( size_t nSize ) throw (std::bad_alloc)
-#else
-void *__cdecl operator new[]( size_t nSize )
-#endif
-{
- return AllocUnattributed( nSize );
-}
-
-void *__cdecl operator new[] ( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
-{
- return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
-}
-
-#ifdef OSX
-void __cdecl operator delete[]( void *pMem ) throw()
-#else
-void __cdecl operator delete[]( void *pMem )
-#endif
-{
- g_pMemAlloc->Free( pMem );
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Override some debugging allocation methods in MSVC
-// NOTE: These have to be here for release + debug builds in case we
-// link to a debug static lib!!!
-//-----------------------------------------------------------------------------
-#ifndef _STATIC_LINKED
-#ifdef _WIN32
-
-// This here just hides the internal file names, etc of allocations
-// made in the c runtime library
-#define CRT_INTERNAL_FILE_NAME "C-runtime internal"
-
-class CAttibCRT
-{
-public:
- CAttibCRT(int nBlockUse) : m_nBlockUse(nBlockUse)
- {
- if (m_nBlockUse == _CRT_BLOCK)
- {
- g_pMemAlloc->PushAllocDbgInfo(CRT_INTERNAL_FILE_NAME, 0);
- }
- }
-
- ~CAttibCRT()
- {
- if (m_nBlockUse == _CRT_BLOCK)
- {
- g_pMemAlloc->PopAllocDbgInfo();
- }
- }
-
-private:
- int m_nBlockUse;
-};
-
-
-#define AttribIfCrt() CAttibCRT _attrib(nBlockUse)
-#elif defined(POSIX)
-#define AttribIfCrt()
-#endif // _WIN32
-
-
-extern "C"
-{
-
-void *__cdecl _nh_malloc_dbg( size_t nSize, int nFlag, int nBlockUse,
- const char *pFileName, int nLine )
-{
- AttribIfCrt();
- return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
-}
-
-void *__cdecl _malloc_dbg( size_t nSize, int nBlockUse,
- const char *pFileName, int nLine )
-{
- AttribIfCrt();
- return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
-}
-
-#if defined( _X360 )
-void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse,
- const char * szFileName, int nLine, int * errno_tmp )
-{
- return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine );
-}
-#endif
-
-void *__cdecl _calloc_dbg( size_t nNum, size_t nSize, int nBlockUse,
- const char *pFileName, int nLine )
-{
- AttribIfCrt();
- void *pMem = g_pMemAlloc->Alloc(nSize * nNum, pFileName, nLine);
- memset(pMem, 0, nSize * nNum);
- return pMem;
-}
-
-void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse,
- const char * szFileName, int nLine, int * errno_tmp )
-{
- return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine );
-}
-
-void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse,
- const char *pFileName, int nLine )
-{
- AttribIfCrt();
- return g_pMemAlloc->Realloc(pMem, nNewSize, pFileName, nLine);
-}
-
-void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse,
- const char *pFileName, int nLine )
-{
- Assert( 0 );
- return NULL;
-}
-
-void __cdecl _free_dbg( void *pMem, int nBlockUse )
-{
- AttribIfCrt();
- g_pMemAlloc->Free(pMem);
-}
-
-size_t __cdecl _msize_dbg( void *pMem, int nBlockUse )
-{
-#ifdef _WIN32
- return _msize(pMem);
-#elif POSIX
- Assert( "_msize_dbg unsupported" );
- return 0;
-#endif
-}
-
-
-#ifdef _WIN32
-
-#if defined(_DEBUG) && _MSC_VER >= 1300
-// X360TBD: aligned and offset allocations may be important on the 360
-
-// aligned base
-ALLOC_CALL void *__cdecl _aligned_malloc_base( size_t size, size_t align )
-{
- return MemAlloc_AllocAligned( size, align );
-}
-
-ALLOC_CALL void *__cdecl _aligned_realloc_base( void *ptr, size_t size, size_t align )
-{
- return MemAlloc_ReallocAligned( ptr, size, align );
-}
-
-ALLOC_CALL void *__cdecl _aligned_recalloc_base( void *ptr, size_t size, size_t align )
-{
- Error( "Unsupported function\n" );
- return NULL;
-}
-
-FREE_CALL void __cdecl _aligned_free_base( void *ptr )
-{
- MemAlloc_FreeAligned( ptr );
-}
-
-// aligned
-ALLOC_CALL void * __cdecl _aligned_malloc( size_t size, size_t align )
-{
- return _aligned_malloc_base(size, align);
-}
-
-ALLOC_CALL void *__cdecl _aligned_realloc(void *memblock, size_t size, size_t align)
-{
- return _aligned_realloc_base(memblock, size, align);
-}
-
-ALLOC_CALL void * __cdecl _aligned_recalloc( void * memblock, size_t count, size_t size, size_t align )
-{
- return _aligned_recalloc_base(memblock, count * size, align);
-}
-
-FREE_CALL void __cdecl _aligned_free( void *memblock )
-{
- _aligned_free_base(memblock);
-}
-
-// aligned offset base
-ALLOC_CALL void * __cdecl _aligned_offset_malloc_base( size_t size, size_t align, size_t offset )
-{
- Assert( IsPC() || 0 );
- return NULL;
-}
-
-ALLOC_CALL void * __cdecl _aligned_offset_realloc_base( void * memblock, size_t size, size_t align, size_t offset)
-{
- Assert( IsPC() || 0 );
- return NULL;
-}
-
-ALLOC_CALL void * __cdecl _aligned_offset_recalloc_base( void * memblock, size_t size, size_t align, size_t offset)
-{
- Assert( IsPC() || 0 );
- return NULL;
-}
-
-// aligned offset
-ALLOC_CALL void *__cdecl _aligned_offset_malloc(size_t size, size_t align, size_t offset)
-{
- return _aligned_offset_malloc_base( size, align, offset );
-}
-
-ALLOC_CALL void *__cdecl _aligned_offset_realloc(void *memblock, size_t size, size_t align, size_t offset)
-{
- return _aligned_offset_realloc_base( memblock, size, align, offset );
-}
-
-ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t count, size_t size, size_t align, size_t offset )
-{
- return _aligned_offset_recalloc_base( memblock, count * size, align, offset );
-}
-
-#endif // _MSC_VER >= 1400
-
-#endif
-
-} // end extern "C"
-
-
-//-----------------------------------------------------------------------------
-// Override some the _CRT debugging allocation methods in MSVC
-//-----------------------------------------------------------------------------
-#ifdef _WIN32
-
-extern "C"
-{
-
-int _CrtDumpMemoryLeaks(void)
-{
- return 0;
-}
-
-_CRT_DUMP_CLIENT _CrtSetDumpClient( _CRT_DUMP_CLIENT dumpClient )
-{
- return NULL;
-}
-
-int _CrtSetDbgFlag( int nNewFlag )
-{
- return g_pMemAlloc->CrtSetDbgFlag( nNewFlag );
-}
-
-// 64-bit port.
-#define AFNAME(var) __p_ ## var
-#define AFRET(var) &var
-
-int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF;
-int* AFNAME(_crtDbgFlag)(void)
-{
- return AFRET(_crtDbgFlag);
-}
-
-long _crtBreakAlloc; /* Break on this allocation */
-long* AFNAME(_crtBreakAlloc) (void)
-{
- return AFRET(_crtBreakAlloc);
-}
-
-void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse )
-{
- DebuggerBreak();
-}
-
-_CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook )
-{
- DebuggerBreak();
- return NULL;
-}
-
-long __cdecl _CrtSetBreakAlloc( long lNewBreakAlloc )
-{
- return g_pMemAlloc->CrtSetBreakAlloc( lNewBreakAlloc );
-}
-
-int __cdecl _CrtIsValidHeapPointer( const void *pMem )
-{
- return g_pMemAlloc->CrtIsValidHeapPointer( pMem );
-}
-
-int __cdecl _CrtIsValidPointer( const void *pMem, unsigned int size, int access )
-{
- return g_pMemAlloc->CrtIsValidPointer( pMem, size, access );
-}
-
-int __cdecl _CrtCheckMemory( void )
-{
- // FIXME: Remove this when we re-implement the heap
- return g_pMemAlloc->CrtCheckMemory( );
-}
-
-int __cdecl _CrtIsMemoryBlock( const void *pMem, unsigned int nSize,
- long *plRequestNumber, char **ppFileName, int *pnLine )
-{
- DebuggerBreak();
- return 1;
-}
-
-int __cdecl _CrtMemDifference( _CrtMemState *pState, const _CrtMemState * oldState, const _CrtMemState * newState )
-{
- DebuggerBreak();
- return FALSE;
-}
-
-void __cdecl _CrtMemDumpStatistics( const _CrtMemState *pState )
-{
- DebuggerBreak();
-}
-
-void __cdecl _CrtMemCheckpoint( _CrtMemState *pState )
-{
- // FIXME: Remove this when we re-implement the heap
- g_pMemAlloc->CrtMemCheckpoint( pState );
-}
-
-void __cdecl _CrtMemDumpAllObjectsSince( const _CrtMemState *pState )
-{
- DebuggerBreak();
-}
-
-void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pContext )
-{
- DebuggerBreak();
-}
-
-
-//-----------------------------------------------------------------------------
-// Methods in dbgrpt.cpp
-//-----------------------------------------------------------------------------
-long _crtAssertBusy = -1;
-
-int __cdecl _CrtSetReportMode( int nReportType, int nReportMode )
-{
- return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode );
-}
-
-_HFILE __cdecl _CrtSetReportFile( int nRptType, _HFILE hFile )
-{
- return (_HFILE)g_pMemAlloc->CrtSetReportFile( nRptType, hFile );
-}
-
-_CRT_REPORT_HOOK __cdecl _CrtSetReportHook( _CRT_REPORT_HOOK pfnNewHook )
-{
- return (_CRT_REPORT_HOOK)g_pMemAlloc->CrtSetReportHook( pfnNewHook );
-}
-
-int __cdecl _CrtDbgReport( int nRptType, const char * szFile,
- int nLine, const char * szModule, const char * szFormat, ... )
-{
- static char output[1024];
- va_list args;
- if ( szFormat )
- {
- va_start( args, szFormat );
- _vsnprintf( output, sizeof( output )-1, szFormat, args );
- va_end( args );
- }
- else
- {
- output[0] = 0;
- }
-
- return g_pMemAlloc->CrtDbgReport( nRptType, szFile, nLine, szModule, output );
-}
-
-#if _MSC_VER >= 1400
-
-// Configure VS so that it will record crash dumps on pure-call violations
-// and invalid parameter handlers.
-// If you manage to call a pure-virtual function (easily done if you indirectly
-// call a pure-virtual function from the base-class constructor or destructor)
-// or if you invoke the invalid parameter handler (printf(NULL); is one way)
-// then no crash dump will be created.
-// This crash redirects the handlers for these two events so that crash dumps
-// are created.
-//
-// The ErrorHandlerRegistrar object must be in memoverride.cpp so that it will
-// be placed in every DLL and EXE. This is required because each DLL and EXE
-// gets its own copy of the C run-time and these overrides are set on a per-CRT
-// basis.
-
-/*
-// This sample code will cause pure-call and invalid_parameter violations and
-// was used for testing:
-class Base
-{
-public:
- virtual void PureFunction() = 0;
-
- Base()
- {
- NonPureFunction();
- }
-
- void NonPureFunction()
- {
- PureFunction();
- }
-};
-
-class Derived : public Base
-{
-public:
- void PureFunction() OVERRIDE
- {
- }
-};
-
-void PureCallViolation()
-{
- Derived derived;
-}
-
-void InvalidParameterViolation()
-{
- printf( NULL );
-}
-*/
-
-#include <stdlib.h>
-#include "minidump.h"
-
-// Disable compiler optimizations. If we don't do this then VC++ generates code
-// that confuses the Visual Studio debugger and causes it to display completely
-// random call stacks. That makes the minidumps excruciatingly hard to understand.
-#pragma optimize("", off)
-
-// Write a minidump file, unless running under the debugger in which case break
-// into the debugger.
-// The "int dummy" parameter is so that the callers can be unique so that the
-// linker won't use its /opt:icf optimization to collapse them together. This
-// makes reading the call stack easier.
-void __cdecl WriteMiniDumpOrBreak( int dummy, const char *pchName )
-{
- if ( Plat_IsInDebugSession() )
- {
- __debugbreak();
- // Continue at your peril...
- }
- else
- {
- WriteMiniDump( pchName );
- // Call Plat_ExitProcess so we don't continue in a bad state.
- TerminateProcess(GetCurrentProcess(), 0);
- }
-}
-
-void __cdecl VPureCall()
-{
- WriteMiniDumpOrBreak( 0, "PureClass" );
-}
-
-void VInvalidParameterHandler(const wchar_t* expression,
- const wchar_t* function,
- const wchar_t* file,
- unsigned int line,
- uintptr_t pReserved)
-{
- WriteMiniDumpOrBreak( 1, "InvalidParameterHandler" );
-}
-
-// Restore compiler optimizations.
-#pragma optimize("", on)
-
-// Helper class for registering error callbacks. See above for details.
-class ErrorHandlerRegistrar
-{
-public:
- ErrorHandlerRegistrar();
-} s_ErrorHandlerRegistration;
-
-ErrorHandlerRegistrar::ErrorHandlerRegistrar()
-{
- _set_purecall_handler( VPureCall );
- _set_invalid_parameter_handler( VInvalidParameterHandler );
-}
-
-#if defined( _DEBUG )
-
-// wrapper which passes no debug info; not available in debug
-#ifndef SUPPRESS_INVALID_PARAMETER_NO_INFO
-void __cdecl _invalid_parameter_noinfo(void)
-{
- Assert(0);
-}
-#endif
-
-#endif /* defined( _DEBUG ) */
-
-#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
-
-int __cdecl __crtMessageWindowW( int nRptType, const wchar_t * szFile, const wchar_t * szLine,
- const wchar_t * szModule, const wchar_t * szUserMessage )
-{
- Assert(0);
- return 0;
-}
-
-int __cdecl _CrtDbgReportV( int nRptType, const wchar_t *szFile, int nLine,
- const wchar_t *szModule, const wchar_t *szFormat, va_list arglist )
-{
- Assert(0);
- return 0;
-}
-
-int __cdecl _CrtDbgReportW( int nRptType, const wchar_t *szFile, int nLine,
- const wchar_t *szModule, const wchar_t *szFormat, ...)
-{
- Assert(0);
- return 0;
-}
-
-int __cdecl _VCrtDbgReportA( int nRptType, const wchar_t * szFile, int nLine,
- const wchar_t * szModule, const wchar_t * szFormat, va_list arglist )
-{
- Assert(0);
- return 0;
-}
-
-int __cdecl _CrtSetReportHook2( int mode, _CRT_REPORT_HOOK pfnNewHook )
-{
- _CrtSetReportHook( pfnNewHook );
- return 0;
-}
-
-
-#endif /* defined( _DEBUG ) || defined( USE_MEM_DEBUG ) */
-
-extern "C" int __crtDebugCheckCount = FALSE;
-
-extern "C" int __cdecl _CrtSetCheckCount( int fCheckCount )
-{
- int oldCheckCount = __crtDebugCheckCount;
- return oldCheckCount;
-}
-
-extern "C" int __cdecl _CrtGetCheckCount( void )
-{
- return __crtDebugCheckCount;
-}
-
-// aligned offset debug
-extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n )
-{
- Assert( IsPC() || 0 );
- void *pMem = ReallocUnattributed( memblock, size * count );
- memset( pMem, 0, size * count );
- return pMem;
-}
-
-extern "C" void * __cdecl _aligned_recalloc_dbg( void *memblock, size_t count, size_t size, size_t align, const char * f_name, int line_n )
-{
- return _aligned_offset_recalloc_dbg(memblock, count, size, align, 0, f_name, line_n);
-}
-
-extern "C" void * __cdecl _recalloc_dbg ( void * memblock, size_t count, size_t size, int nBlockUse, const char * szFileName, int nLine )
-{
- return _aligned_offset_recalloc_dbg(memblock, count, size, 0, 0, szFileName, nLine);
-}
-
-_CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void )
-{
- return NULL;
-}
-
-#endif
-int __cdecl _CrtReportBlockType(const void * pUserData)
-{
- return 0;
-}
-
-
-} // end extern "C"
-#endif // _WIN32
-
-// Most files include this file, so when it's used it adds an extra .ValveDbg section,
-// to help identify debug binaries.
-#ifdef _WIN32
- #ifndef NDEBUG // _DEBUG
- #pragma data_seg("ValveDBG")
- volatile const char* DBG = "*** DEBUG STUB ***";
- #endif
-#endif
-
-#endif
-
-// Extras added prevent dbgheap.obj from being included - DAL
-#ifdef _WIN32
-
-extern "C"
-{
-size_t __crtDebugFillThreshold = 0;
-
-extern "C" void * __cdecl _heap_alloc_base (size_t size) {
- assert(0);
- return NULL;
-}
-
-
-void * __cdecl _heap_alloc_dbg( size_t nSize, int nBlockUse, const char * szFileName, int nLine)
-{
- return _heap_alloc(nSize);
-}
-
-// 64-bit
-#ifdef _WIN64
-static void * __cdecl realloc_help( void * pUserData, size_t * pnNewSize, int nBlockUse,const char * szFileName,
- int nLine, int fRealloc )
-{
- assert(0); // Shouldn't be needed
- return NULL;
-}
-#else
-static void * __cdecl realloc_help( void * pUserData, size_t nNewSize, int nBlockUse, const char * szFileName,
- int nLine, int fRealloc)
-{
- assert(0); // Shouldn't be needed
- return NULL;
-}
-#endif
-
-void __cdecl _free_nolock( void * pUserData)
-{
- // I don't think the second param is used in memoverride
- _free_dbg(pUserData, 0);
-}
-
-void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse)
-{
- _free_dbg(pUserData, 0);
-}
-
-_CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void)
-{
- assert(0);
- return NULL;
-}
-
-static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize)
-{
- int bOkay = TRUE;
- return bOkay;
-}
-
-
-_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void)
-{
- assert(0);
- return NULL;
-}
-
-#if _MSC_VER >= 1400
-static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead)
-{
-}
-
-static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, _locale_t plocinfo)
-{
-}
-#endif
-void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n)
-{
- return _aligned_malloc(size, align);
-}
-
-void * __cdecl _aligned_realloc_dbg( void *memblock, size_t size, size_t align,
- const char * f_name, int line_n)
-{
- return _aligned_realloc(memblock, size, align);
-}
-
-void * __cdecl _aligned_offset_malloc_dbg( size_t size, size_t align, size_t offset,
- const char * f_name, int line_n)
-{
- return _aligned_offset_malloc(size, align, offset);
-}
-
-void * __cdecl _aligned_offset_realloc_dbg( void * memblock, size_t size, size_t align,
- size_t offset, const char * f_name, int line_n)
-{
- return _aligned_offset_realloc(memblock, size, align, offset);
-}
-
-void __cdecl _aligned_free_dbg( void * memblock)
-{
- _aligned_free(memblock);
-}
-
-size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold)
-{
- assert(0);
- return 0;
-}
-
-//===========================================
-// NEW!!! 64-bit
-
-char * __cdecl _strdup ( const char * string )
-{
- int nSize = (int)strlen(string) + 1;
- // Check for integer underflow.
- if ( nSize <= 0 )
- return NULL;
- char *pCopy = (char*)AllocUnattributed( nSize );
- if ( pCopy )
- memcpy( pCopy, string, nSize );
- return pCopy;
-}
-
-#if 0
-_TSCHAR * __cdecl _tfullpath_dbg ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen, int nBlockUse, const char * szFileName, int nLine )
-{
- Assert(0);
- return NULL;
-}
-
-_TSCHAR * __cdecl _tfullpath ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen )
-{
- Assert(0);
- return NULL;
-}
-
-_TSCHAR * __cdecl _tgetdcwd_lk_dbg ( int drive, _TSCHAR *pnbuf, int maxlen, int nBlockUse, const char * szFileName, int nLine )
-{
- Assert(0);
- return NULL;
-}
-
-_TSCHAR * __cdecl _tgetdcwd_nolock ( int drive, _TSCHAR *pnbuf, int maxlen )
-{
- Assert(0);
- return NULL;
-}
-
-errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname, int nBlockUse, const char * szFileName, int nLine )
-{
- Assert(0);
- return 0;
-}
-
-errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname )
-{
- Assert(0);
- return 0;
-}
-
-_TSCHAR * __cdecl _ttempnam_dbg ( const _TSCHAR *dir, const _TSCHAR *pfx, int nBlockUse, const char * szFileName, int nLine )
-{
- Assert(0);
- return 0;
-}
-
-_TSCHAR * __cdecl _ttempnam ( const _TSCHAR *dir, const _TSCHAR *pfx )
-{
- Assert(0);
- return 0;
-}
-#endif
-
-wchar_t * __cdecl _wcsdup_dbg ( const wchar_t * string, int nBlockUse, const char * szFileName, int nLine )
-{
- Assert(0);
- return 0;
-}
-
-wchar_t * __cdecl _wcsdup ( const wchar_t * string )
-{
- Assert(0);
- return 0;
-}
-
-} // end extern "C"
-
-#if _MSC_VER >= 1400
-
-//-----------------------------------------------------------------------------
-// XBox Memory Allocator Override
-//-----------------------------------------------------------------------------
-#if defined( _X360 )
-#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
-#include "utlmap.h"
-
-MEMALLOC_DEFINE_EXTERNAL_TRACKING( XMem );
-
-CThreadFastMutex g_XMemAllocMutex;
-
-void XMemAlloc_RegisterAllocation( void *p, DWORD dwAllocAttributes )
-{
- if ( !g_pMemAlloc )
- {
- // core xallocs cannot be journaled until system is ready
- return;
- }
-
- AUTO_LOCK_FM( g_XMemAllocMutex );
- int size = XMemSize( p, dwAllocAttributes );
- MemAlloc_RegisterExternalAllocation( XMem, p, size );
-}
-
-void XMemAlloc_RegisterDeallocation( void *p, DWORD dwAllocAttributes )
-{
- if ( !g_pMemAlloc )
- {
- // core xallocs cannot be journaled until system is ready
- return;
- }
-
- AUTO_LOCK_FM( g_XMemAllocMutex );
- int size = XMemSize( p, dwAllocAttributes );
- MemAlloc_RegisterExternalDeallocation( XMem, p, size );
-}
-
-#else
-
-#define XMemAlloc_RegisterAllocation( p, a ) ((void)0)
-#define XMemAlloc_RegisterDeallocation( p, a ) ((void)0)
-
-#endif
-
-//-----------------------------------------------------------------------------
-// XMemAlloc
-//
-// XBox Memory Allocator Override
-//-----------------------------------------------------------------------------
-LPVOID WINAPI XMemAlloc( SIZE_T dwSize, DWORD dwAllocAttributes )
-{
- LPVOID ptr;
- XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
- bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
-
- if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
- {
- MEM_ALLOC_CREDIT();
- switch ( pAttribs->dwAlignment )
- {
- case XALLOC_ALIGNMENT_4:
- ptr = g_pMemAlloc->Alloc( dwSize );
- break;
- case XALLOC_ALIGNMENT_8:
- ptr = MemAlloc_AllocAligned( dwSize, 8 );
- break;
- case XALLOC_ALIGNMENT_DEFAULT:
- case XALLOC_ALIGNMENT_16:
- default:
- ptr = MemAlloc_AllocAligned( dwSize, 16 );
- break;
- }
- if ( pAttribs->dwZeroInitialize != 0 )
- {
- memset( ptr, 0, XMemSize( ptr, dwAllocAttributes ) );
- }
- return ptr;
- }
-
- ptr = XMemAllocDefault( dwSize, dwAllocAttributes );
- if ( ptr )
- {
- XMemAlloc_RegisterAllocation( ptr, dwAllocAttributes );
- }
-
- return ptr;
-}
-
-//-----------------------------------------------------------------------------
-// XMemFree
-//
-// XBox Memory Allocator Override
-//-----------------------------------------------------------------------------
-VOID WINAPI XMemFree( PVOID pAddress, DWORD dwAllocAttributes )
-{
- if ( !pAddress )
- {
- return;
- }
-
- XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
- bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
-
- if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
- {
- switch ( pAttribs->dwAlignment )
- {
- case XALLOC_ALIGNMENT_4:
- return g_pMemAlloc->Free( pAddress );
- default:
- return MemAlloc_FreeAligned( pAddress );
- }
- return;
- }
-
- XMemAlloc_RegisterDeallocation( pAddress, dwAllocAttributes );
-
- XMemFreeDefault( pAddress, dwAllocAttributes );
-}
-
-//-----------------------------------------------------------------------------
-// XMemSize
-//
-// XBox Memory Allocator Override
-//-----------------------------------------------------------------------------
-SIZE_T WINAPI XMemSize( PVOID pAddress, DWORD dwAllocAttributes )
-{
- XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
- bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
-
- if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
- {
- switch ( pAttribs->dwAlignment )
- {
- case XALLOC_ALIGNMENT_4:
- return g_pMemAlloc->GetSize( pAddress );
- default:
- return MemAlloc_GetSizeAligned( pAddress );
- }
- }
-
- return XMemSizeDefault( pAddress, dwAllocAttributes );
-}
-#endif // _X360
-
-#define MAX_LANG_LEN 64 /* max language name length */
-#define MAX_CTRY_LEN 64 /* max country name length */
-#define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */
-#define MAX_LC_LEN (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
-
-#if _MSC_VER >= 1700 // VS 11
-// Copied from C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\mtdll.h
-#ifndef _SETLOC_STRUCT_DEFINED
-struct _is_ctype_compatible {
- unsigned long id;
- int is_clike;
-};
-
-typedef struct setloc_struct {
- /* getqloc static variables */
- wchar_t *pchLanguage;
- wchar_t *pchCountry;
- int iLocState;
- int iPrimaryLen;
- BOOL bAbbrevLanguage;
- BOOL bAbbrevCountry;
- UINT _cachecp;
- wchar_t _cachein[MAX_LC_LEN];
- wchar_t _cacheout[MAX_LC_LEN];
- /* _setlocale_set_cat (LC_CTYPE) static variable */
- struct _is_ctype_compatible _Loc_c[5];
- wchar_t _cacheLocaleName[LOCALE_NAME_MAX_LENGTH];
-} _setloc_struct, *_psetloc_struct;
-#define _SETLOC_STRUCT_DEFINED
-#endif /* _SETLOC_STRUCT_DEFINED */
-
-_CRTIMP extern unsigned long __cdecl __threadid(void);
-#define _threadid (__threadid())
-_CRTIMP extern uintptr_t __cdecl __threadhandle(void);
-#define _threadhandle (__threadhandle())
-
-/* Structure for each thread's data */
-
-struct _tiddata {
- unsigned long _tid; /* thread ID */
-
-
- uintptr_t _thandle; /* thread handle */
-
- int _terrno; /* errno value */
- unsigned long _tdoserrno; /* _doserrno value */
- unsigned int _fpds; /* Floating Point data segment */
- unsigned long _holdrand; /* rand() seed value */
- char * _token; /* ptr to strtok() token */
- wchar_t * _wtoken; /* ptr to wcstok() token */
- unsigned char * _mtoken; /* ptr to _mbstok() token */
-
- /* following pointers get malloc'd at runtime */
- char * _errmsg; /* ptr to strerror()/_strerror() buff */
- wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
- char * _namebuf0; /* ptr to tmpnam() buffer */
- wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
- char * _namebuf1; /* ptr to tmpfile() buffer */
- wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
- char * _asctimebuf; /* ptr to asctime() buffer */
- wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
- void * _gmtimebuf; /* ptr to gmtime() structure */
- char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
- unsigned char _con_ch_buf[MB_LEN_MAX];
- /* ptr to putch() buffer */
- unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
-
- /* following fields are needed by _beginthread code */
- void * _initaddr; /* initial user thread address */
- void * _initarg; /* initial user thread argument */
-
- /* following three fields are needed to support signal handling and
- * runtime errors */
- void * _pxcptacttab; /* ptr to exception-action table */
- void * _tpxcptinfoptrs; /* ptr to exception info pointers */
- int _tfpecode; /* float point exception code */
-
- /* pointer to the copy of the multibyte character information used by
- * the thread */
- pthreadmbcinfo ptmbcinfo;
-
- /* pointer to the copy of the locale informaton used by the thead */
- pthreadlocinfo ptlocinfo;
- int _ownlocale; /* if 1, this thread owns its own locale */
-
- /* following field is needed by NLG routines */
- unsigned long _NLG_dwCode;
-
- /*
- * Per-Thread data needed by C++ Exception Handling
- */
- void * _terminate; /* terminate() routine */
- void * _unexpected; /* unexpected() routine */
- void * _translator; /* S.E. translator */
- void * _purecall; /* called when pure virtual happens */
- void * _curexception; /* current exception */
- void * _curcontext; /* current exception context */
- int _ProcessingThrow; /* for uncaught_exception */
- void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
-#if defined (_M_X64) || defined (_M_ARM)
- void * _pExitContext;
- void * _pUnwindContext;
- void * _pFrameInfoChain;
-#if defined (_WIN64)
- unsigned __int64 _ImageBase;
- unsigned __int64 _ThrowImageBase;
-#else /* defined (_WIN64) */
- unsigned __int32 _ImageBase;
- unsigned __int32 _ThrowImageBase;
-#endif /* defined (_WIN64) */
- void * _pForeignException;
-#elif defined (_M_IX86)
- void * _pFrameInfoChain;
-#endif /* defined (_M_IX86) */
- _setloc_struct _setloc_data;
-
- void * _reserved1; /* nothing */
- void * _reserved2; /* nothing */
- void * _reserved3; /* nothing */
-#ifdef _M_IX86
- void * _reserved4; /* nothing */
- void * _reserved5; /* nothing */
-#endif /* _M_IX86 */
-
- int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
-
- unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
-};
-#else
-struct _is_ctype_compatible {
- unsigned long id;
- int is_clike;
-};
-
-typedef struct setloc_struct {
- /* getqloc static variables */
- char *pchLanguage;
- char *pchCountry;
- int iLcidState;
- int iPrimaryLen;
- BOOL bAbbrevLanguage;
- BOOL bAbbrevCountry;
- LCID lcidLanguage;
- LCID lcidCountry;
- /* expand_locale static variables */
- LC_ID _cacheid;
- UINT _cachecp;
- char _cachein[MAX_LC_LEN];
- char _cacheout[MAX_LC_LEN];
- /* _setlocale_set_cat (LC_CTYPE) static variable */
- struct _is_ctype_compatible _Lcid_c[5];
-} _setloc_struct, *_psetloc_struct;
-
-struct _tiddata {
- unsigned long _tid; /* thread ID */
-
-
- uintptr_t _thandle; /* thread handle */
-
- int _terrno; /* errno value */
- unsigned long _tdoserrno; /* _doserrno value */
- unsigned int _fpds; /* Floating Point data segment */
- unsigned long _holdrand; /* rand() seed value */
- char * _token; /* ptr to strtok() token */
- wchar_t * _wtoken; /* ptr to wcstok() token */
- unsigned char * _mtoken; /* ptr to _mbstok() token */
-
- /* following pointers get malloc'd at runtime */
- char * _errmsg; /* ptr to strerror()/_strerror() buff */
- wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
- char * _namebuf0; /* ptr to tmpnam() buffer */
- wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
- char * _namebuf1; /* ptr to tmpfile() buffer */
- wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
- char * _asctimebuf; /* ptr to asctime() buffer */
- wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
- void * _gmtimebuf; /* ptr to gmtime() structure */
- char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
- unsigned char _con_ch_buf[MB_LEN_MAX];
- /* ptr to putch() buffer */
- unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
-
- /* following fields are needed by _beginthread code */
- void * _initaddr; /* initial user thread address */
- void * _initarg; /* initial user thread argument */
-
- /* following three fields are needed to support signal handling and
- * runtime errors */
- void * _pxcptacttab; /* ptr to exception-action table */
- void * _tpxcptinfoptrs; /* ptr to exception info pointers */
- int _tfpecode; /* float point exception code */
-
- /* pointer to the copy of the multibyte character information used by
- * the thread */
- pthreadmbcinfo ptmbcinfo;
-
- /* pointer to the copy of the locale informaton used by the thead */
- pthreadlocinfo ptlocinfo;
- int _ownlocale; /* if 1, this thread owns its own locale */
-
- /* following field is needed by NLG routines */
- unsigned long _NLG_dwCode;
-
- /*
- * Per-Thread data needed by C++ Exception Handling
- */
- void * _terminate; /* terminate() routine */
- void * _unexpected; /* unexpected() routine */
- void * _translator; /* S.E. translator */
- void * _purecall; /* called when pure virtual happens */
- void * _curexception; /* current exception */
- void * _curcontext; /* current exception context */
- int _ProcessingThrow; /* for uncaught_exception */
- void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
-#if defined (_M_IA64) || defined (_M_AMD64)
- void * _pExitContext;
- void * _pUnwindContext;
- void * _pFrameInfoChain;
- unsigned __int64 _ImageBase;
-#if defined (_M_IA64)
- unsigned __int64 _TargetGp;
-#endif /* defined (_M_IA64) */
- unsigned __int64 _ThrowImageBase;
- void * _pForeignException;
-#elif defined (_M_IX86)
- void * _pFrameInfoChain;
-#endif /* defined (_M_IX86) */
- _setloc_struct _setloc_data;
-
- void * _encode_ptr; /* EncodePointer() routine */
- void * _decode_ptr; /* DecodePointer() routine */
-
- void * _reserved1; /* nothing */
- void * _reserved2; /* nothing */
- void * _reserved3; /* nothing */
-
- int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
-
- unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
-};
-#endif
-
-typedef struct _tiddata * _ptiddata;
-
-class _LocaleUpdate
-{
- _locale_tstruct localeinfo;
- _ptiddata ptd;
- bool updated;
- public:
- _LocaleUpdate(_locale_t plocinfo)
- : updated(false)
- {
- /*
- if (plocinfo == NULL)
- {
- ptd = _getptd();
- localeinfo.locinfo = ptd->ptlocinfo;
- localeinfo.mbcinfo = ptd->ptmbcinfo;
-
- __UPDATE_LOCALE(ptd, localeinfo.locinfo);
- __UPDATE_MBCP(ptd, localeinfo.mbcinfo);
- if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT))
- {
- ptd->_ownlocale |= _PER_THREAD_LOCALE_BIT;
- updated = true;
- }
- }
- else
- {
- localeinfo=*plocinfo;
- }
- */
- }
- ~_LocaleUpdate()
- {
-// if (updated)
-// ptd->_ownlocale = ptd->_ownlocale & ~_PER_THREAD_LOCALE_BIT;
- }
- _locale_t GetLocaleT()
- {
- return &localeinfo;
- }
-};
-
-
-#pragma warning(push)
-#pragma warning(disable: 4483)
-#if _MSC_FULL_VER >= 140050415
-#define _NATIVE_STARTUP_NAMESPACE __identifier("<CrtImplementationDetails>")
-#else /* _MSC_FULL_VER >= 140050415 */
-#define _NATIVE_STARTUP_NAMESPACE __CrtImplementationDetails
-#endif /* _MSC_FULL_VER >= 140050415 */
-
-namespace _NATIVE_STARTUP_NAMESPACE
-{
- class NativeDll
- {
- private:
- static const unsigned int ProcessDetach = 0;
- static const unsigned int ProcessAttach = 1;
- static const unsigned int ThreadAttach = 2;
- static const unsigned int ThreadDetach = 3;
- static const unsigned int ProcessVerifier = 4;
-
- public:
-
- inline static bool IsInDllMain()
- {
- return false;
- }
-
- inline static bool IsInProcessAttach()
- {
- return false;
- }
-
- inline static bool IsInProcessDetach()
- {
- return false;
- }
-
- inline static bool IsInVcclrit()
- {
- return false;
- }
-
- inline static bool IsSafeForManagedCode()
- {
- if (!IsInDllMain())
- {
- return true;
- }
-
- if (IsInVcclrit())
- {
- return true;
- }
-
- return !IsInProcessAttach() && !IsInProcessDetach();
- }
- };
-}
-#pragma warning(pop)
-
-#endif // _MSC_VER >= 1400
-
-#endif // !STEAM && !NO_MALLOC_OVERRIDE
-
-#endif // _WIN32
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Insert this file into all projects using the memory system
+// It will cause that project to use the shader memory allocator
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
+
+#undef PROTECTED_THINGS_ENABLE // allow use of _vsnprintf
+
+#if defined( _WIN32 ) && !defined( _X360 )
+#define WIN_32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "tier0/dbg.h"
+#include "tier0/memalloc.h"
+#include <string.h>
+#include <stdio.h>
+#include "memdbgoff.h"
+
+#ifdef _WIN32
+// ARG: crtdbg is necessary for certain definitions below,
+// but it also redefines malloc as a macro in release.
+// To disable this, we gotta define _DEBUG before including it.. BLEAH!
+#define _DEBUG 1
+#include "crtdbg.h"
+#ifdef NDEBUG
+#undef _DEBUG
+#endif
+
+// Turn this back off in release mode.
+#ifdef NDEBUG
+#undef _DEBUG
+#endif
+#elif POSIX
+#define __cdecl
+#endif
+
+#if defined( _WIN32 ) && !defined( _X360 )
+const char *MakeModuleFileName()
+{
+ if ( g_pMemAlloc->IsDebugHeap() )
+ {
+ char *pszModuleName = (char *)HeapAlloc( GetProcessHeap(), 0, MAX_PATH ); // small leak, debug only
+
+ MEMORY_BASIC_INFORMATION mbi;
+ static int dummy;
+ VirtualQuery( &dummy, &mbi, sizeof(mbi) );
+
+ GetModuleFileName( reinterpret_cast<HMODULE>(mbi.AllocationBase), pszModuleName, MAX_PATH );
+ char *pDot = strrchr( pszModuleName, '.' );
+ if ( pDot )
+ {
+ char *pSlash = strrchr( pszModuleName, '\\' );
+ if ( pSlash )
+ {
+ pszModuleName = pSlash + 1;
+ *pDot = 0;
+ }
+ }
+
+ return pszModuleName;
+ }
+ return NULL;
+}
+
+static void *AllocUnattributed( size_t nSize )
+{
+ static const char *pszOwner = MakeModuleFileName();
+
+ if ( !pszOwner )
+ return g_pMemAlloc->Alloc(nSize);
+ else
+ return g_pMemAlloc->Alloc(nSize, pszOwner, 0);
+}
+
+static void *ReallocUnattributed( void *pMem, size_t nSize )
+{
+ static const char *pszOwner = MakeModuleFileName();
+
+ if ( !pszOwner )
+ return g_pMemAlloc->Realloc(pMem, nSize);
+ else
+ return g_pMemAlloc->Realloc(pMem, nSize, pszOwner, 0);
+}
+
+#else
+#define MakeModuleFileName() NULL
+inline void *AllocUnattributed( size_t nSize )
+{
+ return g_pMemAlloc->Alloc(nSize);
+}
+
+inline void *ReallocUnattributed( void *pMem, size_t nSize )
+{
+ return g_pMemAlloc->Realloc(pMem, nSize);
+}
+#endif
+
+//-----------------------------------------------------------------------------
+// Standard functions in the CRT that we're going to override to call our allocator
+//-----------------------------------------------------------------------------
+#if defined(_WIN32) && !defined(_STATIC_LINKED)
+// this magic only works under win32
+// under linux this malloc() overrides the libc malloc() and so we
+// end up in a recursion (as g_pMemAlloc->Alloc() calls malloc)
+#if _MSC_VER >= 1400
+#define ALLOC_CALL _CRTNOALIAS _CRTRESTRICT
+#define FREE_CALL _CRTNOALIAS
+#else
+#define ALLOC_CALL
+#define FREE_CALL
+#endif
+
+extern "C"
+{
+
+ALLOC_CALL void *malloc( size_t nSize )
+{
+ return AllocUnattributed( nSize );
+}
+
+FREE_CALL void free( void *pMem )
+{
+ g_pMemAlloc->Free(pMem);
+}
+
+ALLOC_CALL void *realloc( void *pMem, size_t nSize )
+{
+ return ReallocUnattributed( pMem, nSize );
+}
+
+ALLOC_CALL void *calloc( size_t nCount, size_t nElementSize )
+{
+ void *pMem = AllocUnattributed( nElementSize * nCount );
+ memset(pMem, 0, nElementSize * nCount);
+ return pMem;
+}
+
+} // end extern "C"
+
+//-----------------------------------------------------------------------------
+// Non-standard MSVC functions that we're going to override to call our allocator
+//-----------------------------------------------------------------------------
+extern "C"
+{
+
+// 64-bit
+#ifdef _WIN64
+void* __cdecl _malloc_base( size_t nSize )
+{
+ return AllocUnattributed( nSize );
+}
+#else
+void *_malloc_base( size_t nSize )
+{
+ return AllocUnattributed( nSize );
+}
+#endif
+
+void *_calloc_base( size_t nSize )
+{
+ void *pMem = AllocUnattributed( nSize );
+ memset(pMem, 0, nSize);
+ return pMem;
+}
+
+void *_realloc_base( void *pMem, size_t nSize )
+{
+ return ReallocUnattributed( pMem, nSize );
+}
+
+void *_recalloc_base( void *pMem, size_t nSize )
+{
+ void *pMemOut = ReallocUnattributed( pMem, nSize );
+ memset(pMemOut, 0, nSize);
+ return pMemOut;
+}
+
+void _free_base( void *pMem )
+{
+ g_pMemAlloc->Free(pMem);
+}
+
+void *__cdecl _expand_base( void *pMem, size_t nNewSize, int nBlockUse )
+{
+ Assert( 0 );
+ return NULL;
+}
+
+// crt
+void * __cdecl _malloc_crt(size_t size)
+{
+ return AllocUnattributed( size );
+}
+
+void * __cdecl _calloc_crt(size_t count, size_t size)
+{
+ return _calloc_base( count * size );
+}
+
+void * __cdecl _realloc_crt(void *ptr, size_t size)
+{
+ return _realloc_base( ptr, size );
+}
+
+void * __cdecl _recalloc_crt(void *ptr, size_t count, size_t size)
+{
+ return _recalloc_base( ptr, size * count );
+}
+
+ALLOC_CALL void * __cdecl _recalloc ( void * memblock, size_t count, size_t size )
+{
+ void *pMem = ReallocUnattributed( memblock, size * count );
+ memset( pMem, 0, size * count );
+ return pMem;
+}
+
+size_t _msize_base( void *pMem )
+{
+ return g_pMemAlloc->GetSize(pMem);
+}
+
+size_t _msize( void *pMem )
+{
+ return _msize_base(pMem);
+}
+
+size_t msize( void *pMem )
+{
+ return g_pMemAlloc->GetSize(pMem);
+}
+
+void *__cdecl _heap_alloc( size_t nSize )
+{
+ return AllocUnattributed( nSize );
+}
+
+void *__cdecl _nh_malloc( size_t nSize, int )
+{
+ return AllocUnattributed( nSize );
+}
+
+void *__cdecl _expand( void *pMem, size_t nSize )
+{
+ Assert( 0 );
+ return NULL;
+}
+
+unsigned int _amblksiz = 16; //BYTES_PER_PARA;
+
+#if _MSC_VER >= 1400
+HANDLE _crtheap = (HANDLE)1; // PatM Can't be 0 or CRT pukes
+int __active_heap = 1;
+#endif // _MSC_VER >= 1400
+
+size_t __cdecl _get_sbh_threshold( void )
+{
+ return 0;
+}
+
+int __cdecl _set_sbh_threshold( size_t )
+{
+ return 0;
+}
+
+int _heapchk()
+{
+ return g_pMemAlloc->heapchk();
+}
+
+int _heapmin()
+{
+ return 1;
+}
+
+int __cdecl _heapadd( void *, size_t )
+{
+ return 0;
+}
+
+int __cdecl _heapset( unsigned int )
+{
+ return 0;
+}
+
+size_t __cdecl _heapused( size_t *, size_t * )
+{
+ return 0;
+}
+
+#ifdef _WIN32
+int __cdecl _heapwalk( _HEAPINFO * )
+{
+ return 0;
+}
+#endif
+
+} // end extern "C"
+
+
+//-----------------------------------------------------------------------------
+// Debugging functions that we're going to override to call our allocator
+// NOTE: These have to be here for release + debug builds in case we
+// link to a debug static lib!!!
+//-----------------------------------------------------------------------------
+
+extern "C"
+{
+
+void *malloc_db( size_t nSize, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
+}
+
+void free_db( void *pMem, const char *pFileName, int nLine )
+{
+ g_pMemAlloc->Free(pMem, pFileName, nLine);
+}
+
+void *realloc_db( void *pMem, size_t nSize, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->Realloc(pMem, nSize, pFileName, nLine);
+}
+
+} // end extern "C"
+
+//-----------------------------------------------------------------------------
+// These methods are standard MSVC heap initialization + shutdown methods
+//-----------------------------------------------------------------------------
+extern "C"
+{
+
+#if !defined( _X360 )
+ int __cdecl _heap_init()
+ {
+ return g_pMemAlloc != NULL;
+ }
+
+ void __cdecl _heap_term()
+ {
+ }
+#endif
+
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Prevents us from using an inappropriate new or delete method,
+// ensures they are here even when linking against debug or release static libs
+//-----------------------------------------------------------------------------
+#ifndef NO_MEMOVERRIDE_NEW_DELETE
+#ifdef OSX
+void *__cdecl operator new( size_t nSize ) throw (std::bad_alloc)
+#else
+void *__cdecl operator new( size_t nSize )
+#endif
+{
+ return AllocUnattributed( nSize );
+}
+
+void *__cdecl operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
+}
+
+#ifdef OSX
+void __cdecl operator delete( void *pMem ) throw()
+#else
+void __cdecl operator delete( void *pMem )
+#endif
+{
+ g_pMemAlloc->Free( pMem );
+}
+
+#ifdef OSX
+void *__cdecl operator new[]( size_t nSize ) throw (std::bad_alloc)
+#else
+void *__cdecl operator new[]( size_t nSize )
+#endif
+{
+ return AllocUnattributed( nSize );
+}
+
+void *__cdecl operator new[] ( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
+{
+ return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
+}
+
+#ifdef OSX
+void __cdecl operator delete[]( void *pMem ) throw()
+#else
+void __cdecl operator delete[]( void *pMem )
+#endif
+{
+ g_pMemAlloc->Free( pMem );
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Override some debugging allocation methods in MSVC
+// NOTE: These have to be here for release + debug builds in case we
+// link to a debug static lib!!!
+//-----------------------------------------------------------------------------
+#ifndef _STATIC_LINKED
+#ifdef _WIN32
+
+// This here just hides the internal file names, etc of allocations
+// made in the c runtime library
+#define CRT_INTERNAL_FILE_NAME "C-runtime internal"
+
+class CAttibCRT
+{
+public:
+ CAttibCRT(int nBlockUse) : m_nBlockUse(nBlockUse)
+ {
+ if (m_nBlockUse == _CRT_BLOCK)
+ {
+ g_pMemAlloc->PushAllocDbgInfo(CRT_INTERNAL_FILE_NAME, 0);
+ }
+ }
+
+ ~CAttibCRT()
+ {
+ if (m_nBlockUse == _CRT_BLOCK)
+ {
+ g_pMemAlloc->PopAllocDbgInfo();
+ }
+ }
+
+private:
+ int m_nBlockUse;
+};
+
+
+#define AttribIfCrt() CAttibCRT _attrib(nBlockUse)
+#elif defined(POSIX)
+#define AttribIfCrt()
+#endif // _WIN32
+
+
+extern "C"
+{
+
+void *__cdecl _nh_malloc_dbg( size_t nSize, int nFlag, int nBlockUse,
+ const char *pFileName, int nLine )
+{
+ AttribIfCrt();
+ return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
+}
+
+void *__cdecl _malloc_dbg( size_t nSize, int nBlockUse,
+ const char *pFileName, int nLine )
+{
+ AttribIfCrt();
+ return g_pMemAlloc->Alloc(nSize, pFileName, nLine);
+}
+
+#if defined( _X360 )
+void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse,
+ const char * szFileName, int nLine, int * errno_tmp )
+{
+ return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine );
+}
+#endif
+
+void *__cdecl _calloc_dbg( size_t nNum, size_t nSize, int nBlockUse,
+ const char *pFileName, int nLine )
+{
+ AttribIfCrt();
+ void *pMem = g_pMemAlloc->Alloc(nSize * nNum, pFileName, nLine);
+ memset(pMem, 0, nSize * nNum);
+ return pMem;
+}
+
+void *__cdecl _calloc_dbg_impl( size_t nNum, size_t nSize, int nBlockUse,
+ const char * szFileName, int nLine, int * errno_tmp )
+{
+ return _calloc_dbg( nNum, nSize, nBlockUse, szFileName, nLine );
+}
+
+void *__cdecl _realloc_dbg( void *pMem, size_t nNewSize, int nBlockUse,
+ const char *pFileName, int nLine )
+{
+ AttribIfCrt();
+ return g_pMemAlloc->Realloc(pMem, nNewSize, pFileName, nLine);
+}
+
+void *__cdecl _expand_dbg( void *pMem, size_t nNewSize, int nBlockUse,
+ const char *pFileName, int nLine )
+{
+ Assert( 0 );
+ return NULL;
+}
+
+void __cdecl _free_dbg( void *pMem, int nBlockUse )
+{
+ AttribIfCrt();
+ g_pMemAlloc->Free(pMem);
+}
+
+size_t __cdecl _msize_dbg( void *pMem, int nBlockUse )
+{
+#ifdef _WIN32
+ return _msize(pMem);
+#elif POSIX
+ Assert( "_msize_dbg unsupported" );
+ return 0;
+#endif
+}
+
+
+#ifdef _WIN32
+
+#if defined(_DEBUG) && _MSC_VER >= 1300
+// X360TBD: aligned and offset allocations may be important on the 360
+
+// aligned base
+ALLOC_CALL void *__cdecl _aligned_malloc_base( size_t size, size_t align )
+{
+ return MemAlloc_AllocAligned( size, align );
+}
+
+ALLOC_CALL void *__cdecl _aligned_realloc_base( void *ptr, size_t size, size_t align )
+{
+ return MemAlloc_ReallocAligned( ptr, size, align );
+}
+
+ALLOC_CALL void *__cdecl _aligned_recalloc_base( void *ptr, size_t size, size_t align )
+{
+ Error( "Unsupported function\n" );
+ return NULL;
+}
+
+FREE_CALL void __cdecl _aligned_free_base( void *ptr )
+{
+ MemAlloc_FreeAligned( ptr );
+}
+
+// aligned
+ALLOC_CALL void * __cdecl _aligned_malloc( size_t size, size_t align )
+{
+ return _aligned_malloc_base(size, align);
+}
+
+ALLOC_CALL void *__cdecl _aligned_realloc(void *memblock, size_t size, size_t align)
+{
+ return _aligned_realloc_base(memblock, size, align);
+}
+
+ALLOC_CALL void * __cdecl _aligned_recalloc( void * memblock, size_t count, size_t size, size_t align )
+{
+ return _aligned_recalloc_base(memblock, count * size, align);
+}
+
+FREE_CALL void __cdecl _aligned_free( void *memblock )
+{
+ _aligned_free_base(memblock);
+}
+
+// aligned offset base
+ALLOC_CALL void * __cdecl _aligned_offset_malloc_base( size_t size, size_t align, size_t offset )
+{
+ Assert( IsPC() || 0 );
+ return NULL;
+}
+
+ALLOC_CALL void * __cdecl _aligned_offset_realloc_base( void * memblock, size_t size, size_t align, size_t offset)
+{
+ Assert( IsPC() || 0 );
+ return NULL;
+}
+
+ALLOC_CALL void * __cdecl _aligned_offset_recalloc_base( void * memblock, size_t size, size_t align, size_t offset)
+{
+ Assert( IsPC() || 0 );
+ return NULL;
+}
+
+// aligned offset
+ALLOC_CALL void *__cdecl _aligned_offset_malloc(size_t size, size_t align, size_t offset)
+{
+ return _aligned_offset_malloc_base( size, align, offset );
+}
+
+ALLOC_CALL void *__cdecl _aligned_offset_realloc(void *memblock, size_t size, size_t align, size_t offset)
+{
+ return _aligned_offset_realloc_base( memblock, size, align, offset );
+}
+
+ALLOC_CALL void * __cdecl _aligned_offset_recalloc( void * memblock, size_t count, size_t size, size_t align, size_t offset )
+{
+ return _aligned_offset_recalloc_base( memblock, count * size, align, offset );
+}
+
+#endif // _MSC_VER >= 1400
+
+#endif
+
+} // end extern "C"
+
+
+//-----------------------------------------------------------------------------
+// Override some the _CRT debugging allocation methods in MSVC
+//-----------------------------------------------------------------------------
+#ifdef _WIN32
+
+extern "C"
+{
+
+int _CrtDumpMemoryLeaks(void)
+{
+ return 0;
+}
+
+_CRT_DUMP_CLIENT _CrtSetDumpClient( _CRT_DUMP_CLIENT dumpClient )
+{
+ return NULL;
+}
+
+int _CrtSetDbgFlag( int nNewFlag )
+{
+ return g_pMemAlloc->CrtSetDbgFlag( nNewFlag );
+}
+
+// 64-bit port.
+#define AFNAME(var) __p_ ## var
+#define AFRET(var) &var
+
+int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF;
+int* AFNAME(_crtDbgFlag)(void)
+{
+ return AFRET(_crtDbgFlag);
+}
+
+long _crtBreakAlloc; /* Break on this allocation */
+long* AFNAME(_crtBreakAlloc) (void)
+{
+ return AFRET(_crtBreakAlloc);
+}
+
+void __cdecl _CrtSetDbgBlockType( void *pMem, int nBlockUse )
+{
+ DebuggerBreak();
+}
+
+_CRT_ALLOC_HOOK __cdecl _CrtSetAllocHook( _CRT_ALLOC_HOOK pfnNewHook )
+{
+ DebuggerBreak();
+ return NULL;
+}
+
+long __cdecl _CrtSetBreakAlloc( long lNewBreakAlloc )
+{
+ return g_pMemAlloc->CrtSetBreakAlloc( lNewBreakAlloc );
+}
+
+int __cdecl _CrtIsValidHeapPointer( const void *pMem )
+{
+ return g_pMemAlloc->CrtIsValidHeapPointer( pMem );
+}
+
+int __cdecl _CrtIsValidPointer( const void *pMem, unsigned int size, int access )
+{
+ return g_pMemAlloc->CrtIsValidPointer( pMem, size, access );
+}
+
+int __cdecl _CrtCheckMemory( void )
+{
+ // FIXME: Remove this when we re-implement the heap
+ return g_pMemAlloc->CrtCheckMemory( );
+}
+
+int __cdecl _CrtIsMemoryBlock( const void *pMem, unsigned int nSize,
+ long *plRequestNumber, char **ppFileName, int *pnLine )
+{
+ DebuggerBreak();
+ return 1;
+}
+
+int __cdecl _CrtMemDifference( _CrtMemState *pState, const _CrtMemState * oldState, const _CrtMemState * newState )
+{
+ DebuggerBreak();
+ return FALSE;
+}
+
+void __cdecl _CrtMemDumpStatistics( const _CrtMemState *pState )
+{
+ DebuggerBreak();
+}
+
+void __cdecl _CrtMemCheckpoint( _CrtMemState *pState )
+{
+ // FIXME: Remove this when we re-implement the heap
+ g_pMemAlloc->CrtMemCheckpoint( pState );
+}
+
+void __cdecl _CrtMemDumpAllObjectsSince( const _CrtMemState *pState )
+{
+ DebuggerBreak();
+}
+
+void __cdecl _CrtDoForAllClientObjects( void (*pfn)(void *, void *), void * pContext )
+{
+ DebuggerBreak();
+}
+
+
+//-----------------------------------------------------------------------------
+// Methods in dbgrpt.cpp
+//-----------------------------------------------------------------------------
+long _crtAssertBusy = -1;
+
+int __cdecl _CrtSetReportMode( int nReportType, int nReportMode )
+{
+ return g_pMemAlloc->CrtSetReportMode( nReportType, nReportMode );
+}
+
+_HFILE __cdecl _CrtSetReportFile( int nRptType, _HFILE hFile )
+{
+ return (_HFILE)g_pMemAlloc->CrtSetReportFile( nRptType, hFile );
+}
+
+_CRT_REPORT_HOOK __cdecl _CrtSetReportHook( _CRT_REPORT_HOOK pfnNewHook )
+{
+ return (_CRT_REPORT_HOOK)g_pMemAlloc->CrtSetReportHook( pfnNewHook );
+}
+
+int __cdecl _CrtDbgReport( int nRptType, const char * szFile,
+ int nLine, const char * szModule, const char * szFormat, ... )
+{
+ static char output[1024];
+ va_list args;
+ if ( szFormat )
+ {
+ va_start( args, szFormat );
+ _vsnprintf( output, sizeof( output )-1, szFormat, args );
+ va_end( args );
+ }
+ else
+ {
+ output[0] = 0;
+ }
+
+ return g_pMemAlloc->CrtDbgReport( nRptType, szFile, nLine, szModule, output );
+}
+
+#if _MSC_VER >= 1400
+
+// Configure VS so that it will record crash dumps on pure-call violations
+// and invalid parameter handlers.
+// If you manage to call a pure-virtual function (easily done if you indirectly
+// call a pure-virtual function from the base-class constructor or destructor)
+// or if you invoke the invalid parameter handler (printf(NULL); is one way)
+// then no crash dump will be created.
+// This crash redirects the handlers for these two events so that crash dumps
+// are created.
+//
+// The ErrorHandlerRegistrar object must be in memoverride.cpp so that it will
+// be placed in every DLL and EXE. This is required because each DLL and EXE
+// gets its own copy of the C run-time and these overrides are set on a per-CRT
+// basis.
+
+/*
+// This sample code will cause pure-call and invalid_parameter violations and
+// was used for testing:
+class Base
+{
+public:
+ virtual void PureFunction() = 0;
+
+ Base()
+ {
+ NonPureFunction();
+ }
+
+ void NonPureFunction()
+ {
+ PureFunction();
+ }
+};
+
+class Derived : public Base
+{
+public:
+ void PureFunction() OVERRIDE
+ {
+ }
+};
+
+void PureCallViolation()
+{
+ Derived derived;
+}
+
+void InvalidParameterViolation()
+{
+ printf( NULL );
+}
+*/
+
+#include <stdlib.h>
+#include "minidump.h"
+
+// Disable compiler optimizations. If we don't do this then VC++ generates code
+// that confuses the Visual Studio debugger and causes it to display completely
+// random call stacks. That makes the minidumps excruciatingly hard to understand.
+#pragma optimize("", off)
+
+// Write a minidump file, unless running under the debugger in which case break
+// into the debugger.
+// The "int dummy" parameter is so that the callers can be unique so that the
+// linker won't use its /opt:icf optimization to collapse them together. This
+// makes reading the call stack easier.
+void __cdecl WriteMiniDumpOrBreak( int dummy, const char *pchName )
+{
+ if ( Plat_IsInDebugSession() )
+ {
+ __debugbreak();
+ // Continue at your peril...
+ }
+ else
+ {
+ WriteMiniDump( pchName );
+ // Call Plat_ExitProcess so we don't continue in a bad state.
+ TerminateProcess(GetCurrentProcess(), 0);
+ }
+}
+
+void __cdecl VPureCall()
+{
+ WriteMiniDumpOrBreak( 0, "PureClass" );
+}
+
+void VInvalidParameterHandler(const wchar_t* expression,
+ const wchar_t* function,
+ const wchar_t* file,
+ unsigned int line,
+ uintptr_t pReserved)
+{
+ WriteMiniDumpOrBreak( 1, "InvalidParameterHandler" );
+}
+
+// Restore compiler optimizations.
+#pragma optimize("", on)
+
+// Helper class for registering error callbacks. See above for details.
+class ErrorHandlerRegistrar
+{
+public:
+ ErrorHandlerRegistrar();
+} s_ErrorHandlerRegistration;
+
+ErrorHandlerRegistrar::ErrorHandlerRegistrar()
+{
+ _set_purecall_handler( VPureCall );
+ _set_invalid_parameter_handler( VInvalidParameterHandler );
+}
+
+#if defined( _DEBUG )
+
+// wrapper which passes no debug info; not available in debug
+#ifndef SUPPRESS_INVALID_PARAMETER_NO_INFO
+void __cdecl _invalid_parameter_noinfo(void)
+{
+ Assert(0);
+}
+#endif
+
+#endif /* defined( _DEBUG ) */
+
+#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
+
+int __cdecl __crtMessageWindowW( int nRptType, const wchar_t * szFile, const wchar_t * szLine,
+ const wchar_t * szModule, const wchar_t * szUserMessage )
+{
+ Assert(0);
+ return 0;
+}
+
+int __cdecl _CrtDbgReportV( int nRptType, const wchar_t *szFile, int nLine,
+ const wchar_t *szModule, const wchar_t *szFormat, va_list arglist )
+{
+ Assert(0);
+ return 0;
+}
+
+int __cdecl _CrtDbgReportW( int nRptType, const wchar_t *szFile, int nLine,
+ const wchar_t *szModule, const wchar_t *szFormat, ...)
+{
+ Assert(0);
+ return 0;
+}
+
+int __cdecl _VCrtDbgReportA( int nRptType, const wchar_t * szFile, int nLine,
+ const wchar_t * szModule, const wchar_t * szFormat, va_list arglist )
+{
+ Assert(0);
+ return 0;
+}
+
+int __cdecl _CrtSetReportHook2( int mode, _CRT_REPORT_HOOK pfnNewHook )
+{
+ _CrtSetReportHook( pfnNewHook );
+ return 0;
+}
+
+
+#endif /* defined( _DEBUG ) || defined( USE_MEM_DEBUG ) */
+
+extern "C" int __crtDebugCheckCount = FALSE;
+
+extern "C" int __cdecl _CrtSetCheckCount( int fCheckCount )
+{
+ int oldCheckCount = __crtDebugCheckCount;
+ return oldCheckCount;
+}
+
+extern "C" int __cdecl _CrtGetCheckCount( void )
+{
+ return __crtDebugCheckCount;
+}
+
+// aligned offset debug
+extern "C" void * __cdecl _aligned_offset_recalloc_dbg( void * memblock, size_t count, size_t size, size_t align, size_t offset, const char * f_name, int line_n )
+{
+ Assert( IsPC() || 0 );
+ void *pMem = ReallocUnattributed( memblock, size * count );
+ memset( pMem, 0, size * count );
+ return pMem;
+}
+
+extern "C" void * __cdecl _aligned_recalloc_dbg( void *memblock, size_t count, size_t size, size_t align, const char * f_name, int line_n )
+{
+ return _aligned_offset_recalloc_dbg(memblock, count, size, align, 0, f_name, line_n);
+}
+
+extern "C" void * __cdecl _recalloc_dbg ( void * memblock, size_t count, size_t size, int nBlockUse, const char * szFileName, int nLine )
+{
+ return _aligned_offset_recalloc_dbg(memblock, count, size, 0, 0, szFileName, nLine);
+}
+
+_CRT_REPORT_HOOK __cdecl _CrtGetReportHook( void )
+{
+ return NULL;
+}
+
+#endif
+int __cdecl _CrtReportBlockType(const void * pUserData)
+{
+ return 0;
+}
+
+
+} // end extern "C"
+#endif // _WIN32
+
+// Most files include this file, so when it's used it adds an extra .ValveDbg section,
+// to help identify debug binaries.
+#ifdef _WIN32
+ #ifndef NDEBUG // _DEBUG
+ #pragma data_seg("ValveDBG")
+ volatile const char* DBG = "*** DEBUG STUB ***";
+ #endif
+#endif
+
+#endif
+
+// Extras added prevent dbgheap.obj from being included - DAL
+#ifdef _WIN32
+
+extern "C"
+{
+size_t __crtDebugFillThreshold = 0;
+
+extern "C" void * __cdecl _heap_alloc_base (size_t size) {
+ assert(0);
+ return NULL;
+}
+
+
+void * __cdecl _heap_alloc_dbg( size_t nSize, int nBlockUse, const char * szFileName, int nLine)
+{
+ return _heap_alloc(nSize);
+}
+
+// 64-bit
+#ifdef _WIN64
+static void * __cdecl realloc_help( void * pUserData, size_t * pnNewSize, int nBlockUse,const char * szFileName,
+ int nLine, int fRealloc )
+{
+ assert(0); // Shouldn't be needed
+ return NULL;
+}
+#else
+static void * __cdecl realloc_help( void * pUserData, size_t nNewSize, int nBlockUse, const char * szFileName,
+ int nLine, int fRealloc)
+{
+ assert(0); // Shouldn't be needed
+ return NULL;
+}
+#endif
+
+void __cdecl _free_nolock( void * pUserData)
+{
+ // I don't think the second param is used in memoverride
+ _free_dbg(pUserData, 0);
+}
+
+void __cdecl _free_dbg_nolock( void * pUserData, int nBlockUse)
+{
+ _free_dbg(pUserData, 0);
+}
+
+_CRT_ALLOC_HOOK __cdecl _CrtGetAllocHook ( void)
+{
+ assert(0);
+ return NULL;
+}
+
+static int __cdecl CheckBytes( unsigned char * pb, unsigned char bCheck, size_t nSize)
+{
+ int bOkay = TRUE;
+ return bOkay;
+}
+
+
+_CRT_DUMP_CLIENT __cdecl _CrtGetDumpClient ( void)
+{
+ assert(0);
+ return NULL;
+}
+
+#if _MSC_VER >= 1400
+static void __cdecl _printMemBlockData( _locale_t plocinfo, _CrtMemBlockHeader * pHead)
+{
+}
+
+static void __cdecl _CrtMemDumpAllObjectsSince_stat( const _CrtMemState * state, _locale_t plocinfo)
+{
+}
+#endif
+void * __cdecl _aligned_malloc_dbg( size_t size, size_t align, const char * f_name, int line_n)
+{
+ return _aligned_malloc(size, align);
+}
+
+void * __cdecl _aligned_realloc_dbg( void *memblock, size_t size, size_t align,
+ const char * f_name, int line_n)
+{
+ return _aligned_realloc(memblock, size, align);
+}
+
+void * __cdecl _aligned_offset_malloc_dbg( size_t size, size_t align, size_t offset,
+ const char * f_name, int line_n)
+{
+ return _aligned_offset_malloc(size, align, offset);
+}
+
+void * __cdecl _aligned_offset_realloc_dbg( void * memblock, size_t size, size_t align,
+ size_t offset, const char * f_name, int line_n)
+{
+ return _aligned_offset_realloc(memblock, size, align, offset);
+}
+
+void __cdecl _aligned_free_dbg( void * memblock)
+{
+ _aligned_free(memblock);
+}
+
+size_t __cdecl _CrtSetDebugFillThreshold( size_t _NewDebugFillThreshold)
+{
+ assert(0);
+ return 0;
+}
+
+//===========================================
+// NEW!!! 64-bit
+
+char * __cdecl _strdup ( const char * string )
+{
+ int nSize = (int)strlen(string) + 1;
+ // Check for integer underflow.
+ if ( nSize <= 0 )
+ return NULL;
+ char *pCopy = (char*)AllocUnattributed( nSize );
+ if ( pCopy )
+ memcpy( pCopy, string, nSize );
+ return pCopy;
+}
+
+#if 0
+_TSCHAR * __cdecl _tfullpath_dbg ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen, int nBlockUse, const char * szFileName, int nLine )
+{
+ Assert(0);
+ return NULL;
+}
+
+_TSCHAR * __cdecl _tfullpath ( _TSCHAR *UserBuf, const _TSCHAR *path, size_t maxlen )
+{
+ Assert(0);
+ return NULL;
+}
+
+_TSCHAR * __cdecl _tgetdcwd_lk_dbg ( int drive, _TSCHAR *pnbuf, int maxlen, int nBlockUse, const char * szFileName, int nLine )
+{
+ Assert(0);
+ return NULL;
+}
+
+_TSCHAR * __cdecl _tgetdcwd_nolock ( int drive, _TSCHAR *pnbuf, int maxlen )
+{
+ Assert(0);
+ return NULL;
+}
+
+errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname, int nBlockUse, const char * szFileName, int nLine )
+{
+ Assert(0);
+ return 0;
+}
+
+errno_t __cdecl _tdupenv_s_helper ( _TSCHAR **pBuffer, size_t *pBufferSizeInTChars, const _TSCHAR *varname )
+{
+ Assert(0);
+ return 0;
+}
+
+_TSCHAR * __cdecl _ttempnam_dbg ( const _TSCHAR *dir, const _TSCHAR *pfx, int nBlockUse, const char * szFileName, int nLine )
+{
+ Assert(0);
+ return 0;
+}
+
+_TSCHAR * __cdecl _ttempnam ( const _TSCHAR *dir, const _TSCHAR *pfx )
+{
+ Assert(0);
+ return 0;
+}
+#endif
+
+wchar_t * __cdecl _wcsdup_dbg ( const wchar_t * string, int nBlockUse, const char * szFileName, int nLine )
+{
+ Assert(0);
+ return 0;
+}
+
+wchar_t * __cdecl _wcsdup ( const wchar_t * string )
+{
+ Assert(0);
+ return 0;
+}
+
+} // end extern "C"
+
+#if _MSC_VER >= 1400
+
+//-----------------------------------------------------------------------------
+// XBox Memory Allocator Override
+//-----------------------------------------------------------------------------
+#if defined( _X360 )
+#if defined( _DEBUG ) || defined( USE_MEM_DEBUG )
+#include "utlmap.h"
+
+MEMALLOC_DEFINE_EXTERNAL_TRACKING( XMem );
+
+CThreadFastMutex g_XMemAllocMutex;
+
+void XMemAlloc_RegisterAllocation( void *p, DWORD dwAllocAttributes )
+{
+ if ( !g_pMemAlloc )
+ {
+ // core xallocs cannot be journaled until system is ready
+ return;
+ }
+
+ AUTO_LOCK_FM( g_XMemAllocMutex );
+ int size = XMemSize( p, dwAllocAttributes );
+ MemAlloc_RegisterExternalAllocation( XMem, p, size );
+}
+
+void XMemAlloc_RegisterDeallocation( void *p, DWORD dwAllocAttributes )
+{
+ if ( !g_pMemAlloc )
+ {
+ // core xallocs cannot be journaled until system is ready
+ return;
+ }
+
+ AUTO_LOCK_FM( g_XMemAllocMutex );
+ int size = XMemSize( p, dwAllocAttributes );
+ MemAlloc_RegisterExternalDeallocation( XMem, p, size );
+}
+
+#else
+
+#define XMemAlloc_RegisterAllocation( p, a ) ((void)0)
+#define XMemAlloc_RegisterDeallocation( p, a ) ((void)0)
+
+#endif
+
+//-----------------------------------------------------------------------------
+// XMemAlloc
+//
+// XBox Memory Allocator Override
+//-----------------------------------------------------------------------------
+LPVOID WINAPI XMemAlloc( SIZE_T dwSize, DWORD dwAllocAttributes )
+{
+ LPVOID ptr;
+ XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
+ bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
+
+ if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
+ {
+ MEM_ALLOC_CREDIT();
+ switch ( pAttribs->dwAlignment )
+ {
+ case XALLOC_ALIGNMENT_4:
+ ptr = g_pMemAlloc->Alloc( dwSize );
+ break;
+ case XALLOC_ALIGNMENT_8:
+ ptr = MemAlloc_AllocAligned( dwSize, 8 );
+ break;
+ case XALLOC_ALIGNMENT_DEFAULT:
+ case XALLOC_ALIGNMENT_16:
+ default:
+ ptr = MemAlloc_AllocAligned( dwSize, 16 );
+ break;
+ }
+ if ( pAttribs->dwZeroInitialize != 0 )
+ {
+ memset( ptr, 0, XMemSize( ptr, dwAllocAttributes ) );
+ }
+ return ptr;
+ }
+
+ ptr = XMemAllocDefault( dwSize, dwAllocAttributes );
+ if ( ptr )
+ {
+ XMemAlloc_RegisterAllocation( ptr, dwAllocAttributes );
+ }
+
+ return ptr;
+}
+
+//-----------------------------------------------------------------------------
+// XMemFree
+//
+// XBox Memory Allocator Override
+//-----------------------------------------------------------------------------
+VOID WINAPI XMemFree( PVOID pAddress, DWORD dwAllocAttributes )
+{
+ if ( !pAddress )
+ {
+ return;
+ }
+
+ XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
+ bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
+
+ if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
+ {
+ switch ( pAttribs->dwAlignment )
+ {
+ case XALLOC_ALIGNMENT_4:
+ return g_pMemAlloc->Free( pAddress );
+ default:
+ return MemAlloc_FreeAligned( pAddress );
+ }
+ return;
+ }
+
+ XMemAlloc_RegisterDeallocation( pAddress, dwAllocAttributes );
+
+ XMemFreeDefault( pAddress, dwAllocAttributes );
+}
+
+//-----------------------------------------------------------------------------
+// XMemSize
+//
+// XBox Memory Allocator Override
+//-----------------------------------------------------------------------------
+SIZE_T WINAPI XMemSize( PVOID pAddress, DWORD dwAllocAttributes )
+{
+ XALLOC_ATTRIBUTES *pAttribs = (XALLOC_ATTRIBUTES *)&dwAllocAttributes;
+ bool bPhysical = ( pAttribs->dwMemoryType == XALLOC_MEMTYPE_PHYSICAL );
+
+ if ( !bPhysical && !pAttribs->dwHeapTracksAttributes && pAttribs->dwAllocatorId != eXALLOCAllocatorId_XUI )
+ {
+ switch ( pAttribs->dwAlignment )
+ {
+ case XALLOC_ALIGNMENT_4:
+ return g_pMemAlloc->GetSize( pAddress );
+ default:
+ return MemAlloc_GetSizeAligned( pAddress );
+ }
+ }
+
+ return XMemSizeDefault( pAddress, dwAllocAttributes );
+}
+#endif // _X360
+
+#define MAX_LANG_LEN 64 /* max language name length */
+#define MAX_CTRY_LEN 64 /* max country name length */
+#define MAX_MODIFIER_LEN 0 /* max modifier name length - n/a */
+#define MAX_LC_LEN (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
+
+#if _MSC_VER >= 1700 // VS 11
+// Copied from C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\mtdll.h
+#ifndef _SETLOC_STRUCT_DEFINED
+struct _is_ctype_compatible {
+ unsigned long id;
+ int is_clike;
+};
+
+typedef struct setloc_struct {
+ /* getqloc static variables */
+ wchar_t *pchLanguage;
+ wchar_t *pchCountry;
+ int iLocState;
+ int iPrimaryLen;
+ BOOL bAbbrevLanguage;
+ BOOL bAbbrevCountry;
+ UINT _cachecp;
+ wchar_t _cachein[MAX_LC_LEN];
+ wchar_t _cacheout[MAX_LC_LEN];
+ /* _setlocale_set_cat (LC_CTYPE) static variable */
+ struct _is_ctype_compatible _Loc_c[5];
+ wchar_t _cacheLocaleName[LOCALE_NAME_MAX_LENGTH];
+} _setloc_struct, *_psetloc_struct;
+#define _SETLOC_STRUCT_DEFINED
+#endif /* _SETLOC_STRUCT_DEFINED */
+
+_CRTIMP extern unsigned long __cdecl __threadid(void);
+#define _threadid (__threadid())
+_CRTIMP extern uintptr_t __cdecl __threadhandle(void);
+#define _threadhandle (__threadhandle())
+
+/* Structure for each thread's data */
+
+struct _tiddata {
+ unsigned long _tid; /* thread ID */
+
+
+ uintptr_t _thandle; /* thread handle */
+
+ int _terrno; /* errno value */
+ unsigned long _tdoserrno; /* _doserrno value */
+ unsigned int _fpds; /* Floating Point data segment */
+ unsigned long _holdrand; /* rand() seed value */
+ char * _token; /* ptr to strtok() token */
+ wchar_t * _wtoken; /* ptr to wcstok() token */
+ unsigned char * _mtoken; /* ptr to _mbstok() token */
+
+ /* following pointers get malloc'd at runtime */
+ char * _errmsg; /* ptr to strerror()/_strerror() buff */
+ wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
+ char * _namebuf0; /* ptr to tmpnam() buffer */
+ wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
+ char * _namebuf1; /* ptr to tmpfile() buffer */
+ wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
+ char * _asctimebuf; /* ptr to asctime() buffer */
+ wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
+ void * _gmtimebuf; /* ptr to gmtime() structure */
+ char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
+ unsigned char _con_ch_buf[MB_LEN_MAX];
+ /* ptr to putch() buffer */
+ unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
+
+ /* following fields are needed by _beginthread code */
+ void * _initaddr; /* initial user thread address */
+ void * _initarg; /* initial user thread argument */
+
+ /* following three fields are needed to support signal handling and
+ * runtime errors */
+ void * _pxcptacttab; /* ptr to exception-action table */
+ void * _tpxcptinfoptrs; /* ptr to exception info pointers */
+ int _tfpecode; /* float point exception code */
+
+ /* pointer to the copy of the multibyte character information used by
+ * the thread */
+ pthreadmbcinfo ptmbcinfo;
+
+ /* pointer to the copy of the locale informaton used by the thead */
+ pthreadlocinfo ptlocinfo;
+ int _ownlocale; /* if 1, this thread owns its own locale */
+
+ /* following field is needed by NLG routines */
+ unsigned long _NLG_dwCode;
+
+ /*
+ * Per-Thread data needed by C++ Exception Handling
+ */
+ void * _terminate; /* terminate() routine */
+ void * _unexpected; /* unexpected() routine */
+ void * _translator; /* S.E. translator */
+ void * _purecall; /* called when pure virtual happens */
+ void * _curexception; /* current exception */
+ void * _curcontext; /* current exception context */
+ int _ProcessingThrow; /* for uncaught_exception */
+ void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
+#if defined (_M_X64) || defined (_M_ARM)
+ void * _pExitContext;
+ void * _pUnwindContext;
+ void * _pFrameInfoChain;
+#if defined (_WIN64)
+ unsigned __int64 _ImageBase;
+ unsigned __int64 _ThrowImageBase;
+#else /* defined (_WIN64) */
+ unsigned __int32 _ImageBase;
+ unsigned __int32 _ThrowImageBase;
+#endif /* defined (_WIN64) */
+ void * _pForeignException;
+#elif defined (_M_IX86)
+ void * _pFrameInfoChain;
+#endif /* defined (_M_IX86) */
+ _setloc_struct _setloc_data;
+
+ void * _reserved1; /* nothing */
+ void * _reserved2; /* nothing */
+ void * _reserved3; /* nothing */
+#ifdef _M_IX86
+ void * _reserved4; /* nothing */
+ void * _reserved5; /* nothing */
+#endif /* _M_IX86 */
+
+ int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
+
+ unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
+};
+#else
+struct _is_ctype_compatible {
+ unsigned long id;
+ int is_clike;
+};
+
+typedef struct setloc_struct {
+ /* getqloc static variables */
+ char *pchLanguage;
+ char *pchCountry;
+ int iLcidState;
+ int iPrimaryLen;
+ BOOL bAbbrevLanguage;
+ BOOL bAbbrevCountry;
+ LCID lcidLanguage;
+ LCID lcidCountry;
+ /* expand_locale static variables */
+ LC_ID _cacheid;
+ UINT _cachecp;
+ char _cachein[MAX_LC_LEN];
+ char _cacheout[MAX_LC_LEN];
+ /* _setlocale_set_cat (LC_CTYPE) static variable */
+ struct _is_ctype_compatible _Lcid_c[5];
+} _setloc_struct, *_psetloc_struct;
+
+struct _tiddata {
+ unsigned long _tid; /* thread ID */
+
+
+ uintptr_t _thandle; /* thread handle */
+
+ int _terrno; /* errno value */
+ unsigned long _tdoserrno; /* _doserrno value */
+ unsigned int _fpds; /* Floating Point data segment */
+ unsigned long _holdrand; /* rand() seed value */
+ char * _token; /* ptr to strtok() token */
+ wchar_t * _wtoken; /* ptr to wcstok() token */
+ unsigned char * _mtoken; /* ptr to _mbstok() token */
+
+ /* following pointers get malloc'd at runtime */
+ char * _errmsg; /* ptr to strerror()/_strerror() buff */
+ wchar_t * _werrmsg; /* ptr to _wcserror()/__wcserror() buff */
+ char * _namebuf0; /* ptr to tmpnam() buffer */
+ wchar_t * _wnamebuf0; /* ptr to _wtmpnam() buffer */
+ char * _namebuf1; /* ptr to tmpfile() buffer */
+ wchar_t * _wnamebuf1; /* ptr to _wtmpfile() buffer */
+ char * _asctimebuf; /* ptr to asctime() buffer */
+ wchar_t * _wasctimebuf; /* ptr to _wasctime() buffer */
+ void * _gmtimebuf; /* ptr to gmtime() structure */
+ char * _cvtbuf; /* ptr to ecvt()/fcvt buffer */
+ unsigned char _con_ch_buf[MB_LEN_MAX];
+ /* ptr to putch() buffer */
+ unsigned short _ch_buf_used; /* if the _con_ch_buf is used */
+
+ /* following fields are needed by _beginthread code */
+ void * _initaddr; /* initial user thread address */
+ void * _initarg; /* initial user thread argument */
+
+ /* following three fields are needed to support signal handling and
+ * runtime errors */
+ void * _pxcptacttab; /* ptr to exception-action table */
+ void * _tpxcptinfoptrs; /* ptr to exception info pointers */
+ int _tfpecode; /* float point exception code */
+
+ /* pointer to the copy of the multibyte character information used by
+ * the thread */
+ pthreadmbcinfo ptmbcinfo;
+
+ /* pointer to the copy of the locale informaton used by the thead */
+ pthreadlocinfo ptlocinfo;
+ int _ownlocale; /* if 1, this thread owns its own locale */
+
+ /* following field is needed by NLG routines */
+ unsigned long _NLG_dwCode;
+
+ /*
+ * Per-Thread data needed by C++ Exception Handling
+ */
+ void * _terminate; /* terminate() routine */
+ void * _unexpected; /* unexpected() routine */
+ void * _translator; /* S.E. translator */
+ void * _purecall; /* called when pure virtual happens */
+ void * _curexception; /* current exception */
+ void * _curcontext; /* current exception context */
+ int _ProcessingThrow; /* for uncaught_exception */
+ void * _curexcspec; /* for handling exceptions thrown from std::unexpected */
+#if defined (_M_IA64) || defined (_M_AMD64)
+ void * _pExitContext;
+ void * _pUnwindContext;
+ void * _pFrameInfoChain;
+ unsigned __int64 _ImageBase;
+#if defined (_M_IA64)
+ unsigned __int64 _TargetGp;
+#endif /* defined (_M_IA64) */
+ unsigned __int64 _ThrowImageBase;
+ void * _pForeignException;
+#elif defined (_M_IX86)
+ void * _pFrameInfoChain;
+#endif /* defined (_M_IX86) */
+ _setloc_struct _setloc_data;
+
+ void * _encode_ptr; /* EncodePointer() routine */
+ void * _decode_ptr; /* DecodePointer() routine */
+
+ void * _reserved1; /* nothing */
+ void * _reserved2; /* nothing */
+ void * _reserved3; /* nothing */
+
+ int _cxxReThrow; /* Set to True if it's a rethrown C++ Exception */
+
+ unsigned long __initDomain; /* initial domain used by _beginthread[ex] for managed function */
+};
+#endif
+
+typedef struct _tiddata * _ptiddata;
+
+class _LocaleUpdate
+{
+ _locale_tstruct localeinfo;
+ _ptiddata ptd;
+ bool updated;
+ public:
+ _LocaleUpdate(_locale_t plocinfo)
+ : updated(false)
+ {
+ /*
+ if (plocinfo == NULL)
+ {
+ ptd = _getptd();
+ localeinfo.locinfo = ptd->ptlocinfo;
+ localeinfo.mbcinfo = ptd->ptmbcinfo;
+
+ __UPDATE_LOCALE(ptd, localeinfo.locinfo);
+ __UPDATE_MBCP(ptd, localeinfo.mbcinfo);
+ if (!(ptd->_ownlocale & _PER_THREAD_LOCALE_BIT))
+ {
+ ptd->_ownlocale |= _PER_THREAD_LOCALE_BIT;
+ updated = true;
+ }
+ }
+ else
+ {
+ localeinfo=*plocinfo;
+ }
+ */
+ }
+ ~_LocaleUpdate()
+ {
+// if (updated)
+// ptd->_ownlocale = ptd->_ownlocale & ~_PER_THREAD_LOCALE_BIT;
+ }
+ _locale_t GetLocaleT()
+ {
+ return &localeinfo;
+ }
+};
+
+
+#pragma warning(push)
+#pragma warning(disable: 4483)
+#if _MSC_FULL_VER >= 140050415
+#define _NATIVE_STARTUP_NAMESPACE __identifier("<CrtImplementationDetails>")
+#else /* _MSC_FULL_VER >= 140050415 */
+#define _NATIVE_STARTUP_NAMESPACE __CrtImplementationDetails
+#endif /* _MSC_FULL_VER >= 140050415 */
+
+namespace _NATIVE_STARTUP_NAMESPACE
+{
+ class NativeDll
+ {
+ private:
+ static const unsigned int ProcessDetach = 0;
+ static const unsigned int ProcessAttach = 1;
+ static const unsigned int ThreadAttach = 2;
+ static const unsigned int ThreadDetach = 3;
+ static const unsigned int ProcessVerifier = 4;
+
+ public:
+
+ inline static bool IsInDllMain()
+ {
+ return false;
+ }
+
+ inline static bool IsInProcessAttach()
+ {
+ return false;
+ }
+
+ inline static bool IsInProcessDetach()
+ {
+ return false;
+ }
+
+ inline static bool IsInVcclrit()
+ {
+ return false;
+ }
+
+ inline static bool IsSafeForManagedCode()
+ {
+ if (!IsInDllMain())
+ {
+ return true;
+ }
+
+ if (IsInVcclrit())
+ {
+ return true;
+ }
+
+ return !IsInProcessAttach() && !IsInProcessDetach();
+ }
+ };
+}
+#pragma warning(pop)
+
+#endif // _MSC_VER >= 1400
+
+#endif // !STEAM && !NO_MALLOC_OVERRIDE
+
+#endif // _WIN32
diff --git a/sp/src/public/tier0/minidump.h b/sp/src/public/tier0/minidump.h
index 71f03563..fad2d073 100644
--- a/sp/src/public/tier0/minidump.h
+++ b/sp/src/public/tier0/minidump.h
@@ -1,87 +1,87 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-//=============================================================================//
-
-#ifndef MINIDUMP_H
-#define MINIDUMP_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-
-// Set prefix to use for minidump files. If you don't set one, it is defaulted for you,
-// using the current module name
-PLATFORM_INTERFACE void SetMinidumpFilenamePrefix( const char *pszPrefix );
-
-// Set comment to put into minidump file upon next call of WriteMiniDump. (Most common use is the assert text.)
-PLATFORM_INTERFACE void SetMinidumpComment( const char *pszComment );
-
-// writes out a minidump of the current stack trace with a unique filename
-PLATFORM_INTERFACE void WriteMiniDump( const char *pszFilenameSuffix = NULL );
-
-typedef void (*FnWMain)( int , tchar *[] );
-typedef void (*FnVoidPtrFn)( void * );
-
-#if defined(_WIN32) && !defined(_X360)
-
-// calls the passed in function pointer and catches any exceptions/crashes thrown by it, and writes a minidump
-// use from wmain() to protect the whole program
-typedef void (*FnWMain)( int , tchar *[] );
-typedef int (*FnWMainIntRet)( int , tchar *[] );
-typedef void (*FnVoidPtrFn)( void * );
-
-enum ECatchAndWriteMinidumpAction
-{
- k_ECatchAndWriteMiniDumpAbort = 0,
- k_ECatchAndWriteMiniDumpReThrow = 1,
- k_ECatchAndWriteMiniDumpIgnore = 2,
-};
-
-PLATFORM_INTERFACE void CatchAndWriteMiniDump( FnWMain pfn, int argc, tchar *argv[] ); // action = Abort
-PLATFORM_INTERFACE void CatchAndWriteMiniDumpForVoidPtrFn( FnVoidPtrFn pfn, void *pv, bool bExitQuietly ); // action = abort if bExitQuietly, Rethrow otherwise
-
-PLATFORM_INTERFACE void CatchAndWriteMiniDumpEx( FnWMain pfn, int argc, tchar *argv[], ECatchAndWriteMinidumpAction eAction );
-PLATFORM_INTERFACE int CatchAndWriteMiniDumpExReturnsInt( FnWMainIntRet pfn, int argc, tchar *argv[], ECatchAndWriteMinidumpAction eAction );
-PLATFORM_INTERFACE void CatchAndWriteMiniDumpExForVoidPtrFn( FnVoidPtrFn pfn, void *pv, ECatchAndWriteMinidumpAction eAction );
-
-// Let's not include this. We'll use forwards instead.
-//#include <dbghelp.h>
-struct _EXCEPTION_POINTERS;
-
-// Replaces the current function pointer with the one passed in.
-// Returns the previously-set function.
-// The function is called internally by WriteMiniDump() and CatchAndWriteMiniDump()
-// The default is the built-in function that uses DbgHlp.dll's MiniDumpWriteDump function
-typedef void (*FnMiniDump)( unsigned int uStructuredExceptionCode, _EXCEPTION_POINTERS * pExceptionInfo, const char *pszFilenameSuffix );
-PLATFORM_INTERFACE FnMiniDump SetMiniDumpFunction( FnMiniDump pfn );
-
-// Use this to write a minidump explicitly.
-// Some of the tools choose to catch the minidump themselves instead of using CatchAndWriteMinidump
-// so they can show their own dialog.
-//
-// ptchMinidumpFileNameBuffer if not-NULL should be a writable tchar buffer of length at
-// least _MAX_PATH and on return will contain the name of the minidump file written.
-// If ptchMinidumpFileNameBuffer is NULL the name of the minidump file written will not
-// be available after the function returns.
-//
-PLATFORM_INTERFACE bool WriteMiniDumpUsingExceptionInfo(
- unsigned int uStructuredExceptionCode,
- _EXCEPTION_POINTERS * pExceptionInfo,
- int /* MINIDUMP_TYPE */ minidumpType,
- const char *pszFilenameSuffix = NULL,
- tchar *ptchMinidumpFileNameBuffer = NULL
- );
-
-// Call this to enable a handler for unhandled exceptions.
-PLATFORM_INTERFACE void MinidumpSetUnhandledExceptionFunction( FnMiniDump pfn );
-
-// Call this to prevent crashes in kernel callbacks such as window procs from
-// being silently swallowed. We should always call this at startup.
-PLATFORM_INTERFACE void EnableCrashingOnCrashes();
-
-#endif
-
-#endif // MINIDUMP_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#ifndef MINIDUMP_H
+#define MINIDUMP_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+
+// Set prefix to use for minidump files. If you don't set one, it is defaulted for you,
+// using the current module name
+PLATFORM_INTERFACE void SetMinidumpFilenamePrefix( const char *pszPrefix );
+
+// Set comment to put into minidump file upon next call of WriteMiniDump. (Most common use is the assert text.)
+PLATFORM_INTERFACE void SetMinidumpComment( const char *pszComment );
+
+// writes out a minidump of the current stack trace with a unique filename
+PLATFORM_INTERFACE void WriteMiniDump( const char *pszFilenameSuffix = NULL );
+
+typedef void (*FnWMain)( int , tchar *[] );
+typedef void (*FnVoidPtrFn)( void * );
+
+#if defined(_WIN32) && !defined(_X360)
+
+// calls the passed in function pointer and catches any exceptions/crashes thrown by it, and writes a minidump
+// use from wmain() to protect the whole program
+typedef void (*FnWMain)( int , tchar *[] );
+typedef int (*FnWMainIntRet)( int , tchar *[] );
+typedef void (*FnVoidPtrFn)( void * );
+
+enum ECatchAndWriteMinidumpAction
+{
+ k_ECatchAndWriteMiniDumpAbort = 0,
+ k_ECatchAndWriteMiniDumpReThrow = 1,
+ k_ECatchAndWriteMiniDumpIgnore = 2,
+};
+
+PLATFORM_INTERFACE void CatchAndWriteMiniDump( FnWMain pfn, int argc, tchar *argv[] ); // action = Abort
+PLATFORM_INTERFACE void CatchAndWriteMiniDumpForVoidPtrFn( FnVoidPtrFn pfn, void *pv, bool bExitQuietly ); // action = abort if bExitQuietly, Rethrow otherwise
+
+PLATFORM_INTERFACE void CatchAndWriteMiniDumpEx( FnWMain pfn, int argc, tchar *argv[], ECatchAndWriteMinidumpAction eAction );
+PLATFORM_INTERFACE int CatchAndWriteMiniDumpExReturnsInt( FnWMainIntRet pfn, int argc, tchar *argv[], ECatchAndWriteMinidumpAction eAction );
+PLATFORM_INTERFACE void CatchAndWriteMiniDumpExForVoidPtrFn( FnVoidPtrFn pfn, void *pv, ECatchAndWriteMinidumpAction eAction );
+
+// Let's not include this. We'll use forwards instead.
+//#include <dbghelp.h>
+struct _EXCEPTION_POINTERS;
+
+// Replaces the current function pointer with the one passed in.
+// Returns the previously-set function.
+// The function is called internally by WriteMiniDump() and CatchAndWriteMiniDump()
+// The default is the built-in function that uses DbgHlp.dll's MiniDumpWriteDump function
+typedef void (*FnMiniDump)( unsigned int uStructuredExceptionCode, _EXCEPTION_POINTERS * pExceptionInfo, const char *pszFilenameSuffix );
+PLATFORM_INTERFACE FnMiniDump SetMiniDumpFunction( FnMiniDump pfn );
+
+// Use this to write a minidump explicitly.
+// Some of the tools choose to catch the minidump themselves instead of using CatchAndWriteMinidump
+// so they can show their own dialog.
+//
+// ptchMinidumpFileNameBuffer if not-NULL should be a writable tchar buffer of length at
+// least _MAX_PATH and on return will contain the name of the minidump file written.
+// If ptchMinidumpFileNameBuffer is NULL the name of the minidump file written will not
+// be available after the function returns.
+//
+PLATFORM_INTERFACE bool WriteMiniDumpUsingExceptionInfo(
+ unsigned int uStructuredExceptionCode,
+ _EXCEPTION_POINTERS * pExceptionInfo,
+ int /* MINIDUMP_TYPE */ minidumpType,
+ const char *pszFilenameSuffix = NULL,
+ tchar *ptchMinidumpFileNameBuffer = NULL
+ );
+
+// Call this to enable a handler for unhandled exceptions.
+PLATFORM_INTERFACE void MinidumpSetUnhandledExceptionFunction( FnMiniDump pfn );
+
+// Call this to prevent crashes in kernel callbacks such as window procs from
+// being silently swallowed. We should always call this at startup.
+PLATFORM_INTERFACE void EnableCrashingOnCrashes();
+
+#endif
+
+#endif // MINIDUMP_H
diff --git a/sp/src/public/tier0/platform.h b/sp/src/public/tier0/platform.h
index 1ff753f5..0e5a3428 100644
--- a/sp/src/public/tier0/platform.h
+++ b/sp/src/public/tier0/platform.h
@@ -1,1576 +1,1576 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//===========================================================================//
-
-#ifndef PLATFORM_H
-#define PLATFORM_H
-
-#if defined( _X360 )
- #define NO_STEAM
- #define NO_VOICE
- // for the 360, the ppc platform and the rtos are tightly coupled
- // setup the 360 environment here !once! for much less leaf module include wackiness
- // these are critical order and purposely appear *before* anything else
- #define _XBOX
-#include <xtl.h>
- #include <xaudio2.h>
- #include <xbdm.h>
-#include <Xgraphics.h>
- #include <xui.h>
- #include <pmcpbsetup.h>
-#include <XMAHardwareAbstraction.h>
- #undef _XBOX
-#endif
-
-#include "wchartypes.h"
-#include "basetypes.h"
-#include "tier0/valve_off.h"
-
-#ifdef _DEBUG
-#if !defined( PLAT_COMPILE_TIME_ASSERT )
-#define PLAT_COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
-#endif
-#else
-#if !defined( PLAT_COMPILE_TIME_ASSERT )
-#define PLAT_COMPILE_TIME_ASSERT( pred )
-#endif
-#endif
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-// feature enables
-#define NEW_SOFTWARE_LIGHTING
-
-#ifdef POSIX
-// need this for _alloca
-#include <alloca.h>
-#include <unistd.h>
- #include <signal.h>
-#include <time.h>
-#endif
-
-#include <malloc.h>
-#include <new>
-
-
-// need this for memset
-#include <string.h>
-
-#include "tier0/valve_minmax_on.h" // GCC 4.2.2 headers screw up our min/max defs.
-
-#ifdef _RETAIL
-#define IsRetail() true
-#else
-#define IsRetail() false
-#endif
-
-#ifdef _DEBUG
-#define IsRelease() false
-#define IsDebug() true
-#else
-#define IsRelease() true
-#define IsDebug() false
-#endif
-
-// Deprecating, infavor of IsX360() which will revert to IsXbox()
-// after confidence of xbox 1 code flush
-#define IsXbox() false
-
-#ifdef _WIN32
- #define IsLinux() false
- #define IsOSX() false
- #define IsPosix() false
- #define PLATFORM_WINDOWS 1 // Windows PC or Xbox 360
- #ifndef _X360
- #define IsWindows() true
- #define IsPC() true
- #define IsConsole() false
- #define IsX360() false
- #define IsPS3() false
- #define IS_WINDOWS_PC
- #define PLATFORM_WINDOWS_PC 1 // Windows PC
- #ifdef _WIN64
- #define IsPlatformWindowsPC64() true
- #define IsPlatformWindowsPC32() false
- #define PLATFORM_WINDOWS_PC64 1
- #else
- #define IsPlatformWindowsPC64() false
- #define IsPlatformWindowsPC32() true
- #define PLATFORM_WINDOWS_PC32 1
- #endif
- #else
- #define PLATFORM_X360 1
- #ifndef _CONSOLE
- #define _CONSOLE
- #endif
- #define IsWindows() false
- #define IsPC() false
- #define IsConsole() true
- #define IsX360() true
- #define IsPS3() false
- #endif
- // Adding IsPlatformOpenGL() to help fix a bunch of code that was using IsPosix() to infer if the DX->GL translation layer was being used.
- #if defined( DX_TO_GL_ABSTRACTION )
- #define IsPlatformOpenGL() true
- #else
- #define IsPlatformOpenGL() false
- #endif
-#elif defined(POSIX)
- #define IsPC() true
- #define IsWindows() false
- #define IsConsole() false
- #define IsX360() false
- #define IsPS3() false
- #if defined( LINUX )
- #define IsLinux() true
- #else
- #define IsLinux() false
- #endif
-
- #if defined( OSX )
- #define IsOSX() true
- #else
- #define IsOSX() false
- #endif
-
- #define IsPosix() true
- #define IsPlatformOpenGL() true
-#else
- #error
-#endif
-
-typedef unsigned char uint8;
-typedef signed char int8;
-
-#if defined(__x86_64__) || defined(_WIN64)
- #define X64BITS
-#endif // __x86_64__
-
-#if defined( _WIN32 )
-
- typedef __int16 int16;
- typedef unsigned __int16 uint16;
- typedef __int32 int32;
- typedef unsigned __int32 uint32;
- typedef __int64 int64;
- typedef unsigned __int64 uint64;
-
- #ifdef PLATFORM_64BITS
- typedef __int64 intp; // intp is an integer that can accomodate a pointer
- typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *)
- #else
- typedef __int32 intp;
- typedef unsigned __int32 uintp;
- #endif
-
- #if defined( _X360 )
- #ifdef __m128
- #undef __m128
- #endif
- #define __m128 __vector4
- #endif
-
- // Use this to specify that a function is an override of a virtual function.
- // This lets the compiler catch cases where you meant to override a virtual
- // function but you accidentally changed the function signature and created
- // an overloaded function. Usage in function declarations is like this:
- // int GetData() const OVERRIDE;
- #define OVERRIDE override
-
-#else // _WIN32
-
- typedef short int16;
- typedef unsigned short uint16;
- typedef int int32;
- typedef unsigned int uint32;
- typedef long long int64;
- typedef unsigned long long uint64;
- #ifdef X64BITS
- typedef long long intp;
- typedef unsigned long long uintp;
- #else
- typedef int intp;
- typedef unsigned int uintp;
- #endif
- typedef void *HWND;
-
- // Avoid redefinition warnings if a previous header defines this.
- #undef OVERRIDE
- #if defined(__clang__)
- #define OVERRIDE override
- // warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
- // Disabling this warning is less intrusive than enabling C++11 extensions
- #pragma GCC diagnostic ignored "-Wc++11-extensions"
- #else
- #define OVERRIDE
- #endif
-
-#endif // else _WIN32
-
-// From steam/steamtypes.h
-// RTime32
-// We use this 32 bit time representing real world time.
-// It offers 1 second resolution beginning on January 1, 1970 (Unix time)
-typedef uint32 RTime32;
-
-typedef float float32;
-typedef double float64;
-
-// for when we don't care about how many bits we use
-typedef unsigned int uint;
-
-#ifdef _MSC_VER
-#pragma once
-// Ensure that everybody has the right compiler version installed. The version
-// number can be obtained by looking at the compiler output when you type 'cl'
-// and removing the last two digits and the periods: 16.00.40219.01 becomes 160040219
-#if _MSC_FULL_VER > 160000000
- #if _MSC_FULL_VER < 160040219
- #error You must install VS 2010 SP1
- #endif
-#else
- #if _MSC_FULL_VER < 140050727
- #error You must install VS 2005 SP1
- #endif
-#endif
-#endif
-
-// This can be used to ensure the size of pointers to members when declaring
-// a pointer type for a class that has only been forward declared
-#ifdef _MSC_VER
-#define SINGLE_INHERITANCE __single_inheritance
-#define MULTIPLE_INHERITANCE __multiple_inheritance
-#else
-#define SINGLE_INHERITANCE
-#define MULTIPLE_INHERITANCE
-#endif
-
-#ifdef _MSC_VER
-#define NO_VTABLE __declspec( novtable )
-#else
-#define NO_VTABLE
-#endif
-
-#ifdef _MSC_VER
- // This indicates that a function never returns, which helps with
- // generating accurate compiler warnings
- #define NORETURN __declspec( noreturn )
-#else
- #define NORETURN
-#endif
-
-// This can be used to declare an abstract (interface only) class.
-// Classes marked abstract should not be instantiated. If they are, and access violation will occur.
-//
-// Example of use:
-//
-// abstract_class CFoo
-// {
-// ...
-// }
-//
-// MSDN __declspec(novtable) documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_novtable.asp
-//
-// Note: NJS: This is not enabled for regular PC, due to not knowing the implications of exporting a class with no no vtable.
-// It's probable that this shouldn't be an issue, but an experiment should be done to verify this.
-//
-#ifndef _X360
-#define abstract_class class
-#else
-#define abstract_class class NO_VTABLE
-#endif
-
-
-// MSVC CRT uses 0x7fff while gcc uses MAX_INT, leading to mismatches between platforms
-// As a result, we pick the least common denominator here. This should be used anywhere
-// you might typically want to use RAND_MAX
-#define VALVE_RAND_MAX 0x7fff
-
-
-
-/*
-FIXME: Enable this when we no longer fear change =)
-
-// need these for the limits
-#include <limits.h>
-#include <float.h>
-
-// Maximum and minimum representable values
-#define INT8_MAX SCHAR_MAX
-#define INT16_MAX SHRT_MAX
-#define INT32_MAX LONG_MAX
-#define INT64_MAX (((int64)~0) >> 1)
-
-#define INT8_MIN SCHAR_MIN
-#define INT16_MIN SHRT_MIN
-#define INT32_MIN LONG_MIN
-#define INT64_MIN (((int64)1) << 63)
-
-#define UINT8_MAX ((uint8)~0)
-#define UINT16_MAX ((uint16)~0)
-#define UINT32_MAX ((uint32)~0)
-#define UINT64_MAX ((uint64)~0)
-
-#define UINT8_MIN 0
-#define UINT16_MIN 0
-#define UINT32_MIN 0
-#define UINT64_MIN 0
-
-#ifndef UINT_MIN
-#define UINT_MIN UINT32_MIN
-#endif
-
-#define FLOAT32_MAX FLT_MAX
-#define FLOAT64_MAX DBL_MAX
-
-#define FLOAT32_MIN FLT_MIN
-#define FLOAT64_MIN DBL_MIN
-*/
-
-// portability / compiler settings
-#if defined(_WIN32) && !defined(WINDED)
-
-#if defined(_M_IX86)
-#define __i386__ 1
-#endif
-
-#elif POSIX
-#if defined( OSX ) && defined( CARBON_WORKAROUND )
-#define DWORD unsigned int
-#else
-typedef unsigned int DWORD;
-#endif
-typedef unsigned short WORD;
-typedef void * HINSTANCE;
-#define _MAX_PATH PATH_MAX
-#define __cdecl
-#define __stdcall
-#define __declspec
-
-#endif // defined(_WIN32) && !defined(WINDED)
-
-
-// Defines MAX_PATH
-#ifndef MAX_PATH
-#define MAX_PATH 260
-#endif
-
-#ifdef _WIN32
-#define MAX_UNICODE_PATH 32767
-#else
-#define MAX_UNICODE_PATH MAX_PATH
-#endif
-
-#define MAX_UNICODE_PATH_IN_UTF8 MAX_UNICODE_PATH*4
-
-#ifdef GNUC
-#undef offsetof
-//#define offsetof( type, var ) __builtin_offsetof( type, var )
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#else
-#undef offsetof
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-#endif
-
-
-#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression
-
-// Used to step into the debugger
-#if defined( _WIN32 ) && !defined( _X360 )
-#define DebuggerBreak() __debugbreak()
-#elif defined( _X360 )
-#define DebuggerBreak() DebugBreak()
-#else
- // On OSX, SIGTRAP doesn't really stop the thread cold when debugging.
- // So if being debugged, use INT3 which is precise.
-#ifdef OSX
-#define DebuggerBreak() if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); }
-#else
-#define DebuggerBreak() raise(SIGTRAP)
-#endif
-#endif
-#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak()
-
-// C functions for external declarations that call the appropriate C++ methods
-#ifndef EXPORT
- #ifdef _WIN32
- #define EXPORT _declspec( dllexport )
- #else
- #define EXPORT /* */
- #endif
-#endif
-
-#if defined __i386__ && !defined __linux__
- #define id386 1
-#else
- #define id386 0
-#endif // __i386__
-
-// decls for aligning data
-#ifdef _WIN32
- #define DECL_ALIGN(x) __declspec(align(x))
-
-#elif GNUC
- #define DECL_ALIGN(x) __attribute__((aligned(x)))
-#else
- #define DECL_ALIGN(x) /* */
-#endif
-
-#ifdef _MSC_VER
-// MSVC has the align at the start of the struct
-#define ALIGN4 DECL_ALIGN(4)
-#define ALIGN8 DECL_ALIGN(8)
-#define ALIGN16 DECL_ALIGN(16)
-#define ALIGN32 DECL_ALIGN(32)
-#define ALIGN128 DECL_ALIGN(128)
-
-#define ALIGN4_POST
-#define ALIGN8_POST
-#define ALIGN16_POST
-#define ALIGN32_POST
-#define ALIGN128_POST
-#elif defined( GNUC )
-// gnuc has the align decoration at the end
-#define ALIGN4
-#define ALIGN8
-#define ALIGN16
-#define ALIGN32
-#define ALIGN128
-
-#define ALIGN4_POST DECL_ALIGN(4)
-#define ALIGN8_POST DECL_ALIGN(8)
-#define ALIGN16_POST DECL_ALIGN(16)
-#define ALIGN32_POST DECL_ALIGN(32)
-#define ALIGN128_POST DECL_ALIGN(128)
-#else
-#error
-#endif
-
-// Pull in the /analyze code annotations.
-#include "annotations.h"
-
-//-----------------------------------------------------------------------------
-// Convert int<-->pointer, avoiding 32/64-bit compiler warnings:
-//-----------------------------------------------------------------------------
-#define INT_TO_POINTER( i ) (void *)( ( i ) + (char *)NULL )
-#define POINTER_TO_INT( p ) ( (int)(uintp)( p ) )
-
-
-//-----------------------------------------------------------------------------
-// Stack-based allocation related helpers
-//-----------------------------------------------------------------------------
-#if defined( GNUC )
- #define stackalloc( _size ) alloca( ALIGN_VALUE( _size, 16 ) )
-#ifdef _LINUX
- #define mallocsize( _p ) ( malloc_usable_size( _p ) )
-#elif defined(OSX)
- #define mallocsize( _p ) ( malloc_size( _p ) )
-#else
-#error
-#endif
-#elif defined ( _WIN32 )
- #define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) )
- #define mallocsize( _p ) ( _msize( _p ) )
-#endif
-
-#define stackfree( _p ) 0
-
-// Linux had a few areas where it didn't construct objects in the same order that Windows does.
-// So when CVProfile::CVProfile() would access g_pMemAlloc, it would crash because the allocator wasn't initalized yet.
-#ifdef POSIX
- #define CONSTRUCT_EARLY __attribute__((init_priority(101)))
-#else
- #define CONSTRUCT_EARLY
- #endif
-
-#if defined(_MSC_VER)
- #define SELECTANY __declspec(selectany)
- #define RESTRICT __restrict
- #define RESTRICT_FUNC __declspec(restrict)
- #define FMTFUNCTION( a, b )
-#elif defined(GNUC)
- #define SELECTANY __attribute__((weak))
- #if defined(LINUX) && !defined(DEDICATED)
- #define RESTRICT
- #else
- #define RESTRICT __restrict
- #endif
- #define RESTRICT_FUNC
- // squirrel.h does a #define printf DevMsg which leads to warnings when we try
- // to use printf as the prototype format function. Using __printf__ instead.
- #define FMTFUNCTION( fmtargnumber, firstvarargnumber ) __attribute__ (( format( __printf__, fmtargnumber, firstvarargnumber )))
-#else
- #define SELECTANY static
- #define RESTRICT
- #define RESTRICT_FUNC
- #define FMTFUNCTION( a, b )
-#endif
-
-#if defined( _WIN32 )
-
- // Used for dll exporting and importing
- #define DLL_EXPORT extern "C" __declspec( dllexport )
- #define DLL_IMPORT extern "C" __declspec( dllimport )
-
- // Can't use extern "C" when DLL exporting a class
- #define DLL_CLASS_EXPORT __declspec( dllexport )
- #define DLL_CLASS_IMPORT __declspec( dllimport )
-
- // Can't use extern "C" when DLL exporting a global
- #define DLL_GLOBAL_EXPORT extern __declspec( dllexport )
- #define DLL_GLOBAL_IMPORT extern __declspec( dllimport )
-
- #define DLL_LOCAL
-
-#elif defined GNUC
-// Used for dll exporting and importing
-#define DLL_EXPORT extern "C" __attribute__ ((visibility("default")))
-#define DLL_IMPORT extern "C"
-
-// Can't use extern "C" when DLL exporting a class
-#define DLL_CLASS_EXPORT __attribute__ ((visibility("default")))
-#define DLL_CLASS_IMPORT
-
-// Can't use extern "C" when DLL exporting a global
-#define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default")))
-#define DLL_GLOBAL_IMPORT extern
-
-#define DLL_LOCAL __attribute__ ((visibility("hidden")))
-
-#else
-#error "Unsupported Platform."
-#endif
-
-// Used for standard calling conventions
-#if defined( _WIN32 ) && !defined( _X360 )
- #define STDCALL __stdcall
- #define FASTCALL __fastcall
- #define FORCEINLINE __forceinline
- // GCC 3.4.1 has a bug in supporting forced inline of templated functions
- // this macro lets us not force inlining in that case
- #define FORCEINLINE_TEMPLATE __forceinline
-#elif defined( _X360 )
- #define STDCALL __stdcall
- #ifdef FORCEINLINE
- #undef FORCEINLINE
-#endif
- #define FORCEINLINE __forceinline
- #define FORCEINLINE_TEMPLATE __forceinline
- #else
- #define STDCALL
- #define FASTCALL
- #ifdef _LINUX_DEBUGGABLE
- #define FORCEINLINE
- #else
- #define FORCEINLINE inline __attribute__ ((always_inline))
- #endif
- // GCC 3.4.1 has a bug in supporting forced inline of templated functions
- // this macro lets us not force inlining in that case
- #define FORCEINLINE_TEMPLATE inline
-// #define __stdcall __attribute__ ((__stdcall__))
-#endif
-
-// Force a function call site -not- to inlined. (useful for profiling)
-#define DONT_INLINE(a) (((int)(a)+1)?(a):(a))
-
-// Pass hints to the compiler to prevent it from generating unnessecary / stupid code
-// in certain situations. Several compilers other than MSVC also have an equivilent
-// construct.
-//
-// Essentially the 'Hint' is that the condition specified is assumed to be true at
-// that point in the compilation. If '0' is passed, then the compiler assumes that
-// any subsequent code in the same 'basic block' is unreachable, and thus usually
-// removed.
-#ifdef _MSC_VER
- #define HINT(THE_HINT) __assume((THE_HINT))
-#else
- #define HINT(THE_HINT) 0
-#endif
-
-// Marks the codepath from here until the next branch entry point as unreachable,
-// and asserts if any attempt is made to execute it.
-#define UNREACHABLE() { Assert(0); HINT(0); }
-
-// In cases where no default is present or appropriate, this causes MSVC to generate
-// as little code as possible, and throw an assertion in debug.
-#define NO_DEFAULT default: UNREACHABLE();
-
-
-#ifdef _WIN32
-
-// Remove warnings from warning level 4.
-#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
-#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
-#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
-#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
-#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
-#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined
-#pragma warning(disable : 4702) // warning C4702: unreachable code
-#pragma warning(disable : 4505) // unreferenced local function has been removed
-#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& )
-#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex'
-#pragma warning(disable : 4324) // Padding was added at the end of a structure
-#pragma warning(disable : 4244) // type conversion warning.
-#pragma warning(disable : 4305) // truncation from 'const double ' to 'float '
-#pragma warning(disable : 4786) // Disable warnings about long symbol names
-#pragma warning(disable : 4250) // 'X' : inherits 'Y::Z' via dominance
-#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
-#pragma warning(disable : 4481) // warning C4481: nonstandard extension used: override specifier 'override'
-#pragma warning(disable : 4748) // warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
-
-#if _MSC_VER >= 1300
-#pragma warning(disable : 4511) // Disable warnings about private copy constructors
-#pragma warning(disable : 4121) // warning C4121: 'symbol' : alignment of a member was sensitive to packing
-#pragma warning(disable : 4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc (disabled due to std headers having exception syntax)
-#endif
-
-#if _MSC_VER >= 1400
-#pragma warning(disable : 4996) // functions declared deprecated
-#endif
-
-
-#endif // _WIN32
-
-#if defined( LINUX ) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
- // based on some Jonathan Wakely macros on the net...
- #define GCC_DIAG_STR(s) #s
- #define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y)
- #define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
- #define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
-
- #define GCC_DIAG_PUSH_OFF(x) GCC_DIAG_PRAGMA(push) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
- #define GCC_DIAG_POP() GCC_DIAG_PRAGMA(pop)
-#else
- #define GCC_DIAG_PUSH_OFF(x)
- #define GCC_DIAG_POP()
-#endif
-
-#ifdef LINUX
-#pragma GCC diagnostic ignored "-Wconversion-null" // passing NULL to non-pointer argument 1
-#pragma GCC diagnostic ignored "-Wpointer-arith" // NULL used in arithmetic. Ie, vpanel == NULL where VPANEL is uint.
-#pragma GCC diagnostic ignored "-Wswitch" // enumeration values not handled in switch
-#endif
-
-#ifdef OSX
-#pragma GCC diagnostic ignored "-Wconversion-null" // passing NULL to non-pointer argument 1
-#pragma GCC diagnostic ignored "-Wnull-arithmetic" // NULL used in arithmetic. Ie, vpanel == NULL where VPANEL is uint.
-#pragma GCC diagnostic ignored "-Wswitch-enum" // enumeration values not handled in switch
-#pragma GCC diagnostic ignored "-Wswitch" // enumeration values not handled in switch
-#endif
-
-
-// When we port to 64 bit, we'll have to resolve the int, ptr vs size_t 32/64 bit problems...
-#if !defined( _WIN64 )
-#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data
-#pragma warning( disable : 4311 ) // pointer truncation from 'char *' to 'int'
-#pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size
-#endif
-
-
-#ifdef POSIX
-#define _stricmp stricmp
-#define strcmpi stricmp
-#define stricmp strcasecmp
-#define _vsnprintf vsnprintf
-#define _alloca alloca
-#ifdef _snprintf
-#undef _snprintf
-#endif
-#define _snprintf snprintf
-#define GetProcAddress dlsym
-#define _chdir chdir
-#define _strnicmp strnicmp
-#define strnicmp strncasecmp
-#define _getcwd getcwd
-#define _snwprintf swprintf
-#define swprintf_s swprintf
-#define wcsicmp _wcsicmp
-#define _wcsicmp wcscmp
-#define _finite finite
-#define _tempnam tempnam
-#define _unlink unlink
-#define _access access
-#define _mkdir(dir) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO )
-#define _wtoi(arg) wcstol(arg, NULL, 10)
-#define _wtoi64(arg) wcstoll(arg, NULL, 10)
-
-typedef uint32 HMODULE;
-typedef void *HANDLE;
-#endif
-
-//-----------------------------------------------------------------------------
-// fsel
-//-----------------------------------------------------------------------------
-#ifndef _X360
-
-static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT)
-{
- return fComparand >= 0 ? fValGE : fLT;
-}
-static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT)
-{
- return fComparand >= 0 ? fValGE : fLT;
-}
-
-#else
-
-// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT
-// this is much faster than if ( aFloat > 0 ) { x = .. }
-#define fsel __fsel
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-// FP exception handling
-//-----------------------------------------------------------------------------
-//#define CHECK_FLOAT_EXCEPTIONS 1
-
-#if !defined( _X360 )
-#if defined( _MSC_VER )
-
- #if defined( PLATFORM_WINDOWS_PC64 )
- inline void SetupFPUControlWord()
- {
- }
- #else
- inline void SetupFPUControlWordForceExceptions()
- {
- // use local to get and store control word
- uint16 tmpCtrlW;
- __asm
- {
- fnclex /* clear all current exceptions */
- fnstcw word ptr [tmpCtrlW] /* get current control word */
- and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
- or [tmpCtrlW], 0230h /* set to 53-bit, mask only inexact, underflow */
- fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
- }
- }
-
- #ifdef CHECK_FLOAT_EXCEPTIONS
-
- inline void SetupFPUControlWord()
- {
- SetupFPUControlWordForceExceptions();
- }
-
- #else
-
- inline void SetupFPUControlWord()
- {
- // use local to get and store control word
- uint16 tmpCtrlW;
- __asm
- {
- fnstcw word ptr [tmpCtrlW] /* get current control word */
- and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
- or [tmpCtrlW], 023Fh /* set to 53-bit, mask only inexact, underflow */
- fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
- }
- }
-
- #endif
- #endif
-
-#else
-
- inline void SetupFPUControlWord()
- {
- __volatile unsigned short int __cw;
- __asm __volatile ("fnstcw %0" : "=m" (__cw));
- __cw = __cw & 0x0FCC0; // keep infinity control, keep rounding mode
- __cw = __cw | 0x023F; // set 53-bit, no exceptions
- __asm __volatile ("fldcw %0" : : "m" (__cw));
- }
-
-#endif // _MSC_VER
-
-#else
-
- #ifdef _DEBUG
- FORCEINLINE bool IsFPUControlWordSet()
- {
- float f = 0.996f;
- union
- {
- double flResult;
- int pResult[2];
- };
- flResult = __fctiw( f );
- return ( pResult[1] == 1 );
- }
- #endif
-
- inline void SetupFPUControlWord()
- {
- // Set round-to-nearest in FPSCR
- // (cannot assemble, must use op-code form)
- __emit( 0xFF80010C ); // mtfsfi 7,0
-
- // Favour compatibility over speed (make sure the VPU set to Java-compliant mode)
- // NOTE: the VPU *always* uses round-to-nearest
- __vector4 a = { 0.0f, 0.0f, 0.0f, 0.0f };
- a; // Avoid compiler warning
- __asm
- {
- mtvscr a; // Clear the Vector Status & Control Register to zero
- }
- }
-
-#endif // _X360
-
-//-----------------------------------------------------------------------------
-// Purpose: Standard functions for handling endian-ness
-//-----------------------------------------------------------------------------
-
-//-------------------------------------
-// Basic swaps
-//-------------------------------------
-
-template <typename T>
-inline T WordSwapC( T w )
-{
- uint16 temp;
-
- temp = ((*((uint16 *)&w) & 0xff00) >> 8);
- temp |= ((*((uint16 *)&w) & 0x00ff) << 8);
-
- return *((T*)&temp);
-}
-
-template <typename T>
-inline T DWordSwapC( T dw )
-{
- uint32 temp;
-
- temp = *((uint32 *)&dw) >> 24;
- temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8);
- temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8);
- temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24);
-
- return *((T*)&temp);
-}
-
-template <typename T>
-inline T QWordSwapC( T dw )
-{
- // Assert sizes passed to this are already correct, otherwise
- // the cast to uint64 * below is unsafe and may have wrong results
- // or even crash.
- PLAT_COMPILE_TIME_ASSERT( sizeof( dw ) == sizeof(uint64) );
-
- uint64 temp;
-
- temp = *((uint64 *)&dw) >> 56;
- temp |= ((*((uint64 *)&dw) & 0x00FF000000000000ull) >> 40);
- temp |= ((*((uint64 *)&dw) & 0x0000FF0000000000ull) >> 24);
- temp |= ((*((uint64 *)&dw) & 0x000000FF00000000ull) >> 8);
- temp |= ((*((uint64 *)&dw) & 0x00000000FF000000ull) << 8);
- temp |= ((*((uint64 *)&dw) & 0x0000000000FF0000ull) << 24);
- temp |= ((*((uint64 *)&dw) & 0x000000000000FF00ull) << 40);
- temp |= ((*((uint64 *)&dw) & 0x00000000000000FFull) << 56);
-
- return *((T*)&temp);
-}
-
-//-------------------------------------
-// Fast swaps
-//-------------------------------------
-
-#if defined( _X360 )
-
- #define WordSwap WordSwap360Intr
- #define DWordSwap DWordSwap360Intr
-
- template <typename T>
- inline T WordSwap360Intr( T w )
- {
- T output;
- __storeshortbytereverse( w, 0, &output );
- return output;
- }
-
- template <typename T>
- inline T DWordSwap360Intr( T dw )
- {
- T output;
- __storewordbytereverse( dw, 0, &output );
- return output;
- }
-
-#elif defined( _MSC_VER ) && !defined( PLATFORM_WINDOWS_PC64 )
-
- #define WordSwap WordSwapAsm
- #define DWordSwap DWordSwapAsm
-
- #pragma warning(push)
- #pragma warning (disable:4035) // no return value
-
- template <typename T>
- inline T WordSwapAsm( T w )
- {
- __asm
- {
- mov ax, w
- xchg al, ah
- }
- }
-
- template <typename T>
- inline T DWordSwapAsm( T dw )
- {
- __asm
- {
- mov eax, dw
- bswap eax
- }
- }
-
- #pragma warning(pop)
-
-#else
-
- #define WordSwap WordSwapC
- #define DWordSwap DWordSwapC
-
-#endif
-
-// No ASM implementation for this yet
-#define QWordSwap QWordSwapC
-
-//-------------------------------------
-// The typically used methods.
-//-------------------------------------
-
-#if defined(__i386__) && !defined(VALVE_LITTLE_ENDIAN)
-#define VALVE_LITTLE_ENDIAN 1
-#endif
-
-#if defined( _SGI_SOURCE ) || defined( _X360 )
-#define VALVE_BIG_ENDIAN 1
-#endif
-
-// If a swapped float passes through the fpu, the bytes may get changed.
-// Prevent this by swapping floats as DWORDs.
-#define SafeSwapFloat( pOut, pIn ) (*((uint*)pOut) = DWordSwap( *((uint*)pIn) ))
-
-#if defined(VALVE_LITTLE_ENDIAN)
-
-#define BigShort( val ) WordSwap( val )
-#define BigWord( val ) WordSwap( val )
-#define BigLong( val ) DWordSwap( val )
-#define BigDWord( val ) DWordSwap( val )
-#define LittleShort( val ) ( val )
-#define LittleWord( val ) ( val )
-#define LittleLong( val ) ( val )
-#define LittleDWord( val ) ( val )
-#define LittleQWord( val ) ( val )
-#define SwapShort( val ) BigShort( val )
-#define SwapWord( val ) BigWord( val )
-#define SwapLong( val ) BigLong( val )
-#define SwapDWord( val ) BigDWord( val )
-
-// Pass floats by pointer for swapping to avoid truncation in the fpu
-#define BigFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
-#define LittleFloat( pOut, pIn ) ( *pOut = *pIn )
-#define SwapFloat( pOut, pIn ) BigFloat( pOut, pIn )
-
-#elif defined(VALVE_BIG_ENDIAN)
-
-#define BigShort( val ) ( val )
-#define BigWord( val ) ( val )
-#define BigLong( val ) ( val )
-#define BigDWord( val ) ( val )
-#define LittleShort( val ) WordSwap( val )
-#define LittleWord( val ) WordSwap( val )
-#define LittleLong( val ) DWordSwap( val )
-#define LittleDWord( val ) DWordSwap( val )
-#define LittleQWord( val ) QWordSwap( val )
-#define SwapShort( val ) LittleShort( val )
-#define SwapWord( val ) LittleWord( val )
-#define SwapLong( val ) LittleLong( val )
-#define SwapDWord( val ) LittleDWord( val )
-
-// Pass floats by pointer for swapping to avoid truncation in the fpu
-#define BigFloat( pOut, pIn ) ( *pOut = *pIn )
-#define LittleFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
-#define SwapFloat( pOut, pIn ) LittleFloat( pOut, pIn )
-
-#else
-
-// @Note (toml 05-02-02): this technique expects the compiler to
-// optimize the expression and eliminate the other path. On any new
-// platform/compiler this should be tested.
-inline short BigShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
-inline uint16 BigWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
-inline long BigLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
-inline uint32 BigDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
-inline short LittleShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
-inline uint16 LittleWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
-inline long LittleLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
-inline uint32 LittleDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
-inline uint64 LittleQWord( uint64 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : QWordSwap( val ); }
-inline short SwapShort( short val ) { return WordSwap( val ); }
-inline uint16 SwapWord( uint16 val ) { return WordSwap( val ); }
-inline long SwapLong( long val ) { return DWordSwap( val ); }
-inline uint32 SwapDWord( uint32 val ) { return DWordSwap( val ); }
-
-// Pass floats by pointer for swapping to avoid truncation in the fpu
-inline void BigFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? SafeSwapFloat( pOut, pIn ) : ( *pOut = *pIn ); }
-inline void LittleFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? ( *pOut = *pIn ) : SafeSwapFloat( pOut, pIn ); }
-inline void SwapFloat( float *pOut, const float *pIn ) { SafeSwapFloat( pOut, pIn ); }
-
-#endif
-
-#if _X360
-FORCEINLINE unsigned long LoadLittleDWord( const unsigned long *base, unsigned int dwordIndex )
- {
- return __loadwordbytereverse( dwordIndex<<2, base );
- }
-
-FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword )
- {
- __storewordbytereverse( dword, dwordIndex<<2, base );
- }
-#else
-FORCEINLINE unsigned long LoadLittleDWord( const unsigned long *base, unsigned int dwordIndex )
- {
- return LittleDWord( base[dwordIndex] );
- }
-
-FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword )
- {
- base[dwordIndex] = LittleDWord(dword);
- }
-#endif
-
-
-//-----------------------------------------------------------------------------
-// DLL export for platform utilities
-//-----------------------------------------------------------------------------
-#ifndef STATIC_TIER0
-
-#ifdef TIER0_DLL_EXPORT
-#define PLATFORM_INTERFACE DLL_EXPORT
-#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT
-#define PLATFORM_CLASS DLL_CLASS_EXPORT
-#else
-#define PLATFORM_INTERFACE DLL_IMPORT
-#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT
-#define PLATFORM_CLASS DLL_CLASS_IMPORT
-#endif
-
-#else // BUILD_AS_DLL
-
-#define PLATFORM_INTERFACE extern
-#define PLATFORM_OVERLOAD
-#define PLATFORM_CLASS
-
-#endif // BUILD_AS_DLL
-
-
-// When in benchmark mode, the timer returns a simple incremented value each time you call it.
-//
-// It should not be changed after startup unless you really know what you're doing. The only place
-// that should do this is the benchmark code itself so it can output a legit duration.
-PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode );
-PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode();
-
-
-PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
-PLATFORM_INTERFACE unsigned int Plat_MSTime(); // Time in milliseconds.
-PLATFORM_INTERFACE char * Plat_asctime( const struct tm *tm, char *buf );
-PLATFORM_INTERFACE char * Plat_ctime( const time_t *timep, char *buf, size_t bufsize );
-PLATFORM_INTERFACE struct tm * Plat_gmtime( const time_t *timep, struct tm *result );
-PLATFORM_INTERFACE time_t Plat_timegm( struct tm *timeptr );
-PLATFORM_INTERFACE struct tm * Plat_localtime( const time_t *timep, struct tm *result );
-
-#if defined( _WIN32 ) && defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
- extern "C" unsigned __int64 __rdtsc();
- #pragma intrinsic(__rdtsc)
-#endif
-
-inline uint64 Plat_Rdtsc()
-{
-#if defined( _X360 )
- return ( uint64 )__mftb32();
-#elif defined( _WIN64 )
- return ( uint64 )__rdtsc();
-#elif defined( _WIN32 )
- #if defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
- return ( uint64 )__rdtsc();
- #else
- __asm rdtsc;
- __asm ret;
- #endif
-#elif defined( __i386__ )
- uint64 val;
- __asm__ __volatile__ ( "rdtsc" : "=A" (val) );
- return val;
-#elif defined( __x86_64__ )
- uint32 lo, hi;
- __asm__ __volatile__ ( "rdtsc" : "=a" (lo), "=d" (hi));
- return ( ( ( uint64 )hi ) << 32 ) | lo;
-#else
- #error
-#endif
-}
-
-// b/w compatibility
-#define Sys_FloatTime Plat_FloatTime
-
-// Protect against bad auto operator=
-#define DISALLOW_OPERATOR_EQUAL( _classname ) \
- private: \
- _classname &operator=( const _classname & ); \
- public:
-
-// Define a reasonable operator=
-#define IMPLEMENT_OPERATOR_EQUAL( _classname ) \
- public: \
- _classname &operator=( const _classname &src ) \
- { \
- memcpy( this, &src, sizeof(_classname) ); \
- return *this; \
- }
-
-// Processor Information:
-struct CPUInformation
-{
- int m_Size; // Size of this structure, for forward compatability.
-
- bool m_bRDTSC : 1, // Is RDTSC supported?
- m_bCMOV : 1, // Is CMOV supported?
- m_bFCMOV : 1, // Is FCMOV supported?
- m_bSSE : 1, // Is SSE supported?
- m_bSSE2 : 1, // Is SSE2 Supported?
- m_b3DNow : 1, // Is 3DNow! Supported?
- m_bMMX : 1, // Is MMX supported?
- m_bHT : 1; // Is HyperThreading supported?
-
- uint8 m_nLogicalProcessors; // Number op logical processors.
- uint8 m_nPhysicalProcessors; // Number of physical processors
-
- bool m_bSSE3 : 1,
- m_bSSSE3 : 1,
- m_bSSE4a : 1,
- m_bSSE41 : 1,
- m_bSSE42 : 1;
-
- int64 m_Speed; // In cycles per second.
-
- tchar* m_szProcessorID; // Processor vendor Identification.
-
- CPUInformation(): m_Size(0){}
-};
-
-// Have to return a pointer, not a reference, because references are not compatible with the
-// extern "C" implied by PLATFORM_INTERFACE.
-PLATFORM_INTERFACE const CPUInformation* GetCPUInformation();
-
-PLATFORM_INTERFACE float GetCPUUsage();
-
-PLATFORM_INTERFACE void GetCurrentDate( int *pDay, int *pMonth, int *pYear );
-
-// ---------------------------------------------------------------------------------- //
-// Performance Monitoring Events - L2 stats etc...
-// ---------------------------------------------------------------------------------- //
-PLATFORM_INTERFACE void InitPME();
-PLATFORM_INTERFACE void ShutdownPME();
-
-//-----------------------------------------------------------------------------
-// Thread related functions
-//-----------------------------------------------------------------------------
-
-// Sets a hardware data breakpoint on the given address. Currently Win32-only.
-// Specify 1, 2, or 4 bytes for nWatchBytes; pass 0 to unregister the address.
-PLATFORM_INTERFACE void Plat_SetHardwareDataBreakpoint( const void *pAddress, int nWatchBytes, bool bBreakOnRead );
-
-// Apply current hardware data breakpoints to a newly created thread.
-PLATFORM_INTERFACE void Plat_ApplyHardwareDataBreakpointsToNewThread( unsigned long dwThreadID );
-
-//-----------------------------------------------------------------------------
-// Process related functions
-//-----------------------------------------------------------------------------
-PLATFORM_INTERFACE const tchar *Plat_GetCommandLine();
-#ifndef _WIN32
-// helper function for OS's that don't have a ::GetCommandLine() call
-PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine );
-#endif
-PLATFORM_INTERFACE const char *Plat_GetCommandLineA();
-
-//-----------------------------------------------------------------------------
-// Security related functions
-//-----------------------------------------------------------------------------
-// Ensure that the hardware key's drivers have been installed.
-PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver();
-
-// Ok, so this isn't a very secure way to verify the hardware key for now. It
-// is primarially depending on the fact that all the binaries have been wrapped
-// with the secure wrapper provided by the hardware keys vendor.
-PLATFORM_INTERFACE bool Plat_VerifyHardwareKey();
-
-// The same as above, but notifies user with a message box when the key isn't in
-// and gives him an opportunity to correct the situation.
-PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt();
-
-// Can be called in real time, doesn't perform the verify every frame. Mainly just
-// here to allow the game to drop out quickly when the key is removed, rather than
-// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't
-// like much.
-PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey();
-
-//-----------------------------------------------------------------------------
-// Just logs file and line to simple.log
-//-----------------------------------------------------------------------------
-PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line );
-
-#if _X360
-#define Plat_FastMemset XMemSet
-#define Plat_FastMemcpy XMemCpy
-#else
-#define Plat_FastMemset memset
-#define Plat_FastMemcpy memcpy
-#endif
-
-//-----------------------------------------------------------------------------
-// Returns true if debugger attached, false otherwise
-//-----------------------------------------------------------------------------
-#if defined(_WIN32) || defined(LINUX) || defined(OSX)
-PLATFORM_INTERFACE bool Plat_IsInDebugSession( bool bForceRecheck = false );
-PLATFORM_INTERFACE void Plat_DebugString( const char * );
-#else
-inline bool Plat_IsInDebugSession( bool bForceRecheck = false ) { return false; }
-#define Plat_DebugString(s) ((void)0)
-#endif
-
-//-----------------------------------------------------------------------------
-// Returns true if running on a 64 bit (windows) OS
-//-----------------------------------------------------------------------------
-PLATFORM_INTERFACE bool Is64BitOS();
-
-
-//-----------------------------------------------------------------------------
-// XBOX Components valid in PC compilation space
-//-----------------------------------------------------------------------------
-
-#define XBOX_DVD_SECTORSIZE 2048
-#define XBOX_DVD_ECC_SIZE 32768 // driver reads in quantum ECC blocks
-#define XBOX_HDD_SECTORSIZE 512
-
-// Custom windows messages for Xbox input
-#define WM_XREMOTECOMMAND (WM_USER + 100)
-#define WM_XCONTROLLER_KEY (WM_USER + 101)
-#define WM_SYS_UI (WM_USER + 102)
-#define WM_SYS_SIGNINCHANGED (WM_USER + 103)
-#define WM_SYS_STORAGEDEVICESCHANGED (WM_USER + 104)
-#define WM_SYS_PROFILESETTINGCHANGED (WM_USER + 105)
-#define WM_SYS_MUTELISTCHANGED (WM_USER + 106)
-#define WM_SYS_INPUTDEVICESCHANGED (WM_USER + 107)
-#define WM_SYS_INPUTDEVICECONFIGCHANGED (WM_USER + 108)
-#define WM_LIVE_CONNECTIONCHANGED (WM_USER + 109)
-#define WM_LIVE_INVITE_ACCEPTED (WM_USER + 110)
-#define WM_LIVE_LINK_STATE_CHANGED (WM_USER + 111)
-#define WM_LIVE_CONTENT_INSTALLED (WM_USER + 112)
-#define WM_LIVE_MEMBERSHIP_PURCHASED (WM_USER + 113)
-#define WM_LIVE_VOICECHAT_AWAY (WM_USER + 114)
-#define WM_LIVE_PRESENCE_CHANGED (WM_USER + 115)
-#define WM_FRIENDS_PRESENCE_CHANGED (WM_USER + 116)
-#define WM_FRIENDS_FRIEND_ADDED (WM_USER + 117)
-#define WM_FRIENDS_FRIEND_REMOVED (WM_USER + 118)
-#define WM_CUSTOM_GAMEBANNERPRESSED (WM_USER + 119)
-#define WM_CUSTOM_ACTIONPRESSED (WM_USER + 120)
-#define WM_XMP_STATECHANGED (WM_USER + 121)
-#define WM_XMP_PLAYBACKBEHAVIORCHANGED (WM_USER + 122)
-#define WM_XMP_PLAYBACKCONTROLLERCHANGED (WM_USER + 123)
-
-inline const char *GetPlatformExt( void )
-{
- return IsX360() ? ".360" : "";
-}
-
-// flat view, 6 hw threads
-#define XBOX_PROCESSOR_0 ( 1<<0 )
-#define XBOX_PROCESSOR_1 ( 1<<1 )
-#define XBOX_PROCESSOR_2 ( 1<<2 )
-#define XBOX_PROCESSOR_3 ( 1<<3 )
-#define XBOX_PROCESSOR_4 ( 1<<4 )
-#define XBOX_PROCESSOR_5 ( 1<<5 )
-
-// core view, 3 cores with 2 hw threads each
-#define XBOX_CORE_0_HWTHREAD_0 XBOX_PROCESSOR_0
-#define XBOX_CORE_0_HWTHREAD_1 XBOX_PROCESSOR_1
-#define XBOX_CORE_1_HWTHREAD_0 XBOX_PROCESSOR_2
-#define XBOX_CORE_1_HWTHREAD_1 XBOX_PROCESSOR_3
-#define XBOX_CORE_2_HWTHREAD_0 XBOX_PROCESSOR_4
-#define XBOX_CORE_2_HWTHREAD_1 XBOX_PROCESSOR_5
-
-//-----------------------------------------------------------------------------
-// Include additional dependant header components.
-//-----------------------------------------------------------------------------
-#include "tier0/fasttimer.h"
-
-#if defined( _X360 )
-#include "xbox/xbox_core.h"
-#endif
-
-//-----------------------------------------------------------------------------
-// Methods to invoke the constructor, copy constructor, and destructor
-//-----------------------------------------------------------------------------
-
-template <class T>
-inline T* Construct( T* pMemory )
-{
- return ::new( pMemory ) T;
-}
-
-template <class T, typename ARG1>
-inline T* Construct( T* pMemory, ARG1 a1 )
-{
- return ::new( pMemory ) T( a1 );
-}
-
-template <class T, typename ARG1, typename ARG2>
-inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2 )
-{
- return ::new( pMemory ) T( a1, a2 );
-}
-
-template <class T, typename ARG1, typename ARG2, typename ARG3>
-inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3 )
-{
- return ::new( pMemory ) T( a1, a2, a3 );
-}
-
-template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4>
-inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4 )
-{
- return ::new( pMemory ) T( a1, a2, a3, a4 );
-}
-
-template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4, typename ARG5>
-inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5 )
-{
- return ::new( pMemory ) T( a1, a2, a3, a4, a5 );
-}
-
-template <class T, class P>
-inline void ConstructOneArg( T* pMemory, P const& arg)
-{
- ::new( pMemory ) T(arg);
-}
-
-template <class T, class P1, class P2 >
-inline void ConstructTwoArg( T* pMemory, P1 const& arg1, P2 const& arg2)
-{
- ::new( pMemory ) T(arg1, arg2);
-}
-
-template <class T, class P1, class P2, class P3 >
-inline void ConstructThreeArg( T* pMemory, P1 const& arg1, P2 const& arg2, P3 const& arg3)
-{
- ::new( pMemory ) T(arg1, arg2, arg3);
-}
-
-template <class T>
-inline T* CopyConstruct( T* pMemory, T const& src )
-{
- return ::new( pMemory ) T(src);
-}
-
-template <class T>
-inline void Destruct( T* pMemory )
-{
- pMemory->~T();
-
-#ifdef _DEBUG
- memset( reinterpret_cast<void*>( pMemory ), 0xDD, sizeof(T) );
-#endif
-}
-
-
-//
-// GET_OUTER()
-//
-// A platform-independent way for a contained class to get a pointer to its
-// owner. If you know a class is exclusively used in the context of some
-// "outer" class, this is a much more space efficient way to get at the outer
-// class than having the inner class store a pointer to it.
-//
-// class COuter
-// {
-// class CInner // Note: this does not need to be a nested class to work
-// {
-// void PrintAddressOfOuter()
-// {
-// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) );
-// }
-// };
-//
-// CInner m_Inner;
-// friend class CInner;
-// };
-
-#define GET_OUTER( OuterType, OuterMember ) \
- ( ( OuterType * ) ( (uint8 *)this - offsetof( OuterType, OuterMember ) ) )
-
-
-/* TEMPLATE_FUNCTION_TABLE()
-
- (Note added to platform.h so platforms that correctly support templated
- functions can handle portions as templated functions rather than wrapped
- functions)
-
- Helps automate the process of creating an array of function
- templates that are all specialized by a single integer.
- This sort of thing is often useful in optimization work.
-
- For example, using TEMPLATE_FUNCTION_TABLE, this:
-
- TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10)
- {
- return argument * argument;
- }
-
- is equivilent to the following:
-
- (NOTE: the function has to be wrapped in a class due to code
- generation bugs involved with directly specializing a function
- based on a constant.)
-
- template<int argument>
- class FunctionWrapper
- {
- public:
- int Function( int blah, int blah )
- {
- return argument*argument;
- }
- }
-
- typedef int (*FunctionType)( int blah, int blah );
-
- class FunctionName
- {
- public:
- enum { count = 10 };
- FunctionType functions[10];
- };
-
- FunctionType FunctionName::functions[] =
- {
- FunctionWrapper<0>::Function,
- FunctionWrapper<1>::Function,
- FunctionWrapper<2>::Function,
- FunctionWrapper<3>::Function,
- FunctionWrapper<4>::Function,
- FunctionWrapper<5>::Function,
- FunctionWrapper<6>::Function,
- FunctionWrapper<7>::Function,
- FunctionWrapper<8>::Function,
- FunctionWrapper<9>::Function
- };
-*/
-
-PLATFORM_INTERFACE bool vtune( bool resume );
-
-
-#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \
- \
-typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \
- \
-template<const int nArgument> \
-struct __Function_##NAME \
-{ \
- static RETURN_TYPE FASTCALL Run ARGS; \
-}; \
- \
-template <const int i> \
-struct __MetaLooper_##NAME : __MetaLooper_##NAME<i-1> \
-{ \
- __Type_##NAME func; \
- inline __MetaLooper_##NAME() { func = __Function_##NAME<i>::Run; } \
-}; \
- \
-template<> \
-struct __MetaLooper_##NAME<0> \
-{ \
- __Type_##NAME func; \
- inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \
-}; \
- \
-class NAME \
-{ \
-private: \
- static const __MetaLooper_##NAME<COUNT> m; \
-public: \
- enum { count = COUNT }; \
- static const __Type_##NAME* functions; \
-}; \
-const __MetaLooper_##NAME<COUNT> NAME::m; \
-const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \
-template<const int nArgument> \
-RETURN_TYPE FASTCALL __Function_##NAME<nArgument>::Run ARGS
-
-
-#define LOOP_INTERCHANGE(BOOLEAN, CODE)\
- if( (BOOLEAN) )\
- {\
- CODE;\
- } else\
- {\
- CODE;\
- }
-
-//-----------------------------------------------------------------------------
-// Dynamic libs support
-//-----------------------------------------------------------------------------
-#if 0 // defined( PLATFORM_WINDOWS_PC )
-
-PLATFORM_INTERFACE void *Plat_GetProcAddress( const char *pszModule, const char *pszName );
-
-template <typename FUNCPTR_TYPE>
-class CDynamicFunction
-{
-public:
- CDynamicFunction( const char *pszModule, const char *pszName, FUNCPTR_TYPE pfnFallback = NULL )
- {
- m_pfn = pfnFallback;
- void *pAddr = Plat_GetProcAddress( pszModule, pszName );
- if ( pAddr )
- {
- m_pfn = (FUNCPTR_TYPE)pAddr;
- }
- }
-
- operator bool() { return m_pfn != NULL; }
- bool operator !() { return !m_pfn; }
- operator FUNCPTR_TYPE() { return m_pfn; }
-
-private:
- FUNCPTR_TYPE m_pfn;
-};
-#endif
-
-
-//-----------------------------------------------------------------------------
-
-#include "tier0/valve_on.h"
-
-#if defined(TIER0_DLL_EXPORT)
-extern "C" int V_tier0_stricmp(const char *s1, const char *s2 );
-#undef stricmp
-#undef strcmpi
-#define stricmp(s1,s2) V_tier0_stricmp( s1, s2 )
-#define strcmpi(s1,s2) V_tier0_stricmp( s1, s2 )
-#endif
-
-
-#endif /* PLATFORM_H */
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//===========================================================================//
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#if defined( _X360 )
+ #define NO_STEAM
+ #define NO_VOICE
+ // for the 360, the ppc platform and the rtos are tightly coupled
+ // setup the 360 environment here !once! for much less leaf module include wackiness
+ // these are critical order and purposely appear *before* anything else
+ #define _XBOX
+#include <xtl.h>
+ #include <xaudio2.h>
+ #include <xbdm.h>
+#include <Xgraphics.h>
+ #include <xui.h>
+ #include <pmcpbsetup.h>
+#include <XMAHardwareAbstraction.h>
+ #undef _XBOX
+#endif
+
+#include "wchartypes.h"
+#include "basetypes.h"
+#include "tier0/valve_off.h"
+
+#ifdef _DEBUG
+#if !defined( PLAT_COMPILE_TIME_ASSERT )
+#define PLAT_COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
+#endif
+#else
+#if !defined( PLAT_COMPILE_TIME_ASSERT )
+#define PLAT_COMPILE_TIME_ASSERT( pred )
+#endif
+#endif
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+// feature enables
+#define NEW_SOFTWARE_LIGHTING
+
+#ifdef POSIX
+// need this for _alloca
+#include <alloca.h>
+#include <unistd.h>
+ #include <signal.h>
+#include <time.h>
+#endif
+
+#include <malloc.h>
+#include <new>
+
+
+// need this for memset
+#include <string.h>
+
+#include "tier0/valve_minmax_on.h" // GCC 4.2.2 headers screw up our min/max defs.
+
+#ifdef _RETAIL
+#define IsRetail() true
+#else
+#define IsRetail() false
+#endif
+
+#ifdef _DEBUG
+#define IsRelease() false
+#define IsDebug() true
+#else
+#define IsRelease() true
+#define IsDebug() false
+#endif
+
+// Deprecating, infavor of IsX360() which will revert to IsXbox()
+// after confidence of xbox 1 code flush
+#define IsXbox() false
+
+#ifdef _WIN32
+ #define IsLinux() false
+ #define IsOSX() false
+ #define IsPosix() false
+ #define PLATFORM_WINDOWS 1 // Windows PC or Xbox 360
+ #ifndef _X360
+ #define IsWindows() true
+ #define IsPC() true
+ #define IsConsole() false
+ #define IsX360() false
+ #define IsPS3() false
+ #define IS_WINDOWS_PC
+ #define PLATFORM_WINDOWS_PC 1 // Windows PC
+ #ifdef _WIN64
+ #define IsPlatformWindowsPC64() true
+ #define IsPlatformWindowsPC32() false
+ #define PLATFORM_WINDOWS_PC64 1
+ #else
+ #define IsPlatformWindowsPC64() false
+ #define IsPlatformWindowsPC32() true
+ #define PLATFORM_WINDOWS_PC32 1
+ #endif
+ #else
+ #define PLATFORM_X360 1
+ #ifndef _CONSOLE
+ #define _CONSOLE
+ #endif
+ #define IsWindows() false
+ #define IsPC() false
+ #define IsConsole() true
+ #define IsX360() true
+ #define IsPS3() false
+ #endif
+ // Adding IsPlatformOpenGL() to help fix a bunch of code that was using IsPosix() to infer if the DX->GL translation layer was being used.
+ #if defined( DX_TO_GL_ABSTRACTION )
+ #define IsPlatformOpenGL() true
+ #else
+ #define IsPlatformOpenGL() false
+ #endif
+#elif defined(POSIX)
+ #define IsPC() true
+ #define IsWindows() false
+ #define IsConsole() false
+ #define IsX360() false
+ #define IsPS3() false
+ #if defined( LINUX )
+ #define IsLinux() true
+ #else
+ #define IsLinux() false
+ #endif
+
+ #if defined( OSX )
+ #define IsOSX() true
+ #else
+ #define IsOSX() false
+ #endif
+
+ #define IsPosix() true
+ #define IsPlatformOpenGL() true
+#else
+ #error
+#endif
+
+typedef unsigned char uint8;
+typedef signed char int8;
+
+#if defined(__x86_64__) || defined(_WIN64)
+ #define X64BITS
+#endif // __x86_64__
+
+#if defined( _WIN32 )
+
+ typedef __int16 int16;
+ typedef unsigned __int16 uint16;
+ typedef __int32 int32;
+ typedef unsigned __int32 uint32;
+ typedef __int64 int64;
+ typedef unsigned __int64 uint64;
+
+ #ifdef PLATFORM_64BITS
+ typedef __int64 intp; // intp is an integer that can accomodate a pointer
+ typedef unsigned __int64 uintp; // (ie, sizeof(intp) >= sizeof(int) && sizeof(intp) >= sizeof(void *)
+ #else
+ typedef __int32 intp;
+ typedef unsigned __int32 uintp;
+ #endif
+
+ #if defined( _X360 )
+ #ifdef __m128
+ #undef __m128
+ #endif
+ #define __m128 __vector4
+ #endif
+
+ // Use this to specify that a function is an override of a virtual function.
+ // This lets the compiler catch cases where you meant to override a virtual
+ // function but you accidentally changed the function signature and created
+ // an overloaded function. Usage in function declarations is like this:
+ // int GetData() const OVERRIDE;
+ #define OVERRIDE override
+
+#else // _WIN32
+
+ typedef short int16;
+ typedef unsigned short uint16;
+ typedef int int32;
+ typedef unsigned int uint32;
+ typedef long long int64;
+ typedef unsigned long long uint64;
+ #ifdef X64BITS
+ typedef long long intp;
+ typedef unsigned long long uintp;
+ #else
+ typedef int intp;
+ typedef unsigned int uintp;
+ #endif
+ typedef void *HWND;
+
+ // Avoid redefinition warnings if a previous header defines this.
+ #undef OVERRIDE
+ #if defined(__clang__)
+ #define OVERRIDE override
+ // warning: 'override' keyword is a C++11 extension [-Wc++11-extensions]
+ // Disabling this warning is less intrusive than enabling C++11 extensions
+ #pragma GCC diagnostic ignored "-Wc++11-extensions"
+ #else
+ #define OVERRIDE
+ #endif
+
+#endif // else _WIN32
+
+// From steam/steamtypes.h
+// RTime32
+// We use this 32 bit time representing real world time.
+// It offers 1 second resolution beginning on January 1, 1970 (Unix time)
+typedef uint32 RTime32;
+
+typedef float float32;
+typedef double float64;
+
+// for when we don't care about how many bits we use
+typedef unsigned int uint;
+
+#ifdef _MSC_VER
+#pragma once
+// Ensure that everybody has the right compiler version installed. The version
+// number can be obtained by looking at the compiler output when you type 'cl'
+// and removing the last two digits and the periods: 16.00.40219.01 becomes 160040219
+#if _MSC_FULL_VER > 160000000
+ #if _MSC_FULL_VER < 160040219
+ #error You must install VS 2010 SP1
+ #endif
+#else
+ #if _MSC_FULL_VER < 140050727
+ #error You must install VS 2005 SP1
+ #endif
+#endif
+#endif
+
+// This can be used to ensure the size of pointers to members when declaring
+// a pointer type for a class that has only been forward declared
+#ifdef _MSC_VER
+#define SINGLE_INHERITANCE __single_inheritance
+#define MULTIPLE_INHERITANCE __multiple_inheritance
+#else
+#define SINGLE_INHERITANCE
+#define MULTIPLE_INHERITANCE
+#endif
+
+#ifdef _MSC_VER
+#define NO_VTABLE __declspec( novtable )
+#else
+#define NO_VTABLE
+#endif
+
+#ifdef _MSC_VER
+ // This indicates that a function never returns, which helps with
+ // generating accurate compiler warnings
+ #define NORETURN __declspec( noreturn )
+#else
+ #define NORETURN
+#endif
+
+// This can be used to declare an abstract (interface only) class.
+// Classes marked abstract should not be instantiated. If they are, and access violation will occur.
+//
+// Example of use:
+//
+// abstract_class CFoo
+// {
+// ...
+// }
+//
+// MSDN __declspec(novtable) documentation: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_langref_novtable.asp
+//
+// Note: NJS: This is not enabled for regular PC, due to not knowing the implications of exporting a class with no no vtable.
+// It's probable that this shouldn't be an issue, but an experiment should be done to verify this.
+//
+#ifndef _X360
+#define abstract_class class
+#else
+#define abstract_class class NO_VTABLE
+#endif
+
+
+// MSVC CRT uses 0x7fff while gcc uses MAX_INT, leading to mismatches between platforms
+// As a result, we pick the least common denominator here. This should be used anywhere
+// you might typically want to use RAND_MAX
+#define VALVE_RAND_MAX 0x7fff
+
+
+
+/*
+FIXME: Enable this when we no longer fear change =)
+
+// need these for the limits
+#include <limits.h>
+#include <float.h>
+
+// Maximum and minimum representable values
+#define INT8_MAX SCHAR_MAX
+#define INT16_MAX SHRT_MAX
+#define INT32_MAX LONG_MAX
+#define INT64_MAX (((int64)~0) >> 1)
+
+#define INT8_MIN SCHAR_MIN
+#define INT16_MIN SHRT_MIN
+#define INT32_MIN LONG_MIN
+#define INT64_MIN (((int64)1) << 63)
+
+#define UINT8_MAX ((uint8)~0)
+#define UINT16_MAX ((uint16)~0)
+#define UINT32_MAX ((uint32)~0)
+#define UINT64_MAX ((uint64)~0)
+
+#define UINT8_MIN 0
+#define UINT16_MIN 0
+#define UINT32_MIN 0
+#define UINT64_MIN 0
+
+#ifndef UINT_MIN
+#define UINT_MIN UINT32_MIN
+#endif
+
+#define FLOAT32_MAX FLT_MAX
+#define FLOAT64_MAX DBL_MAX
+
+#define FLOAT32_MIN FLT_MIN
+#define FLOAT64_MIN DBL_MIN
+*/
+
+// portability / compiler settings
+#if defined(_WIN32) && !defined(WINDED)
+
+#if defined(_M_IX86)
+#define __i386__ 1
+#endif
+
+#elif POSIX
+#if defined( OSX ) && defined( CARBON_WORKAROUND )
+#define DWORD unsigned int
+#else
+typedef unsigned int DWORD;
+#endif
+typedef unsigned short WORD;
+typedef void * HINSTANCE;
+#define _MAX_PATH PATH_MAX
+#define __cdecl
+#define __stdcall
+#define __declspec
+
+#endif // defined(_WIN32) && !defined(WINDED)
+
+
+// Defines MAX_PATH
+#ifndef MAX_PATH
+#define MAX_PATH 260
+#endif
+
+#ifdef _WIN32
+#define MAX_UNICODE_PATH 32767
+#else
+#define MAX_UNICODE_PATH MAX_PATH
+#endif
+
+#define MAX_UNICODE_PATH_IN_UTF8 MAX_UNICODE_PATH*4
+
+#ifdef GNUC
+#undef offsetof
+//#define offsetof( type, var ) __builtin_offsetof( type, var )
+#define offsetof(s,m) (size_t)&(((s *)0)->m)
+#else
+#undef offsetof
+#define offsetof(s,m) (size_t)&(((s *)0)->m)
+#endif
+
+
+#define ALIGN_VALUE( val, alignment ) ( ( val + alignment - 1 ) & ~( alignment - 1 ) ) // need macro for constant expression
+
+// Used to step into the debugger
+#if defined( _WIN32 ) && !defined( _X360 )
+#define DebuggerBreak() __debugbreak()
+#elif defined( _X360 )
+#define DebuggerBreak() DebugBreak()
+#else
+ // On OSX, SIGTRAP doesn't really stop the thread cold when debugging.
+ // So if being debugged, use INT3 which is precise.
+#ifdef OSX
+#define DebuggerBreak() if ( Plat_IsInDebugSession() ) { __asm ( "int $3" ); } else { raise(SIGTRAP); }
+#else
+#define DebuggerBreak() raise(SIGTRAP)
+#endif
+#endif
+#define DebuggerBreakIfDebugging() if ( !Plat_IsInDebugSession() ) ; else DebuggerBreak()
+
+// C functions for external declarations that call the appropriate C++ methods
+#ifndef EXPORT
+ #ifdef _WIN32
+ #define EXPORT _declspec( dllexport )
+ #else
+ #define EXPORT /* */
+ #endif
+#endif
+
+#if defined __i386__ && !defined __linux__
+ #define id386 1
+#else
+ #define id386 0
+#endif // __i386__
+
+// decls for aligning data
+#ifdef _WIN32
+ #define DECL_ALIGN(x) __declspec(align(x))
+
+#elif GNUC
+ #define DECL_ALIGN(x) __attribute__((aligned(x)))
+#else
+ #define DECL_ALIGN(x) /* */
+#endif
+
+#ifdef _MSC_VER
+// MSVC has the align at the start of the struct
+#define ALIGN4 DECL_ALIGN(4)
+#define ALIGN8 DECL_ALIGN(8)
+#define ALIGN16 DECL_ALIGN(16)
+#define ALIGN32 DECL_ALIGN(32)
+#define ALIGN128 DECL_ALIGN(128)
+
+#define ALIGN4_POST
+#define ALIGN8_POST
+#define ALIGN16_POST
+#define ALIGN32_POST
+#define ALIGN128_POST
+#elif defined( GNUC )
+// gnuc has the align decoration at the end
+#define ALIGN4
+#define ALIGN8
+#define ALIGN16
+#define ALIGN32
+#define ALIGN128
+
+#define ALIGN4_POST DECL_ALIGN(4)
+#define ALIGN8_POST DECL_ALIGN(8)
+#define ALIGN16_POST DECL_ALIGN(16)
+#define ALIGN32_POST DECL_ALIGN(32)
+#define ALIGN128_POST DECL_ALIGN(128)
+#else
+#error
+#endif
+
+// Pull in the /analyze code annotations.
+#include "annotations.h"
+
+//-----------------------------------------------------------------------------
+// Convert int<-->pointer, avoiding 32/64-bit compiler warnings:
+//-----------------------------------------------------------------------------
+#define INT_TO_POINTER( i ) (void *)( ( i ) + (char *)NULL )
+#define POINTER_TO_INT( p ) ( (int)(uintp)( p ) )
+
+
+//-----------------------------------------------------------------------------
+// Stack-based allocation related helpers
+//-----------------------------------------------------------------------------
+#if defined( GNUC )
+ #define stackalloc( _size ) alloca( ALIGN_VALUE( _size, 16 ) )
+#ifdef _LINUX
+ #define mallocsize( _p ) ( malloc_usable_size( _p ) )
+#elif defined(OSX)
+ #define mallocsize( _p ) ( malloc_size( _p ) )
+#else
+#error
+#endif
+#elif defined ( _WIN32 )
+ #define stackalloc( _size ) _alloca( ALIGN_VALUE( _size, 16 ) )
+ #define mallocsize( _p ) ( _msize( _p ) )
+#endif
+
+#define stackfree( _p ) 0
+
+// Linux had a few areas where it didn't construct objects in the same order that Windows does.
+// So when CVProfile::CVProfile() would access g_pMemAlloc, it would crash because the allocator wasn't initalized yet.
+#ifdef POSIX
+ #define CONSTRUCT_EARLY __attribute__((init_priority(101)))
+#else
+ #define CONSTRUCT_EARLY
+ #endif
+
+#if defined(_MSC_VER)
+ #define SELECTANY __declspec(selectany)
+ #define RESTRICT __restrict
+ #define RESTRICT_FUNC __declspec(restrict)
+ #define FMTFUNCTION( a, b )
+#elif defined(GNUC)
+ #define SELECTANY __attribute__((weak))
+ #if defined(LINUX) && !defined(DEDICATED)
+ #define RESTRICT
+ #else
+ #define RESTRICT __restrict
+ #endif
+ #define RESTRICT_FUNC
+ // squirrel.h does a #define printf DevMsg which leads to warnings when we try
+ // to use printf as the prototype format function. Using __printf__ instead.
+ #define FMTFUNCTION( fmtargnumber, firstvarargnumber ) __attribute__ (( format( __printf__, fmtargnumber, firstvarargnumber )))
+#else
+ #define SELECTANY static
+ #define RESTRICT
+ #define RESTRICT_FUNC
+ #define FMTFUNCTION( a, b )
+#endif
+
+#if defined( _WIN32 )
+
+ // Used for dll exporting and importing
+ #define DLL_EXPORT extern "C" __declspec( dllexport )
+ #define DLL_IMPORT extern "C" __declspec( dllimport )
+
+ // Can't use extern "C" when DLL exporting a class
+ #define DLL_CLASS_EXPORT __declspec( dllexport )
+ #define DLL_CLASS_IMPORT __declspec( dllimport )
+
+ // Can't use extern "C" when DLL exporting a global
+ #define DLL_GLOBAL_EXPORT extern __declspec( dllexport )
+ #define DLL_GLOBAL_IMPORT extern __declspec( dllimport )
+
+ #define DLL_LOCAL
+
+#elif defined GNUC
+// Used for dll exporting and importing
+#define DLL_EXPORT extern "C" __attribute__ ((visibility("default")))
+#define DLL_IMPORT extern "C"
+
+// Can't use extern "C" when DLL exporting a class
+#define DLL_CLASS_EXPORT __attribute__ ((visibility("default")))
+#define DLL_CLASS_IMPORT
+
+// Can't use extern "C" when DLL exporting a global
+#define DLL_GLOBAL_EXPORT extern __attribute ((visibility("default")))
+#define DLL_GLOBAL_IMPORT extern
+
+#define DLL_LOCAL __attribute__ ((visibility("hidden")))
+
+#else
+#error "Unsupported Platform."
+#endif
+
+// Used for standard calling conventions
+#if defined( _WIN32 ) && !defined( _X360 )
+ #define STDCALL __stdcall
+ #define FASTCALL __fastcall
+ #define FORCEINLINE __forceinline
+ // GCC 3.4.1 has a bug in supporting forced inline of templated functions
+ // this macro lets us not force inlining in that case
+ #define FORCEINLINE_TEMPLATE __forceinline
+#elif defined( _X360 )
+ #define STDCALL __stdcall
+ #ifdef FORCEINLINE
+ #undef FORCEINLINE
+#endif
+ #define FORCEINLINE __forceinline
+ #define FORCEINLINE_TEMPLATE __forceinline
+ #else
+ #define STDCALL
+ #define FASTCALL
+ #ifdef _LINUX_DEBUGGABLE
+ #define FORCEINLINE
+ #else
+ #define FORCEINLINE inline __attribute__ ((always_inline))
+ #endif
+ // GCC 3.4.1 has a bug in supporting forced inline of templated functions
+ // this macro lets us not force inlining in that case
+ #define FORCEINLINE_TEMPLATE inline
+// #define __stdcall __attribute__ ((__stdcall__))
+#endif
+
+// Force a function call site -not- to inlined. (useful for profiling)
+#define DONT_INLINE(a) (((int)(a)+1)?(a):(a))
+
+// Pass hints to the compiler to prevent it from generating unnessecary / stupid code
+// in certain situations. Several compilers other than MSVC also have an equivilent
+// construct.
+//
+// Essentially the 'Hint' is that the condition specified is assumed to be true at
+// that point in the compilation. If '0' is passed, then the compiler assumes that
+// any subsequent code in the same 'basic block' is unreachable, and thus usually
+// removed.
+#ifdef _MSC_VER
+ #define HINT(THE_HINT) __assume((THE_HINT))
+#else
+ #define HINT(THE_HINT) 0
+#endif
+
+// Marks the codepath from here until the next branch entry point as unreachable,
+// and asserts if any attempt is made to execute it.
+#define UNREACHABLE() { Assert(0); HINT(0); }
+
+// In cases where no default is present or appropriate, this causes MSVC to generate
+// as little code as possible, and throw an assertion in debug.
+#define NO_DEFAULT default: UNREACHABLE();
+
+
+#ifdef _WIN32
+
+// Remove warnings from warning level 4.
+#pragma warning(disable : 4514) // warning C4514: 'acosl' : unreferenced inline function has been removed
+#pragma warning(disable : 4100) // warning C4100: 'hwnd' : unreferenced formal parameter
+#pragma warning(disable : 4127) // warning C4127: conditional expression is constant
+#pragma warning(disable : 4512) // warning C4512: 'InFileRIFF' : assignment operator could not be generated
+#pragma warning(disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
+#pragma warning(disable : 4710) // warning C4710: function 'x' not inlined
+#pragma warning(disable : 4702) // warning C4702: unreachable code
+#pragma warning(disable : 4505) // unreferenced local function has been removed
+#pragma warning(disable : 4239) // nonstandard extension used : 'argument' ( conversion from class Vector to class Vector& )
+#pragma warning(disable : 4097) // typedef-name 'BaseClass' used as synonym for class-name 'CFlexCycler::CBaseFlex'
+#pragma warning(disable : 4324) // Padding was added at the end of a structure
+#pragma warning(disable : 4244) // type conversion warning.
+#pragma warning(disable : 4305) // truncation from 'const double ' to 'float '
+#pragma warning(disable : 4786) // Disable warnings about long symbol names
+#pragma warning(disable : 4250) // 'X' : inherits 'Y::Z' via dominance
+#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
+#pragma warning(disable : 4481) // warning C4481: nonstandard extension used: override specifier 'override'
+#pragma warning(disable : 4748) // warning C4748: /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function
+
+#if _MSC_VER >= 1300
+#pragma warning(disable : 4511) // Disable warnings about private copy constructors
+#pragma warning(disable : 4121) // warning C4121: 'symbol' : alignment of a member was sensitive to packing
+#pragma warning(disable : 4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc (disabled due to std headers having exception syntax)
+#endif
+
+#if _MSC_VER >= 1400
+#pragma warning(disable : 4996) // functions declared deprecated
+#endif
+
+
+#endif // _WIN32
+
+#if defined( LINUX ) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
+ // based on some Jonathan Wakely macros on the net...
+ #define GCC_DIAG_STR(s) #s
+ #define GCC_DIAG_JOINSTR(x,y) GCC_DIAG_STR(x ## y)
+ #define GCC_DIAG_DO_PRAGMA(x) _Pragma (#x)
+ #define GCC_DIAG_PRAGMA(x) GCC_DIAG_DO_PRAGMA(GCC diagnostic x)
+
+ #define GCC_DIAG_PUSH_OFF(x) GCC_DIAG_PRAGMA(push) GCC_DIAG_PRAGMA(ignored GCC_DIAG_JOINSTR(-W,x))
+ #define GCC_DIAG_POP() GCC_DIAG_PRAGMA(pop)
+#else
+ #define GCC_DIAG_PUSH_OFF(x)
+ #define GCC_DIAG_POP()
+#endif
+
+#ifdef LINUX
+#pragma GCC diagnostic ignored "-Wconversion-null" // passing NULL to non-pointer argument 1
+#pragma GCC diagnostic ignored "-Wpointer-arith" // NULL used in arithmetic. Ie, vpanel == NULL where VPANEL is uint.
+#pragma GCC diagnostic ignored "-Wswitch" // enumeration values not handled in switch
+#endif
+
+#ifdef OSX
+#pragma GCC diagnostic ignored "-Wconversion-null" // passing NULL to non-pointer argument 1
+#pragma GCC diagnostic ignored "-Wnull-arithmetic" // NULL used in arithmetic. Ie, vpanel == NULL where VPANEL is uint.
+#pragma GCC diagnostic ignored "-Wswitch-enum" // enumeration values not handled in switch
+#pragma GCC diagnostic ignored "-Wswitch" // enumeration values not handled in switch
+#endif
+
+
+// When we port to 64 bit, we'll have to resolve the int, ptr vs size_t 32/64 bit problems...
+#if !defined( _WIN64 )
+#pragma warning( disable : 4267 ) // conversion from 'size_t' to 'int', possible loss of data
+#pragma warning( disable : 4311 ) // pointer truncation from 'char *' to 'int'
+#pragma warning( disable : 4312 ) // conversion from 'unsigned int' to 'memhandle_t' of greater size
+#endif
+
+
+#ifdef POSIX
+#define _stricmp stricmp
+#define strcmpi stricmp
+#define stricmp strcasecmp
+#define _vsnprintf vsnprintf
+#define _alloca alloca
+#ifdef _snprintf
+#undef _snprintf
+#endif
+#define _snprintf snprintf
+#define GetProcAddress dlsym
+#define _chdir chdir
+#define _strnicmp strnicmp
+#define strnicmp strncasecmp
+#define _getcwd getcwd
+#define _snwprintf swprintf
+#define swprintf_s swprintf
+#define wcsicmp _wcsicmp
+#define _wcsicmp wcscmp
+#define _finite finite
+#define _tempnam tempnam
+#define _unlink unlink
+#define _access access
+#define _mkdir(dir) mkdir( dir, S_IRWXU | S_IRWXG | S_IRWXO )
+#define _wtoi(arg) wcstol(arg, NULL, 10)
+#define _wtoi64(arg) wcstoll(arg, NULL, 10)
+
+typedef uint32 HMODULE;
+typedef void *HANDLE;
+#endif
+
+//-----------------------------------------------------------------------------
+// fsel
+//-----------------------------------------------------------------------------
+#ifndef _X360
+
+static FORCEINLINE float fsel(float fComparand, float fValGE, float fLT)
+{
+ return fComparand >= 0 ? fValGE : fLT;
+}
+static FORCEINLINE double fsel(double fComparand, double fValGE, double fLT)
+{
+ return fComparand >= 0 ? fValGE : fLT;
+}
+
+#else
+
+// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT
+// this is much faster than if ( aFloat > 0 ) { x = .. }
+#define fsel __fsel
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+// FP exception handling
+//-----------------------------------------------------------------------------
+//#define CHECK_FLOAT_EXCEPTIONS 1
+
+#if !defined( _X360 )
+#if defined( _MSC_VER )
+
+ #if defined( PLATFORM_WINDOWS_PC64 )
+ inline void SetupFPUControlWord()
+ {
+ }
+ #else
+ inline void SetupFPUControlWordForceExceptions()
+ {
+ // use local to get and store control word
+ uint16 tmpCtrlW;
+ __asm
+ {
+ fnclex /* clear all current exceptions */
+ fnstcw word ptr [tmpCtrlW] /* get current control word */
+ and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
+ or [tmpCtrlW], 0230h /* set to 53-bit, mask only inexact, underflow */
+ fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
+ }
+ }
+
+ #ifdef CHECK_FLOAT_EXCEPTIONS
+
+ inline void SetupFPUControlWord()
+ {
+ SetupFPUControlWordForceExceptions();
+ }
+
+ #else
+
+ inline void SetupFPUControlWord()
+ {
+ // use local to get and store control word
+ uint16 tmpCtrlW;
+ __asm
+ {
+ fnstcw word ptr [tmpCtrlW] /* get current control word */
+ and [tmpCtrlW], 0FCC0h /* Keep infinity control + rounding control */
+ or [tmpCtrlW], 023Fh /* set to 53-bit, mask only inexact, underflow */
+ fldcw word ptr [tmpCtrlW] /* put new control word in FPU */
+ }
+ }
+
+ #endif
+ #endif
+
+#else
+
+ inline void SetupFPUControlWord()
+ {
+ __volatile unsigned short int __cw;
+ __asm __volatile ("fnstcw %0" : "=m" (__cw));
+ __cw = __cw & 0x0FCC0; // keep infinity control, keep rounding mode
+ __cw = __cw | 0x023F; // set 53-bit, no exceptions
+ __asm __volatile ("fldcw %0" : : "m" (__cw));
+ }
+
+#endif // _MSC_VER
+
+#else
+
+ #ifdef _DEBUG
+ FORCEINLINE bool IsFPUControlWordSet()
+ {
+ float f = 0.996f;
+ union
+ {
+ double flResult;
+ int pResult[2];
+ };
+ flResult = __fctiw( f );
+ return ( pResult[1] == 1 );
+ }
+ #endif
+
+ inline void SetupFPUControlWord()
+ {
+ // Set round-to-nearest in FPSCR
+ // (cannot assemble, must use op-code form)
+ __emit( 0xFF80010C ); // mtfsfi 7,0
+
+ // Favour compatibility over speed (make sure the VPU set to Java-compliant mode)
+ // NOTE: the VPU *always* uses round-to-nearest
+ __vector4 a = { 0.0f, 0.0f, 0.0f, 0.0f };
+ a; // Avoid compiler warning
+ __asm
+ {
+ mtvscr a; // Clear the Vector Status & Control Register to zero
+ }
+ }
+
+#endif // _X360
+
+//-----------------------------------------------------------------------------
+// Purpose: Standard functions for handling endian-ness
+//-----------------------------------------------------------------------------
+
+//-------------------------------------
+// Basic swaps
+//-------------------------------------
+
+template <typename T>
+inline T WordSwapC( T w )
+{
+ uint16 temp;
+
+ temp = ((*((uint16 *)&w) & 0xff00) >> 8);
+ temp |= ((*((uint16 *)&w) & 0x00ff) << 8);
+
+ return *((T*)&temp);
+}
+
+template <typename T>
+inline T DWordSwapC( T dw )
+{
+ uint32 temp;
+
+ temp = *((uint32 *)&dw) >> 24;
+ temp |= ((*((uint32 *)&dw) & 0x00FF0000) >> 8);
+ temp |= ((*((uint32 *)&dw) & 0x0000FF00) << 8);
+ temp |= ((*((uint32 *)&dw) & 0x000000FF) << 24);
+
+ return *((T*)&temp);
+}
+
+template <typename T>
+inline T QWordSwapC( T dw )
+{
+ // Assert sizes passed to this are already correct, otherwise
+ // the cast to uint64 * below is unsafe and may have wrong results
+ // or even crash.
+ PLAT_COMPILE_TIME_ASSERT( sizeof( dw ) == sizeof(uint64) );
+
+ uint64 temp;
+
+ temp = *((uint64 *)&dw) >> 56;
+ temp |= ((*((uint64 *)&dw) & 0x00FF000000000000ull) >> 40);
+ temp |= ((*((uint64 *)&dw) & 0x0000FF0000000000ull) >> 24);
+ temp |= ((*((uint64 *)&dw) & 0x000000FF00000000ull) >> 8);
+ temp |= ((*((uint64 *)&dw) & 0x00000000FF000000ull) << 8);
+ temp |= ((*((uint64 *)&dw) & 0x0000000000FF0000ull) << 24);
+ temp |= ((*((uint64 *)&dw) & 0x000000000000FF00ull) << 40);
+ temp |= ((*((uint64 *)&dw) & 0x00000000000000FFull) << 56);
+
+ return *((T*)&temp);
+}
+
+//-------------------------------------
+// Fast swaps
+//-------------------------------------
+
+#if defined( _X360 )
+
+ #define WordSwap WordSwap360Intr
+ #define DWordSwap DWordSwap360Intr
+
+ template <typename T>
+ inline T WordSwap360Intr( T w )
+ {
+ T output;
+ __storeshortbytereverse( w, 0, &output );
+ return output;
+ }
+
+ template <typename T>
+ inline T DWordSwap360Intr( T dw )
+ {
+ T output;
+ __storewordbytereverse( dw, 0, &output );
+ return output;
+ }
+
+#elif defined( _MSC_VER ) && !defined( PLATFORM_WINDOWS_PC64 )
+
+ #define WordSwap WordSwapAsm
+ #define DWordSwap DWordSwapAsm
+
+ #pragma warning(push)
+ #pragma warning (disable:4035) // no return value
+
+ template <typename T>
+ inline T WordSwapAsm( T w )
+ {
+ __asm
+ {
+ mov ax, w
+ xchg al, ah
+ }
+ }
+
+ template <typename T>
+ inline T DWordSwapAsm( T dw )
+ {
+ __asm
+ {
+ mov eax, dw
+ bswap eax
+ }
+ }
+
+ #pragma warning(pop)
+
+#else
+
+ #define WordSwap WordSwapC
+ #define DWordSwap DWordSwapC
+
+#endif
+
+// No ASM implementation for this yet
+#define QWordSwap QWordSwapC
+
+//-------------------------------------
+// The typically used methods.
+//-------------------------------------
+
+#if defined(__i386__) && !defined(VALVE_LITTLE_ENDIAN)
+#define VALVE_LITTLE_ENDIAN 1
+#endif
+
+#if defined( _SGI_SOURCE ) || defined( _X360 )
+#define VALVE_BIG_ENDIAN 1
+#endif
+
+// If a swapped float passes through the fpu, the bytes may get changed.
+// Prevent this by swapping floats as DWORDs.
+#define SafeSwapFloat( pOut, pIn ) (*((uint*)pOut) = DWordSwap( *((uint*)pIn) ))
+
+#if defined(VALVE_LITTLE_ENDIAN)
+
+#define BigShort( val ) WordSwap( val )
+#define BigWord( val ) WordSwap( val )
+#define BigLong( val ) DWordSwap( val )
+#define BigDWord( val ) DWordSwap( val )
+#define LittleShort( val ) ( val )
+#define LittleWord( val ) ( val )
+#define LittleLong( val ) ( val )
+#define LittleDWord( val ) ( val )
+#define LittleQWord( val ) ( val )
+#define SwapShort( val ) BigShort( val )
+#define SwapWord( val ) BigWord( val )
+#define SwapLong( val ) BigLong( val )
+#define SwapDWord( val ) BigDWord( val )
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+#define BigFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
+#define LittleFloat( pOut, pIn ) ( *pOut = *pIn )
+#define SwapFloat( pOut, pIn ) BigFloat( pOut, pIn )
+
+#elif defined(VALVE_BIG_ENDIAN)
+
+#define BigShort( val ) ( val )
+#define BigWord( val ) ( val )
+#define BigLong( val ) ( val )
+#define BigDWord( val ) ( val )
+#define LittleShort( val ) WordSwap( val )
+#define LittleWord( val ) WordSwap( val )
+#define LittleLong( val ) DWordSwap( val )
+#define LittleDWord( val ) DWordSwap( val )
+#define LittleQWord( val ) QWordSwap( val )
+#define SwapShort( val ) LittleShort( val )
+#define SwapWord( val ) LittleWord( val )
+#define SwapLong( val ) LittleLong( val )
+#define SwapDWord( val ) LittleDWord( val )
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+#define BigFloat( pOut, pIn ) ( *pOut = *pIn )
+#define LittleFloat( pOut, pIn ) SafeSwapFloat( pOut, pIn )
+#define SwapFloat( pOut, pIn ) LittleFloat( pOut, pIn )
+
+#else
+
+// @Note (toml 05-02-02): this technique expects the compiler to
+// optimize the expression and eliminate the other path. On any new
+// platform/compiler this should be tested.
+inline short BigShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
+inline uint16 BigWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? WordSwap( val ) : val; }
+inline long BigLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
+inline uint32 BigDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? DWordSwap( val ) : val; }
+inline short LittleShort( short val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
+inline uint16 LittleWord( uint16 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : WordSwap( val ); }
+inline long LittleLong( long val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
+inline uint32 LittleDWord( uint32 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : DWordSwap( val ); }
+inline uint64 LittleQWord( uint64 val ) { int test = 1; return ( *(char *)&test == 1 ) ? val : QWordSwap( val ); }
+inline short SwapShort( short val ) { return WordSwap( val ); }
+inline uint16 SwapWord( uint16 val ) { return WordSwap( val ); }
+inline long SwapLong( long val ) { return DWordSwap( val ); }
+inline uint32 SwapDWord( uint32 val ) { return DWordSwap( val ); }
+
+// Pass floats by pointer for swapping to avoid truncation in the fpu
+inline void BigFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? SafeSwapFloat( pOut, pIn ) : ( *pOut = *pIn ); }
+inline void LittleFloat( float *pOut, const float *pIn ) { int test = 1; ( *(char *)&test == 1 ) ? ( *pOut = *pIn ) : SafeSwapFloat( pOut, pIn ); }
+inline void SwapFloat( float *pOut, const float *pIn ) { SafeSwapFloat( pOut, pIn ); }
+
+#endif
+
+#if _X360
+FORCEINLINE unsigned long LoadLittleDWord( const unsigned long *base, unsigned int dwordIndex )
+ {
+ return __loadwordbytereverse( dwordIndex<<2, base );
+ }
+
+FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword )
+ {
+ __storewordbytereverse( dword, dwordIndex<<2, base );
+ }
+#else
+FORCEINLINE unsigned long LoadLittleDWord( const unsigned long *base, unsigned int dwordIndex )
+ {
+ return LittleDWord( base[dwordIndex] );
+ }
+
+FORCEINLINE void StoreLittleDWord( unsigned long *base, unsigned int dwordIndex, unsigned long dword )
+ {
+ base[dwordIndex] = LittleDWord(dword);
+ }
+#endif
+
+
+//-----------------------------------------------------------------------------
+// DLL export for platform utilities
+//-----------------------------------------------------------------------------
+#ifndef STATIC_TIER0
+
+#ifdef TIER0_DLL_EXPORT
+#define PLATFORM_INTERFACE DLL_EXPORT
+#define PLATFORM_OVERLOAD DLL_GLOBAL_EXPORT
+#define PLATFORM_CLASS DLL_CLASS_EXPORT
+#else
+#define PLATFORM_INTERFACE DLL_IMPORT
+#define PLATFORM_OVERLOAD DLL_GLOBAL_IMPORT
+#define PLATFORM_CLASS DLL_CLASS_IMPORT
+#endif
+
+#else // BUILD_AS_DLL
+
+#define PLATFORM_INTERFACE extern
+#define PLATFORM_OVERLOAD
+#define PLATFORM_CLASS
+
+#endif // BUILD_AS_DLL
+
+
+// When in benchmark mode, the timer returns a simple incremented value each time you call it.
+//
+// It should not be changed after startup unless you really know what you're doing. The only place
+// that should do this is the benchmark code itself so it can output a legit duration.
+PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode );
+PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode();
+
+
+PLATFORM_INTERFACE double Plat_FloatTime(); // Returns time in seconds since the module was loaded.
+PLATFORM_INTERFACE unsigned int Plat_MSTime(); // Time in milliseconds.
+PLATFORM_INTERFACE char * Plat_asctime( const struct tm *tm, char *buf );
+PLATFORM_INTERFACE char * Plat_ctime( const time_t *timep, char *buf, size_t bufsize );
+PLATFORM_INTERFACE struct tm * Plat_gmtime( const time_t *timep, struct tm *result );
+PLATFORM_INTERFACE time_t Plat_timegm( struct tm *timeptr );
+PLATFORM_INTERFACE struct tm * Plat_localtime( const time_t *timep, struct tm *result );
+
+#if defined( _WIN32 ) && defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
+ extern "C" unsigned __int64 __rdtsc();
+ #pragma intrinsic(__rdtsc)
+#endif
+
+inline uint64 Plat_Rdtsc()
+{
+#if defined( _X360 )
+ return ( uint64 )__mftb32();
+#elif defined( _WIN64 )
+ return ( uint64 )__rdtsc();
+#elif defined( _WIN32 )
+ #if defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
+ return ( uint64 )__rdtsc();
+ #else
+ __asm rdtsc;
+ __asm ret;
+ #endif
+#elif defined( __i386__ )
+ uint64 val;
+ __asm__ __volatile__ ( "rdtsc" : "=A" (val) );
+ return val;
+#elif defined( __x86_64__ )
+ uint32 lo, hi;
+ __asm__ __volatile__ ( "rdtsc" : "=a" (lo), "=d" (hi));
+ return ( ( ( uint64 )hi ) << 32 ) | lo;
+#else
+ #error
+#endif
+}
+
+// b/w compatibility
+#define Sys_FloatTime Plat_FloatTime
+
+// Protect against bad auto operator=
+#define DISALLOW_OPERATOR_EQUAL( _classname ) \
+ private: \
+ _classname &operator=( const _classname & ); \
+ public:
+
+// Define a reasonable operator=
+#define IMPLEMENT_OPERATOR_EQUAL( _classname ) \
+ public: \
+ _classname &operator=( const _classname &src ) \
+ { \
+ memcpy( this, &src, sizeof(_classname) ); \
+ return *this; \
+ }
+
+// Processor Information:
+struct CPUInformation
+{
+ int m_Size; // Size of this structure, for forward compatability.
+
+ bool m_bRDTSC : 1, // Is RDTSC supported?
+ m_bCMOV : 1, // Is CMOV supported?
+ m_bFCMOV : 1, // Is FCMOV supported?
+ m_bSSE : 1, // Is SSE supported?
+ m_bSSE2 : 1, // Is SSE2 Supported?
+ m_b3DNow : 1, // Is 3DNow! Supported?
+ m_bMMX : 1, // Is MMX supported?
+ m_bHT : 1; // Is HyperThreading supported?
+
+ uint8 m_nLogicalProcessors; // Number op logical processors.
+ uint8 m_nPhysicalProcessors; // Number of physical processors
+
+ bool m_bSSE3 : 1,
+ m_bSSSE3 : 1,
+ m_bSSE4a : 1,
+ m_bSSE41 : 1,
+ m_bSSE42 : 1;
+
+ int64 m_Speed; // In cycles per second.
+
+ tchar* m_szProcessorID; // Processor vendor Identification.
+
+ CPUInformation(): m_Size(0){}
+};
+
+// Have to return a pointer, not a reference, because references are not compatible with the
+// extern "C" implied by PLATFORM_INTERFACE.
+PLATFORM_INTERFACE const CPUInformation* GetCPUInformation();
+
+PLATFORM_INTERFACE float GetCPUUsage();
+
+PLATFORM_INTERFACE void GetCurrentDate( int *pDay, int *pMonth, int *pYear );
+
+// ---------------------------------------------------------------------------------- //
+// Performance Monitoring Events - L2 stats etc...
+// ---------------------------------------------------------------------------------- //
+PLATFORM_INTERFACE void InitPME();
+PLATFORM_INTERFACE void ShutdownPME();
+
+//-----------------------------------------------------------------------------
+// Thread related functions
+//-----------------------------------------------------------------------------
+
+// Sets a hardware data breakpoint on the given address. Currently Win32-only.
+// Specify 1, 2, or 4 bytes for nWatchBytes; pass 0 to unregister the address.
+PLATFORM_INTERFACE void Plat_SetHardwareDataBreakpoint( const void *pAddress, int nWatchBytes, bool bBreakOnRead );
+
+// Apply current hardware data breakpoints to a newly created thread.
+PLATFORM_INTERFACE void Plat_ApplyHardwareDataBreakpointsToNewThread( unsigned long dwThreadID );
+
+//-----------------------------------------------------------------------------
+// Process related functions
+//-----------------------------------------------------------------------------
+PLATFORM_INTERFACE const tchar *Plat_GetCommandLine();
+#ifndef _WIN32
+// helper function for OS's that don't have a ::GetCommandLine() call
+PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine );
+#endif
+PLATFORM_INTERFACE const char *Plat_GetCommandLineA();
+
+//-----------------------------------------------------------------------------
+// Security related functions
+//-----------------------------------------------------------------------------
+// Ensure that the hardware key's drivers have been installed.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyDriver();
+
+// Ok, so this isn't a very secure way to verify the hardware key for now. It
+// is primarially depending on the fact that all the binaries have been wrapped
+// with the secure wrapper provided by the hardware keys vendor.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKey();
+
+// The same as above, but notifies user with a message box when the key isn't in
+// and gives him an opportunity to correct the situation.
+PLATFORM_INTERFACE bool Plat_VerifyHardwareKeyPrompt();
+
+// Can be called in real time, doesn't perform the verify every frame. Mainly just
+// here to allow the game to drop out quickly when the key is removed, rather than
+// allowing the wrapper to pop up it's own blocking dialog, which the engine doesn't
+// like much.
+PLATFORM_INTERFACE bool Plat_FastVerifyHardwareKey();
+
+//-----------------------------------------------------------------------------
+// Just logs file and line to simple.log
+//-----------------------------------------------------------------------------
+PLATFORM_INTERFACE void* Plat_SimpleLog( const tchar* file, int line );
+
+#if _X360
+#define Plat_FastMemset XMemSet
+#define Plat_FastMemcpy XMemCpy
+#else
+#define Plat_FastMemset memset
+#define Plat_FastMemcpy memcpy
+#endif
+
+//-----------------------------------------------------------------------------
+// Returns true if debugger attached, false otherwise
+//-----------------------------------------------------------------------------
+#if defined(_WIN32) || defined(LINUX) || defined(OSX)
+PLATFORM_INTERFACE bool Plat_IsInDebugSession( bool bForceRecheck = false );
+PLATFORM_INTERFACE void Plat_DebugString( const char * );
+#else
+inline bool Plat_IsInDebugSession( bool bForceRecheck = false ) { return false; }
+#define Plat_DebugString(s) ((void)0)
+#endif
+
+//-----------------------------------------------------------------------------
+// Returns true if running on a 64 bit (windows) OS
+//-----------------------------------------------------------------------------
+PLATFORM_INTERFACE bool Is64BitOS();
+
+
+//-----------------------------------------------------------------------------
+// XBOX Components valid in PC compilation space
+//-----------------------------------------------------------------------------
+
+#define XBOX_DVD_SECTORSIZE 2048
+#define XBOX_DVD_ECC_SIZE 32768 // driver reads in quantum ECC blocks
+#define XBOX_HDD_SECTORSIZE 512
+
+// Custom windows messages for Xbox input
+#define WM_XREMOTECOMMAND (WM_USER + 100)
+#define WM_XCONTROLLER_KEY (WM_USER + 101)
+#define WM_SYS_UI (WM_USER + 102)
+#define WM_SYS_SIGNINCHANGED (WM_USER + 103)
+#define WM_SYS_STORAGEDEVICESCHANGED (WM_USER + 104)
+#define WM_SYS_PROFILESETTINGCHANGED (WM_USER + 105)
+#define WM_SYS_MUTELISTCHANGED (WM_USER + 106)
+#define WM_SYS_INPUTDEVICESCHANGED (WM_USER + 107)
+#define WM_SYS_INPUTDEVICECONFIGCHANGED (WM_USER + 108)
+#define WM_LIVE_CONNECTIONCHANGED (WM_USER + 109)
+#define WM_LIVE_INVITE_ACCEPTED (WM_USER + 110)
+#define WM_LIVE_LINK_STATE_CHANGED (WM_USER + 111)
+#define WM_LIVE_CONTENT_INSTALLED (WM_USER + 112)
+#define WM_LIVE_MEMBERSHIP_PURCHASED (WM_USER + 113)
+#define WM_LIVE_VOICECHAT_AWAY (WM_USER + 114)
+#define WM_LIVE_PRESENCE_CHANGED (WM_USER + 115)
+#define WM_FRIENDS_PRESENCE_CHANGED (WM_USER + 116)
+#define WM_FRIENDS_FRIEND_ADDED (WM_USER + 117)
+#define WM_FRIENDS_FRIEND_REMOVED (WM_USER + 118)
+#define WM_CUSTOM_GAMEBANNERPRESSED (WM_USER + 119)
+#define WM_CUSTOM_ACTIONPRESSED (WM_USER + 120)
+#define WM_XMP_STATECHANGED (WM_USER + 121)
+#define WM_XMP_PLAYBACKBEHAVIORCHANGED (WM_USER + 122)
+#define WM_XMP_PLAYBACKCONTROLLERCHANGED (WM_USER + 123)
+
+inline const char *GetPlatformExt( void )
+{
+ return IsX360() ? ".360" : "";
+}
+
+// flat view, 6 hw threads
+#define XBOX_PROCESSOR_0 ( 1<<0 )
+#define XBOX_PROCESSOR_1 ( 1<<1 )
+#define XBOX_PROCESSOR_2 ( 1<<2 )
+#define XBOX_PROCESSOR_3 ( 1<<3 )
+#define XBOX_PROCESSOR_4 ( 1<<4 )
+#define XBOX_PROCESSOR_5 ( 1<<5 )
+
+// core view, 3 cores with 2 hw threads each
+#define XBOX_CORE_0_HWTHREAD_0 XBOX_PROCESSOR_0
+#define XBOX_CORE_0_HWTHREAD_1 XBOX_PROCESSOR_1
+#define XBOX_CORE_1_HWTHREAD_0 XBOX_PROCESSOR_2
+#define XBOX_CORE_1_HWTHREAD_1 XBOX_PROCESSOR_3
+#define XBOX_CORE_2_HWTHREAD_0 XBOX_PROCESSOR_4
+#define XBOX_CORE_2_HWTHREAD_1 XBOX_PROCESSOR_5
+
+//-----------------------------------------------------------------------------
+// Include additional dependant header components.
+//-----------------------------------------------------------------------------
+#include "tier0/fasttimer.h"
+
+#if defined( _X360 )
+#include "xbox/xbox_core.h"
+#endif
+
+//-----------------------------------------------------------------------------
+// Methods to invoke the constructor, copy constructor, and destructor
+//-----------------------------------------------------------------------------
+
+template <class T>
+inline T* Construct( T* pMemory )
+{
+ return ::new( pMemory ) T;
+}
+
+template <class T, typename ARG1>
+inline T* Construct( T* pMemory, ARG1 a1 )
+{
+ return ::new( pMemory ) T( a1 );
+}
+
+template <class T, typename ARG1, typename ARG2>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2 )
+{
+ return ::new( pMemory ) T( a1, a2 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3 )
+{
+ return ::new( pMemory ) T( a1, a2, a3 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4 )
+{
+ return ::new( pMemory ) T( a1, a2, a3, a4 );
+}
+
+template <class T, typename ARG1, typename ARG2, typename ARG3, typename ARG4, typename ARG5>
+inline T* Construct( T* pMemory, ARG1 a1, ARG2 a2, ARG3 a3, ARG4 a4, ARG5 a5 )
+{
+ return ::new( pMemory ) T( a1, a2, a3, a4, a5 );
+}
+
+template <class T, class P>
+inline void ConstructOneArg( T* pMemory, P const& arg)
+{
+ ::new( pMemory ) T(arg);
+}
+
+template <class T, class P1, class P2 >
+inline void ConstructTwoArg( T* pMemory, P1 const& arg1, P2 const& arg2)
+{
+ ::new( pMemory ) T(arg1, arg2);
+}
+
+template <class T, class P1, class P2, class P3 >
+inline void ConstructThreeArg( T* pMemory, P1 const& arg1, P2 const& arg2, P3 const& arg3)
+{
+ ::new( pMemory ) T(arg1, arg2, arg3);
+}
+
+template <class T>
+inline T* CopyConstruct( T* pMemory, T const& src )
+{
+ return ::new( pMemory ) T(src);
+}
+
+template <class T>
+inline void Destruct( T* pMemory )
+{
+ pMemory->~T();
+
+#ifdef _DEBUG
+ memset( reinterpret_cast<void*>( pMemory ), 0xDD, sizeof(T) );
+#endif
+}
+
+
+//
+// GET_OUTER()
+//
+// A platform-independent way for a contained class to get a pointer to its
+// owner. If you know a class is exclusively used in the context of some
+// "outer" class, this is a much more space efficient way to get at the outer
+// class than having the inner class store a pointer to it.
+//
+// class COuter
+// {
+// class CInner // Note: this does not need to be a nested class to work
+// {
+// void PrintAddressOfOuter()
+// {
+// printf( "Outer is at 0x%x\n", GET_OUTER( COuter, m_Inner ) );
+// }
+// };
+//
+// CInner m_Inner;
+// friend class CInner;
+// };
+
+#define GET_OUTER( OuterType, OuterMember ) \
+ ( ( OuterType * ) ( (uint8 *)this - offsetof( OuterType, OuterMember ) ) )
+
+
+/* TEMPLATE_FUNCTION_TABLE()
+
+ (Note added to platform.h so platforms that correctly support templated
+ functions can handle portions as templated functions rather than wrapped
+ functions)
+
+ Helps automate the process of creating an array of function
+ templates that are all specialized by a single integer.
+ This sort of thing is often useful in optimization work.
+
+ For example, using TEMPLATE_FUNCTION_TABLE, this:
+
+ TEMPLATE_FUNCTION_TABLE(int, Function, ( int blah, int blah ), 10)
+ {
+ return argument * argument;
+ }
+
+ is equivilent to the following:
+
+ (NOTE: the function has to be wrapped in a class due to code
+ generation bugs involved with directly specializing a function
+ based on a constant.)
+
+ template<int argument>
+ class FunctionWrapper
+ {
+ public:
+ int Function( int blah, int blah )
+ {
+ return argument*argument;
+ }
+ }
+
+ typedef int (*FunctionType)( int blah, int blah );
+
+ class FunctionName
+ {
+ public:
+ enum { count = 10 };
+ FunctionType functions[10];
+ };
+
+ FunctionType FunctionName::functions[] =
+ {
+ FunctionWrapper<0>::Function,
+ FunctionWrapper<1>::Function,
+ FunctionWrapper<2>::Function,
+ FunctionWrapper<3>::Function,
+ FunctionWrapper<4>::Function,
+ FunctionWrapper<5>::Function,
+ FunctionWrapper<6>::Function,
+ FunctionWrapper<7>::Function,
+ FunctionWrapper<8>::Function,
+ FunctionWrapper<9>::Function
+ };
+*/
+
+PLATFORM_INTERFACE bool vtune( bool resume );
+
+
+#define TEMPLATE_FUNCTION_TABLE(RETURN_TYPE, NAME, ARGS, COUNT) \
+ \
+typedef RETURN_TYPE (FASTCALL *__Type_##NAME) ARGS; \
+ \
+template<const int nArgument> \
+struct __Function_##NAME \
+{ \
+ static RETURN_TYPE FASTCALL Run ARGS; \
+}; \
+ \
+template <const int i> \
+struct __MetaLooper_##NAME : __MetaLooper_##NAME<i-1> \
+{ \
+ __Type_##NAME func; \
+ inline __MetaLooper_##NAME() { func = __Function_##NAME<i>::Run; } \
+}; \
+ \
+template<> \
+struct __MetaLooper_##NAME<0> \
+{ \
+ __Type_##NAME func; \
+ inline __MetaLooper_##NAME() { func = __Function_##NAME<0>::Run; } \
+}; \
+ \
+class NAME \
+{ \
+private: \
+ static const __MetaLooper_##NAME<COUNT> m; \
+public: \
+ enum { count = COUNT }; \
+ static const __Type_##NAME* functions; \
+}; \
+const __MetaLooper_##NAME<COUNT> NAME::m; \
+const __Type_##NAME* NAME::functions = (__Type_##NAME*)&m; \
+template<const int nArgument> \
+RETURN_TYPE FASTCALL __Function_##NAME<nArgument>::Run ARGS
+
+
+#define LOOP_INTERCHANGE(BOOLEAN, CODE)\
+ if( (BOOLEAN) )\
+ {\
+ CODE;\
+ } else\
+ {\
+ CODE;\
+ }
+
+//-----------------------------------------------------------------------------
+// Dynamic libs support
+//-----------------------------------------------------------------------------
+#if 0 // defined( PLATFORM_WINDOWS_PC )
+
+PLATFORM_INTERFACE void *Plat_GetProcAddress( const char *pszModule, const char *pszName );
+
+template <typename FUNCPTR_TYPE>
+class CDynamicFunction
+{
+public:
+ CDynamicFunction( const char *pszModule, const char *pszName, FUNCPTR_TYPE pfnFallback = NULL )
+ {
+ m_pfn = pfnFallback;
+ void *pAddr = Plat_GetProcAddress( pszModule, pszName );
+ if ( pAddr )
+ {
+ m_pfn = (FUNCPTR_TYPE)pAddr;
+ }
+ }
+
+ operator bool() { return m_pfn != NULL; }
+ bool operator !() { return !m_pfn; }
+ operator FUNCPTR_TYPE() { return m_pfn; }
+
+private:
+ FUNCPTR_TYPE m_pfn;
+};
+#endif
+
+
+//-----------------------------------------------------------------------------
+
+#include "tier0/valve_on.h"
+
+#if defined(TIER0_DLL_EXPORT)
+extern "C" int V_tier0_stricmp(const char *s1, const char *s2 );
+#undef stricmp
+#undef strcmpi
+#define stricmp(s1,s2) V_tier0_stricmp( s1, s2 )
+#define strcmpi(s1,s2) V_tier0_stricmp( s1, s2 )
+#endif
+
+
+#endif /* PLATFORM_H */
diff --git a/sp/src/public/tier0/pmc360.h b/sp/src/public/tier0/pmc360.h
index 4421fc91..ebae346f 100644
--- a/sp/src/public/tier0/pmc360.h
+++ b/sp/src/public/tier0/pmc360.h
@@ -1,73 +1,73 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Analogous to l2cache.h, this class represents information gleaned
-// from the 360's Performance Monitor Counters. In particular we
-// are interested in l2 cache misses and load-hit-stores.
-//
-//=============================================================================//
-#ifndef CPMCDATA_H
-#define CPMCDATA_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#ifndef _X360
-#error This file must only be compiled for XBOX360!
-#endif
-
-
-// Warning:
-// As written, this class only supports profiling thread 0, processor 0.
-
-class CPMCData
-{
-public:
-
- CPMCData();
- ~CPMCData() {};
-
- void Start( void );
- void End( void );
-
- /// This function should be called exactly once during the lifespan of the program;
- /// it will set up the counters to record the information we are interested in.
- /// This will stomp on whoever else might have set the performance counters elsewhere
- /// in the game.
- static void InitializeOnceProgramWide( void );
- static bool IsInitialized();
-
- //-------------------------------------------------------------------------
- // GetL2CacheMisses
- //-------------------------------------------------------------------------
- uint64 GetL2CacheMisses( void ) const
- {
- return m_Delta.L2CacheMiss;
- }
-
- uint64 GetLHS( void ) const
- {
- return m_Delta.LHS;
- }
-
-/*
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-#endif // DBGFLAG_VALIDATE
-*/
-
-private:
- /// represents saved numbers from the counters we are interested in
- struct PMCounters
- {
- uint64 L2CacheMiss;
- uint64 LHS; ///< load hit store
-
- PMCounters(int64 _l2cm, int64 _lhs ) : L2CacheMiss(_l2cm), LHS(_lhs) {};
- PMCounters() : L2CacheMiss(0), LHS(0) {};
- };
-
- PMCounters m_OnStart; ///< values when we began the timer
- PMCounters m_Delta ; ///< computed total delta between start/stop
-};
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Analogous to l2cache.h, this class represents information gleaned
+// from the 360's Performance Monitor Counters. In particular we
+// are interested in l2 cache misses and load-hit-stores.
+//
+//=============================================================================//
+#ifndef CPMCDATA_H
+#define CPMCDATA_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifndef _X360
+#error This file must only be compiled for XBOX360!
+#endif
+
+
+// Warning:
+// As written, this class only supports profiling thread 0, processor 0.
+
+class CPMCData
+{
+public:
+
+ CPMCData();
+ ~CPMCData() {};
+
+ void Start( void );
+ void End( void );
+
+ /// This function should be called exactly once during the lifespan of the program;
+ /// it will set up the counters to record the information we are interested in.
+ /// This will stomp on whoever else might have set the performance counters elsewhere
+ /// in the game.
+ static void InitializeOnceProgramWide( void );
+ static bool IsInitialized();
+
+ //-------------------------------------------------------------------------
+ // GetL2CacheMisses
+ //-------------------------------------------------------------------------
+ uint64 GetL2CacheMisses( void ) const
+ {
+ return m_Delta.L2CacheMiss;
+ }
+
+ uint64 GetLHS( void ) const
+ {
+ return m_Delta.LHS;
+ }
+
+/*
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+#endif // DBGFLAG_VALIDATE
+*/
+
+private:
+ /// represents saved numbers from the counters we are interested in
+ struct PMCounters
+ {
+ uint64 L2CacheMiss;
+ uint64 LHS; ///< load hit store
+
+ PMCounters(int64 _l2cm, int64 _lhs ) : L2CacheMiss(_l2cm), LHS(_lhs) {};
+ PMCounters() : L2CacheMiss(0), LHS(0) {};
+ };
+
+ PMCounters m_OnStart; ///< values when we began the timer
+ PMCounters m_Delta ; ///< computed total delta between start/stop
+};
+
#endif // CPMCDATA_H \ No newline at end of file
diff --git a/sp/src/public/tier0/progressbar.h b/sp/src/public/tier0/progressbar.h
index 4b8935b3..ce28afe1 100644
--- a/sp/src/public/tier0/progressbar.h
+++ b/sp/src/public/tier0/progressbar.h
@@ -1,23 +1,23 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Provide a shared place for library fucntions to report progress % for display
-//
-//=============================================================================//
-
-#ifndef PROGRESSBAR_H
-#define PROGRESSBAR_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-PLATFORM_INTERFACE void ReportProgress(char const *job_name, int total_units_to_do,
- int n_units_completed);
-
-typedef void (*ProgressReportHandler_t)( char const*, int, int );
-
-// install your own handler. returns previous handler
-PLATFORM_INTERFACE ProgressReportHandler_t InstallProgressReportHandler( ProgressReportHandler_t pfn);
-
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Provide a shared place for library fucntions to report progress % for display
+//
+//=============================================================================//
+
+#ifndef PROGRESSBAR_H
+#define PROGRESSBAR_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+PLATFORM_INTERFACE void ReportProgress(char const *job_name, int total_units_to_do,
+ int n_units_completed);
+
+typedef void (*ProgressReportHandler_t)( char const*, int, int );
+
+// install your own handler. returns previous handler
+PLATFORM_INTERFACE ProgressReportHandler_t InstallProgressReportHandler( ProgressReportHandler_t pfn);
+
+
+#endif
diff --git a/sp/src/public/tier0/protected_things.h b/sp/src/public/tier0/protected_things.h
index 160a0650..8cbfa929 100644
--- a/sp/src/public/tier0/protected_things.h
+++ b/sp/src/public/tier0/protected_things.h
@@ -1,271 +1,271 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef PROTECTED_THINGS_H
-#define PROTECTED_THINGS_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-// This header tries to prevent people from using potentially dangerous functions
-// (like the notorious non-null-terminating strncpy) and functions that will break
-// VCR mode (like time, input, registry, etc).
-//
-// This header should be included by ALL of our source code.
-
-// Eventually, ALL of these should be protected, but one man can only accomplish so much in
-// one day AND work on features too!
-#if defined( PROTECTED_STRINGS_ENABLE ) && !defined(DISABLE_PROTECTED_STRINGS)
-
- #if defined( printf )
- #undef printf
- #endif
- #define printf printf__HEY_YOU__USE_VSTDLIB
-
- #if defined( wprintf )
- #undef wprintf
- #endif
- #define wprintf wprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( strcmp )
- #undef strcmp
- #endif
- #define strcmp strcmp__HEY_YOU__USE_VSTDLIB
-
- #if defined( wcscmp )
- #undef wcscmp
- #endif
- #define wcscmp wcscmp__HEY_YOU__USE_VSTDLIB
-
- #if defined( strncpy )
- #undef strncpy
- #endif
- #define strncpy strncpy__HEY_YOU__USE_VSTDLIB
-
- #if defined( wcsncpy )
- #undef wcsncpy
- #endif
- #define wcsncpy wcsncpy__HEY_YOU__USE_VSTDLIB
-
- #if defined( strlen )
- #undef strlen
- #endif
- #define strlen strlen__HEY_YOU__USE_VSTDLIB
-
- #if defined( wcslen )
- #undef wcslen
- #endif
- #define wcslen wcslen__HEY_YOU__USE_VSTDLIB
-
- #if defined( Q_strlen )
- #undef Q_strlen
- #endif
- #define Q_strlen Q_strlen__HEY_YOU__USE_VSTDLIB
-
- #if defined( _snprintf )
- #undef _snprintf
- #endif
- #define _snprintf snprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( _snwprintf )
- #undef _snwprintf
- #endif
- #define _snwprintf snwprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( sprintf )
- #undef sprintf
- #endif
- #define sprintf sprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( swprintf )
- #undef swprintf
- #endif
- #define swprintf swprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( vsprintf )
- #undef vsprintf
- #endif
- #define vsprintf vsprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( vswprintf )
- #undef vswprintf
- #endif
- #define vswprintf vswprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( _vsnprintf )
- #undef _vsnprintf
- #endif
- #define _vsnprintf vsnprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( _vsnwprintf )
- #undef _vsnwprintf
- #endif
- #define _vsnwprintf vsnwprintf__HEY_YOU__USE_VSTDLIB
-
- #if defined( strcat )
- #undef strcat
- #endif
- #define strcat strcat__HEY_YOU__USE_VSTDLIB
-
- #if defined( wcscat )
- #undef wcscat
- #endif
- #define wcscat wcscat__HEY_YOU__USE_VSTDLIB
-
- #if defined( strncat )
- #undef strncat
- #endif
- #define strncat strncat__HEY_YOU__USE_VSTDLIB
-
- #if defined( wcsncat )
- #undef wcsncat
- #endif
- #define wcsncat wcsncat__HEY_YOU__USE_VSTDLIB
-
-#endif
-
-
-#if defined( PROTECTED_THINGS_ENABLE ) && !defined( _X360 ) && !defined(DISABLE_PROTECTED_THINGS)
-
- #if defined( GetTickCount )
- #undef GetTickCount
- #endif
- #define GetTickCount GetTickCount__USE_VCR_MODE
-
-
- #if defined( timeGetTime )
- #undef timeGetTime
- #endif
- #define timeGetTime timeGetTime__USE_VCR_MODE
- #if defined( clock )
- #undef clock
- #endif
- #define time time__USE_VCR_MODE
-
-
- #if defined( recvfrom )
- #undef recvfrom
- #endif
- #define recvfrom recvfrom__USE_VCR_MODE
-
-
- #if defined( GetCursorPos )
- #undef GetCursorPos
- #endif
- #define GetCursorPos GetCursorPos__USE_VCR_MODE
-
-
- #if defined( ScreenToClient )
- #undef ScreenToClient
- #endif
- #define ScreenToClient ScreenToClient__USE_VCR_MODE
-
-
- #if defined( GetCommandLine )
- #undef GetCommandLine
- #endif
- #define GetCommandLine GetCommandLine__USE_VCR_MODE
-
-
- #if defined( RegOpenKeyEx )
- #undef RegOpenKeyEx
- #endif
- #define RegOpenKeyEx RegOpenKeyEx__USE_VCR_MODE
-
-
- #if defined( RegOpenKey )
- #undef RegOpenKey
- #endif
- #define RegOpenKey RegOpenKey__USE_VCR_MODE
-
-
- #if defined( RegSetValueEx )
- #undef RegSetValueEx
- #endif
- #define RegSetValueEx RegSetValueEx__USE_VCR_MODE
-
-
- #if defined( RegSetValue )
- #undef RegSetValue
- #endif
- #define RegSetValue RegSetValue__USE_VCR_MODE
-
-
- #if defined( RegQueryValueEx )
- #undef RegQueryValueEx
- #endif
- #define RegQueryValueEx RegQueryValueEx__USE_VCR_MODE
-
-
- #if defined( RegQueryValue )
- #undef RegQueryValue
- #endif
- #define RegQueryValue RegQueryValue__USE_VCR_MODE
-
-
- #if defined( RegCreateKeyEx )
- #undef RegCreateKeyEx
- #endif
- #define RegCreateKeyEx RegCreateKeyEx__USE_VCR_MODE
-
-
- #if defined( RegCreateKey )
- #undef RegCreateKey
- #endif
- #define RegCreateKey RegCreateKey__USE_VCR_MODE
-
-
- #if defined( RegCloseKey )
- #undef RegCloseKey
- #endif
- #define RegCloseKey RegCloseKey__USE_VCR_MODE
-
-
- #if defined( GetNumberOfConsoleInputEvents )
- #undef GetNumberOfConsoleInputEvents
- #endif
- #define GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents__USE_VCR_MODE
-
-
- #if defined( ReadConsoleInput )
- #undef ReadConsoleInput
- #endif
- #define ReadConsoleInput ReadConsoleInput__USE_VCR_MODE
-
-
- #if defined( GetAsyncKeyState )
- #undef GetAsyncKeyState
- #endif
- #define GetAsyncKeyState GetAsyncKeyState__USE_VCR_MODE
-
-
- #if defined( GetKeyState )
- #undef GetKeyState
- #endif
- #define GetKeyState GetKeyState__USE_VCR_MODE
-
-
- #if defined( CreateThread )
- #undef CreateThread
- #endif
- #define CreateThread CreateThread__USE_VCR_MODE
-
- #if defined( WaitForSingleObject )
- #undef WaitForSingleObject
- #endif
- #define WaitForSingleObject WaitForSingleObject__USE_VCR_MODE
-
- #if defined( EnterCriticalSection )
- #undef EnterCriticalSection
- #endif
- #define EnterCriticalSection EnterCriticalSection__USE_VCR_MODE
-
-#endif
-
-
-#endif // PROTECTED_THINGS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef PROTECTED_THINGS_H
+#define PROTECTED_THINGS_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+// This header tries to prevent people from using potentially dangerous functions
+// (like the notorious non-null-terminating strncpy) and functions that will break
+// VCR mode (like time, input, registry, etc).
+//
+// This header should be included by ALL of our source code.
+
+// Eventually, ALL of these should be protected, but one man can only accomplish so much in
+// one day AND work on features too!
+#if defined( PROTECTED_STRINGS_ENABLE ) && !defined(DISABLE_PROTECTED_STRINGS)
+
+ #if defined( printf )
+ #undef printf
+ #endif
+ #define printf printf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wprintf )
+ #undef wprintf
+ #endif
+ #define wprintf wprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( strcmp )
+ #undef strcmp
+ #endif
+ #define strcmp strcmp__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wcscmp )
+ #undef wcscmp
+ #endif
+ #define wcscmp wcscmp__HEY_YOU__USE_VSTDLIB
+
+ #if defined( strncpy )
+ #undef strncpy
+ #endif
+ #define strncpy strncpy__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wcsncpy )
+ #undef wcsncpy
+ #endif
+ #define wcsncpy wcsncpy__HEY_YOU__USE_VSTDLIB
+
+ #if defined( strlen )
+ #undef strlen
+ #endif
+ #define strlen strlen__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wcslen )
+ #undef wcslen
+ #endif
+ #define wcslen wcslen__HEY_YOU__USE_VSTDLIB
+
+ #if defined( Q_strlen )
+ #undef Q_strlen
+ #endif
+ #define Q_strlen Q_strlen__HEY_YOU__USE_VSTDLIB
+
+ #if defined( _snprintf )
+ #undef _snprintf
+ #endif
+ #define _snprintf snprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( _snwprintf )
+ #undef _snwprintf
+ #endif
+ #define _snwprintf snwprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( sprintf )
+ #undef sprintf
+ #endif
+ #define sprintf sprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( swprintf )
+ #undef swprintf
+ #endif
+ #define swprintf swprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( vsprintf )
+ #undef vsprintf
+ #endif
+ #define vsprintf vsprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( vswprintf )
+ #undef vswprintf
+ #endif
+ #define vswprintf vswprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( _vsnprintf )
+ #undef _vsnprintf
+ #endif
+ #define _vsnprintf vsnprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( _vsnwprintf )
+ #undef _vsnwprintf
+ #endif
+ #define _vsnwprintf vsnwprintf__HEY_YOU__USE_VSTDLIB
+
+ #if defined( strcat )
+ #undef strcat
+ #endif
+ #define strcat strcat__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wcscat )
+ #undef wcscat
+ #endif
+ #define wcscat wcscat__HEY_YOU__USE_VSTDLIB
+
+ #if defined( strncat )
+ #undef strncat
+ #endif
+ #define strncat strncat__HEY_YOU__USE_VSTDLIB
+
+ #if defined( wcsncat )
+ #undef wcsncat
+ #endif
+ #define wcsncat wcsncat__HEY_YOU__USE_VSTDLIB
+
+#endif
+
+
+#if defined( PROTECTED_THINGS_ENABLE ) && !defined( _X360 ) && !defined(DISABLE_PROTECTED_THINGS)
+
+ #if defined( GetTickCount )
+ #undef GetTickCount
+ #endif
+ #define GetTickCount GetTickCount__USE_VCR_MODE
+
+
+ #if defined( timeGetTime )
+ #undef timeGetTime
+ #endif
+ #define timeGetTime timeGetTime__USE_VCR_MODE
+ #if defined( clock )
+ #undef clock
+ #endif
+ #define time time__USE_VCR_MODE
+
+
+ #if defined( recvfrom )
+ #undef recvfrom
+ #endif
+ #define recvfrom recvfrom__USE_VCR_MODE
+
+
+ #if defined( GetCursorPos )
+ #undef GetCursorPos
+ #endif
+ #define GetCursorPos GetCursorPos__USE_VCR_MODE
+
+
+ #if defined( ScreenToClient )
+ #undef ScreenToClient
+ #endif
+ #define ScreenToClient ScreenToClient__USE_VCR_MODE
+
+
+ #if defined( GetCommandLine )
+ #undef GetCommandLine
+ #endif
+ #define GetCommandLine GetCommandLine__USE_VCR_MODE
+
+
+ #if defined( RegOpenKeyEx )
+ #undef RegOpenKeyEx
+ #endif
+ #define RegOpenKeyEx RegOpenKeyEx__USE_VCR_MODE
+
+
+ #if defined( RegOpenKey )
+ #undef RegOpenKey
+ #endif
+ #define RegOpenKey RegOpenKey__USE_VCR_MODE
+
+
+ #if defined( RegSetValueEx )
+ #undef RegSetValueEx
+ #endif
+ #define RegSetValueEx RegSetValueEx__USE_VCR_MODE
+
+
+ #if defined( RegSetValue )
+ #undef RegSetValue
+ #endif
+ #define RegSetValue RegSetValue__USE_VCR_MODE
+
+
+ #if defined( RegQueryValueEx )
+ #undef RegQueryValueEx
+ #endif
+ #define RegQueryValueEx RegQueryValueEx__USE_VCR_MODE
+
+
+ #if defined( RegQueryValue )
+ #undef RegQueryValue
+ #endif
+ #define RegQueryValue RegQueryValue__USE_VCR_MODE
+
+
+ #if defined( RegCreateKeyEx )
+ #undef RegCreateKeyEx
+ #endif
+ #define RegCreateKeyEx RegCreateKeyEx__USE_VCR_MODE
+
+
+ #if defined( RegCreateKey )
+ #undef RegCreateKey
+ #endif
+ #define RegCreateKey RegCreateKey__USE_VCR_MODE
+
+
+ #if defined( RegCloseKey )
+ #undef RegCloseKey
+ #endif
+ #define RegCloseKey RegCloseKey__USE_VCR_MODE
+
+
+ #if defined( GetNumberOfConsoleInputEvents )
+ #undef GetNumberOfConsoleInputEvents
+ #endif
+ #define GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents__USE_VCR_MODE
+
+
+ #if defined( ReadConsoleInput )
+ #undef ReadConsoleInput
+ #endif
+ #define ReadConsoleInput ReadConsoleInput__USE_VCR_MODE
+
+
+ #if defined( GetAsyncKeyState )
+ #undef GetAsyncKeyState
+ #endif
+ #define GetAsyncKeyState GetAsyncKeyState__USE_VCR_MODE
+
+
+ #if defined( GetKeyState )
+ #undef GetKeyState
+ #endif
+ #define GetKeyState GetKeyState__USE_VCR_MODE
+
+
+ #if defined( CreateThread )
+ #undef CreateThread
+ #endif
+ #define CreateThread CreateThread__USE_VCR_MODE
+
+ #if defined( WaitForSingleObject )
+ #undef WaitForSingleObject
+ #endif
+ #define WaitForSingleObject WaitForSingleObject__USE_VCR_MODE
+
+ #if defined( EnterCriticalSection )
+ #undef EnterCriticalSection
+ #endif
+ #define EnterCriticalSection EnterCriticalSection__USE_VCR_MODE
+
+#endif
+
+
+#endif // PROTECTED_THINGS_H
diff --git a/sp/src/public/tier0/systeminformation.h b/sp/src/public/tier0/systeminformation.h
index 91fb6c7c..f9ba59e1 100644
--- a/sp/src/public/tier0/systeminformation.h
+++ b/sp/src/public/tier0/systeminformation.h
@@ -1,56 +1,56 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-
-#ifndef SYSTEMINFORMATION_H
-#define SYSTEMINFORMATION_H
-
-#ifdef _WIN32
- #pragma once
-#endif
-
-#ifndef PLATFORM_INTERFACE
- #define PLATFORM_INTERFACE
-#endif
-
-//
-// Defines a possible outcome of a system call
-//
-enum SYSTEM_CALL_RESULT_t
-{
- SYSCALL_SUCCESS = 0, // System call succeeded
- SYSCALL_FAILED = 1, // System call failed
- SYSCALL_NOPROC = 2, // Failed to find required system procedure
- SYSCALL_NODLL = 3, // Failed to find or load required system module
- SYSCALL_UNSUPPORTED = 4, // System call unsupported on the OS
-};
-
-
-//
-// Information about paged pool memory
-//
-struct PAGED_POOL_INFO_t
-{
- unsigned long numPagesUsed; // Number of Paged Pool pages used
- unsigned long numPagesFree; // Number of Paged Pool pages free
-};
-
-//
-// Plat_GetMemPageSize
-// Returns the size of a memory page in kilobytes.
-//
-PLATFORM_INTERFACE unsigned long Plat_GetMemPageSize();
-
-//
-// Plat_GetPagedPoolInfo
-// Fills in the paged pool info structure if successful.
-//
-PLATFORM_INTERFACE SYSTEM_CALL_RESULT_t Plat_GetPagedPoolInfo( PAGED_POOL_INFO_t *pPPI );
-
-
-
-#endif // #ifndef SYSTEMINFORMATION_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+
+#ifndef SYSTEMINFORMATION_H
+#define SYSTEMINFORMATION_H
+
+#ifdef _WIN32
+ #pragma once
+#endif
+
+#ifndef PLATFORM_INTERFACE
+ #define PLATFORM_INTERFACE
+#endif
+
+//
+// Defines a possible outcome of a system call
+//
+enum SYSTEM_CALL_RESULT_t
+{
+ SYSCALL_SUCCESS = 0, // System call succeeded
+ SYSCALL_FAILED = 1, // System call failed
+ SYSCALL_NOPROC = 2, // Failed to find required system procedure
+ SYSCALL_NODLL = 3, // Failed to find or load required system module
+ SYSCALL_UNSUPPORTED = 4, // System call unsupported on the OS
+};
+
+
+//
+// Information about paged pool memory
+//
+struct PAGED_POOL_INFO_t
+{
+ unsigned long numPagesUsed; // Number of Paged Pool pages used
+ unsigned long numPagesFree; // Number of Paged Pool pages free
+};
+
+//
+// Plat_GetMemPageSize
+// Returns the size of a memory page in kilobytes.
+//
+PLATFORM_INTERFACE unsigned long Plat_GetMemPageSize();
+
+//
+// Plat_GetPagedPoolInfo
+// Fills in the paged pool info structure if successful.
+//
+PLATFORM_INTERFACE SYSTEM_CALL_RESULT_t Plat_GetPagedPoolInfo( PAGED_POOL_INFO_t *pPPI );
+
+
+
+#endif // #ifndef SYSTEMINFORMATION_H
diff --git a/sp/src/public/tier0/testthread.h b/sp/src/public/tier0/testthread.h
index d80a4da6..6ffda657 100644
--- a/sp/src/public/tier0/testthread.h
+++ b/sp/src/public/tier0/testthread.h
@@ -1,60 +1,60 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: exposes testing thread functions
-//
-//=============================================================================
-
-#ifndef TESTTHREAD_H
-#define TESTTHREAD_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/dbg.h"
-
-// test callback
-typedef void (STDCALL *TestFunc)(void *pv);
-
-// runs the test function
-DBG_INTERFACE void Test_RunTest(TestFunc func, void *pvArg);
-
-// call to give the test thread a chance to run
-// calling thread will block until the test thread yields
-// doesn't do anything if no tests are running
-DBG_INTERFACE void Test_RunFrame();
-
-// true if any tests are running, or have ran
-DBG_INTERFACE bool Test_IsActive();
-
-// sets that the test has failed
-DBG_INTERFACE void Test_SetFailed();
-
-// true if any tests have failed, due to an assert, warning, or explicit fail
-DBG_INTERFACE bool Test_HasFailed();
-
-// true if any tests have completed
-DBG_INTERFACE bool Test_HasFinished();
-
-// terminates the test thread
-DBG_INTERFACE void Test_TerminateThread();
-
-// the following functions should only be called from the test thread
-
-// yields to the main thread for a single frame
-// passing in is a count of the number of frames that have been yielded by this yield macro
-// can be used to assert if a test thread is blocked foor
-DBG_INTERFACE void TestThread_Yield();
-
-// utility functions to pause the test frame until the selected condition is true
-#define YIELD_UNTIL(x) { int iYieldCount = 0; while (!(x)) { TestThread_Yield(); iYieldCount++; if ( iYieldCount >= 100 ) { AssertMsg( false, #x ); break; } } }
-
-// use this like a while(1) loop, with break; to stop yielding
-#define YIELD_UNTIL_BREAK() for (; true; TestThread_Yield())
-
-// yields for a single frame
-#define YIELD_FRAME() { TestThread_Yield(); }
-#define YIELD_TWO_FRAMES() { TestThread_Yield(); TestThread_Yield(); }
-
-
-
-#endif // TESTTHREAD_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: exposes testing thread functions
+//
+//=============================================================================
+
+#ifndef TESTTHREAD_H
+#define TESTTHREAD_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/dbg.h"
+
+// test callback
+typedef void (STDCALL *TestFunc)(void *pv);
+
+// runs the test function
+DBG_INTERFACE void Test_RunTest(TestFunc func, void *pvArg);
+
+// call to give the test thread a chance to run
+// calling thread will block until the test thread yields
+// doesn't do anything if no tests are running
+DBG_INTERFACE void Test_RunFrame();
+
+// true if any tests are running, or have ran
+DBG_INTERFACE bool Test_IsActive();
+
+// sets that the test has failed
+DBG_INTERFACE void Test_SetFailed();
+
+// true if any tests have failed, due to an assert, warning, or explicit fail
+DBG_INTERFACE bool Test_HasFailed();
+
+// true if any tests have completed
+DBG_INTERFACE bool Test_HasFinished();
+
+// terminates the test thread
+DBG_INTERFACE void Test_TerminateThread();
+
+// the following functions should only be called from the test thread
+
+// yields to the main thread for a single frame
+// passing in is a count of the number of frames that have been yielded by this yield macro
+// can be used to assert if a test thread is blocked foor
+DBG_INTERFACE void TestThread_Yield();
+
+// utility functions to pause the test frame until the selected condition is true
+#define YIELD_UNTIL(x) { int iYieldCount = 0; while (!(x)) { TestThread_Yield(); iYieldCount++; if ( iYieldCount >= 100 ) { AssertMsg( false, #x ); break; } } }
+
+// use this like a while(1) loop, with break; to stop yielding
+#define YIELD_UNTIL_BREAK() for (; true; TestThread_Yield())
+
+// yields for a single frame
+#define YIELD_FRAME() { TestThread_Yield(); }
+#define YIELD_TWO_FRAMES() { TestThread_Yield(); TestThread_Yield(); }
+
+
+
+#endif // TESTTHREAD_H
diff --git a/sp/src/public/tier0/threadtools.h b/sp/src/public/tier0/threadtools.h
index 7faeff72..12ea369a 100644
--- a/sp/src/public/tier0/threadtools.h
+++ b/sp/src/public/tier0/threadtools.h
@@ -1,1714 +1,1714 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: A collection of utility classes to simplify thread handling, and
-// as much as possible contain portability problems. Here avoiding
-// including windows.h.
-//
-//=============================================================================
-
-#ifndef THREADTOOLS_H
-#define THREADTOOLS_H
-
-#include <limits.h>
-
-#include "tier0/platform.h"
-#include "tier0/dbg.h"
-#include "tier0/vcrmode.h"
-
-#ifdef PLATFORM_WINDOWS_PC
-#include <intrin.h>
-#endif
-
-#ifdef POSIX
-#include <pthread.h>
-#include <errno.h>
-#define WAIT_OBJECT_0 0
-#define WAIT_TIMEOUT 0x00000102
-#define WAIT_FAILED -1
-#define THREAD_PRIORITY_HIGHEST 2
-#endif
-
-#if defined( _WIN32 )
-#pragma once
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-// #define THREAD_PROFILER 1
-
-#ifndef _RETAIL
-#define THREAD_MUTEX_TRACING_SUPPORTED
-#if defined(_WIN32) && defined(_DEBUG)
-#define THREAD_MUTEX_TRACING_ENABLED
-#endif
-#endif
-
-#ifdef _WIN32
-typedef void *HANDLE;
-#endif
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-const unsigned TT_INFINITE = 0xffffffff;
-
-#ifndef NO_THREAD_LOCAL
-
-#ifndef THREAD_LOCAL
-#ifdef _WIN32
-#define THREAD_LOCAL __declspec(thread)
-#elif POSIX
-#define THREAD_LOCAL __thread
-#endif
-#endif
-
-#endif // NO_THREAD_LOCAL
-
-typedef unsigned long ThreadId_t;
-
-//-----------------------------------------------------------------------------
-//
-// Simple thread creation. Differs from VCR mode/CreateThread/_beginthreadex
-// in that it accepts a standard C function rather than compiler specific one.
-//
-//-----------------------------------------------------------------------------
-FORWARD_DECLARE_HANDLE( ThreadHandle_t );
-typedef unsigned (*ThreadFunc_t)( void *pParam );
-
-PLATFORM_OVERLOAD ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, ThreadId_t *pID, unsigned stackSize = 0 );
-PLATFORM_INTERFACE ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, unsigned stackSize = 0 );
-PLATFORM_INTERFACE bool ReleaseThreadHandle( ThreadHandle_t );
-
-
-//-----------------------------------------------------------------------------
-
-PLATFORM_INTERFACE void ThreadSleep(unsigned duration = 0);
-PLATFORM_INTERFACE uint ThreadGetCurrentId();
-PLATFORM_INTERFACE ThreadHandle_t ThreadGetCurrentHandle();
-PLATFORM_INTERFACE int ThreadGetPriority( ThreadHandle_t hThread = NULL );
-PLATFORM_INTERFACE bool ThreadSetPriority( ThreadHandle_t hThread, int priority );
-inline bool ThreadSetPriority( int priority ) { return ThreadSetPriority( NULL, priority ); }
-PLATFORM_INTERFACE bool ThreadInMainThread();
-PLATFORM_INTERFACE void DeclareCurrentThreadIsMainThread();
-
-// NOTE: ThreadedLoadLibraryFunc_t needs to return the sleep time in milliseconds or TT_INFINITE
-typedef int (*ThreadedLoadLibraryFunc_t)();
-PLATFORM_INTERFACE void SetThreadedLoadLibraryFunc( ThreadedLoadLibraryFunc_t func );
-PLATFORM_INTERFACE ThreadedLoadLibraryFunc_t GetThreadedLoadLibraryFunc();
-
-#if defined( _WIN32 ) && !defined( _WIN64 ) && !defined( _X360 )
-extern "C" unsigned long __declspec(dllimport) __stdcall GetCurrentThreadId();
-#define ThreadGetCurrentId GetCurrentThreadId
-#endif
-
-inline void ThreadPause()
-{
-#if defined( PLATFORM_WINDOWS_PC )
- // Intrinsic for __asm pause; from <intrin.h>
- _mm_pause();
-#elif POSIX
- __asm __volatile( "pause" );
-#elif defined( _X360 )
-#else
-#error "implement me"
-#endif
-}
-
-PLATFORM_INTERFACE bool ThreadJoin( ThreadHandle_t, unsigned timeout = TT_INFINITE );
-// If you're not calling ThreadJoin, you need to call ThreadDetach so pthreads on Linux knows it can
-// free the memory for this thread. Otherwise you wind up leaking threads until you run out and
-// CreateSimpleThread() will fail.
-PLATFORM_INTERFACE void ThreadDetach( ThreadHandle_t );
-
-PLATFORM_INTERFACE void ThreadSetDebugName( ThreadId_t id, const char *pszName );
-inline void ThreadSetDebugName( const char *pszName ) { ThreadSetDebugName( (ThreadId_t)-1, pszName ); }
-
-PLATFORM_INTERFACE void ThreadSetAffinity( ThreadHandle_t hThread, int nAffinityMask );
-
-//-----------------------------------------------------------------------------
-
-enum ThreadWaitResult_t
-{
- TW_FAILED = 0xffffffff, // WAIT_FAILED
- TW_TIMEOUT = 0x00000102, // WAIT_TIMEOUT
-};
-
-#ifdef _WIN32
-PLATFORM_INTERFACE int ThreadWaitForObjects( int nEvents, const HANDLE *pHandles, bool bWaitAll = true, unsigned timeout = TT_INFINITE );
-inline int ThreadWaitForObject( HANDLE handle, bool bWaitAll = true, unsigned timeout = TT_INFINITE ) { return ThreadWaitForObjects( 1, &handle, bWaitAll, timeout ); }
-#endif
-
-//-----------------------------------------------------------------------------
-//
-// Interlock methods. These perform very fast atomic thread
-// safe operations. These are especially relevant in a multi-core setting.
-//
-//-----------------------------------------------------------------------------
-
-#ifdef _WIN32
-#define NOINLINE
-#elif POSIX
-#define NOINLINE __attribute__ ((noinline))
-#endif
-
-// ThreadMemoryBarrier is a fence/barrier sufficient for most uses. It prevents reads
-// from moving past reads, and writes moving past writes. It is sufficient for
-// read-acquire and write-release barriers. It is not a full barrier and it does
-// not prevent reads from moving past writes -- that would require a full __sync()
-// on PPC and is significantly more expensive.
-#if defined( _X360 ) || defined( _PS3 )
- #define ThreadMemoryBarrier() __lwsync()
-
-#elif defined(_MSC_VER)
- // Prevent compiler reordering across this barrier. This is
- // sufficient for most purposes on x86/x64.
-
- #if _MSC_VER < 1500
- // !KLUDGE! For VC 2005
- // http://connect.microsoft.com/VisualStudio/feedback/details/100051
- #pragma intrinsic(_ReadWriteBarrier)
- #endif
- #define ThreadMemoryBarrier() _ReadWriteBarrier()
-#elif defined(GNUC)
- // Prevent compiler reordering across this barrier. This is
- // sufficient for most purposes on x86/x64.
- // http://preshing.com/20120625/memory-ordering-at-compile-time
- #define ThreadMemoryBarrier() asm volatile("" ::: "memory")
-#else
- #error Every platform needs to define ThreadMemoryBarrier to at least prevent compiler reordering
-#endif
-
-#if defined(_WIN32) && !defined(_X360)
- #if ( _MSC_VER >= 1310 )
- #define USE_INTRINSIC_INTERLOCKED
- #endif
-#endif
-
-#ifdef USE_INTRINSIC_INTERLOCKED
-extern "C"
-{
- long __cdecl _InterlockedIncrement(volatile long*);
- long __cdecl _InterlockedDecrement(volatile long*);
- long __cdecl _InterlockedExchange(volatile long*, long);
- long __cdecl _InterlockedExchangeAdd(volatile long*, long);
- long __cdecl _InterlockedCompareExchange(volatile long*, long, long);
-}
-
-#pragma intrinsic( _InterlockedCompareExchange )
-#pragma intrinsic( _InterlockedDecrement )
-#pragma intrinsic( _InterlockedExchange )
-#pragma intrinsic( _InterlockedExchangeAdd )
-#pragma intrinsic( _InterlockedIncrement )
-
-inline long ThreadInterlockedIncrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedIncrement( p ); }
-inline long ThreadInterlockedDecrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedDecrement( p ); }
-inline long ThreadInterlockedExchange( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchange( p, value ); }
-inline long ThreadInterlockedExchangeAdd( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchangeAdd( p, value ); }
-inline long ThreadInterlockedCompareExchange( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedCompareExchange( p, value, comperand ); }
-inline bool ThreadInterlockedAssignIf( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return ( _InterlockedCompareExchange( p, value, comperand ) == comperand ); }
-#else
-PLATFORM_INTERFACE long ThreadInterlockedIncrement( long volatile * );
-PLATFORM_INTERFACE long ThreadInterlockedDecrement( long volatile * );
-PLATFORM_INTERFACE long ThreadInterlockedExchange( long volatile *, long value );
-PLATFORM_INTERFACE long ThreadInterlockedExchangeAdd( long volatile *, long value );
-PLATFORM_INTERFACE long ThreadInterlockedCompareExchange( long volatile *, long value, long comperand );
-PLATFORM_INTERFACE bool ThreadInterlockedAssignIf( long volatile *, long value, long comperand );
-#endif
-
-inline unsigned ThreadInterlockedExchangeSubtract( long volatile *p, long value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, -value ); }
-
-#if defined( USE_INTRINSIC_INTERLOCKED ) && !defined( _WIN64 )
-#define TIPTR()
-inline void *ThreadInterlockedExchangePointer( void * volatile *p, void *value ) { return (void *)_InterlockedExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value) ); }
-inline void *ThreadInterlockedCompareExchangePointer( void * volatile *p, void *value, void *comperand ) { return (void *)_InterlockedCompareExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value), reinterpret_cast<long>(comperand) ); }
-inline bool ThreadInterlockedAssignPointerIf( void * volatile *p, void *value, void *comperand ) { return ( _InterlockedCompareExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value), reinterpret_cast<long>(comperand) ) == reinterpret_cast<long>(comperand) ); }
-#else
-PLATFORM_INTERFACE void *ThreadInterlockedExchangePointer( void * volatile *, void *value ) NOINLINE;
-PLATFORM_INTERFACE void *ThreadInterlockedCompareExchangePointer( void * volatile *, void *value, void *comperand ) NOINLINE;
-PLATFORM_INTERFACE bool ThreadInterlockedAssignPointerIf( void * volatile *, void *value, void *comperand ) NOINLINE;
-#endif
-
-inline void const *ThreadInterlockedExchangePointerToConst( void const * volatile *p, void const *value ) { return ThreadInterlockedExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ) ); }
-inline void const *ThreadInterlockedCompareExchangePointerToConst( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedCompareExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); }
-inline bool ThreadInterlockedAssignPointerToConstIf( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedAssignPointerIf( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); }
-
-#if defined( X64BITS )
-#if defined (_WIN32)
-typedef __m128i int128;
-inline int128 int128_zero() { return _mm_setzero_si128(); }
-#else
-typedef __int128_t int128;
-#define int128_zero() 0
-#endif
-
-PLATFORM_INTERFACE bool ThreadInterlockedAssignIf128( volatile int128 *pDest, const int128 &value, const int128 &comperand ) NOINLINE;
-
-#endif
-
-PLATFORM_INTERFACE int64 ThreadInterlockedIncrement64( int64 volatile * ) NOINLINE;
-PLATFORM_INTERFACE int64 ThreadInterlockedDecrement64( int64 volatile * ) NOINLINE;
-PLATFORM_INTERFACE int64 ThreadInterlockedCompareExchange64( int64 volatile *, int64 value, int64 comperand ) NOINLINE;
-PLATFORM_INTERFACE int64 ThreadInterlockedExchange64( int64 volatile *, int64 value ) NOINLINE;
-PLATFORM_INTERFACE int64 ThreadInterlockedExchangeAdd64( int64 volatile *, int64 value ) NOINLINE;
-PLATFORM_INTERFACE bool ThreadInterlockedAssignIf64(volatile int64 *pDest, int64 value, int64 comperand ) NOINLINE;
-
-inline unsigned ThreadInterlockedExchangeSubtract( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
-inline unsigned ThreadInterlockedIncrement( unsigned volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); }
-inline unsigned ThreadInterlockedDecrement( unsigned volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); }
-inline unsigned ThreadInterlockedExchange( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); }
-inline unsigned ThreadInterlockedExchangeAdd( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
-inline unsigned ThreadInterlockedCompareExchange( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); }
-inline bool ThreadInterlockedAssignIf( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); }
-
-inline int ThreadInterlockedExchangeSubtract( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
-inline int ThreadInterlockedIncrement( int volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); }
-inline int ThreadInterlockedDecrement( int volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); }
-inline int ThreadInterlockedExchange( int volatile *p, int value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); }
-inline int ThreadInterlockedExchangeAdd( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
-inline int ThreadInterlockedCompareExchange( int volatile *p, int value, int comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); }
-inline bool ThreadInterlockedAssignIf( int volatile *p, int value, int comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); }
-
-//-----------------------------------------------------------------------------
-// Access to VTune thread profiling
-//-----------------------------------------------------------------------------
-#if defined(_WIN32) && defined(THREAD_PROFILER)
-PLATFORM_INTERFACE void ThreadNotifySyncPrepare(void *p);
-PLATFORM_INTERFACE void ThreadNotifySyncCancel(void *p);
-PLATFORM_INTERFACE void ThreadNotifySyncAcquired(void *p);
-PLATFORM_INTERFACE void ThreadNotifySyncReleasing(void *p);
-#else
-#define ThreadNotifySyncPrepare(p) ((void)0)
-#define ThreadNotifySyncCancel(p) ((void)0)
-#define ThreadNotifySyncAcquired(p) ((void)0)
-#define ThreadNotifySyncReleasing(p) ((void)0)
-#endif
-
-//-----------------------------------------------------------------------------
-// Encapsulation of a thread local datum (needed because THREAD_LOCAL doesn't
-// work in a DLL loaded with LoadLibrary()
-//-----------------------------------------------------------------------------
-
-#ifndef __AFXTLS_H__ // not compatible with some Windows headers
-#ifndef NO_THREAD_LOCAL
-
-class PLATFORM_CLASS CThreadLocalBase
- {
-public:
- CThreadLocalBase();
- ~CThreadLocalBase();
-
- void * Get() const;
- void Set(void *);
-
-private:
-#ifdef _WIN32
- uint32 m_index;
-#elif POSIX
- pthread_key_t m_index;
-#endif
- };
-
- //---------------------------------------------------------
-
-#ifndef __AFXTLS_H__
-
- template <class T>
- class CThreadLocal : public CThreadLocalBase
- {
- public:
- CThreadLocal()
- {
- COMPILE_TIME_ASSERT( sizeof(T) == sizeof(void *) );
- }
-
- T Get() const
- {
- return reinterpret_cast<T>( CThreadLocalBase::Get() );
- }
-
- void Set(T val)
- {
- CThreadLocalBase::Set( reinterpret_cast<void *>(val) );
- }
- };
-
-#endif
-
- //---------------------------------------------------------
-
-template <class T = intp>
- class CThreadLocalInt : public CThreadLocal<T>
- {
- public:
- CThreadLocalInt()
- {
- COMPILE_TIME_ASSERT( sizeof(T) >= sizeof(int) );
- }
-
- operator const int() const { return (int)this->Get(); }
- int operator=( int i ) { this->Set( (intp)i ); return i; }
-
- int operator++() { T i = this->Get(); this->Set( ++i ); return (int)i; }
- int operator++(int) { T i = this->Get(); this->Set( i + 1 ); return (int)i; }
-
- int operator--() { T i = this->Get(); this->Set( --i ); return (int)i; }
- int operator--(int) { T i = this->Get(); this->Set( i - 1 ); return (int)i; }
- };
-
-
- //---------------------------------------------------------
-
- template <class T>
- class CThreadLocalPtr : private CThreadLocalBase
- {
- public:
- CThreadLocalPtr() {}
-
- operator const void *() const { return (T *)Get(); }
- operator void *() { return (T *)Get(); }
-
- operator const T *() const { return (T *)Get(); }
- operator const T *() { return (T *)Get(); }
- operator T *() { return (T *)Get(); }
-
- int operator=( int i ) { AssertMsg( i == 0, "Only NULL allowed on integer assign" ); Set( NULL ); return 0; }
- T * operator=( T *p ) { Set( p ); return p; }
-
- bool operator !() const { return (!Get()); }
- bool operator!=( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() != NULL); }
- bool operator==( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() == NULL); }
- bool operator==( const void *p ) const { return (Get() == p); }
- bool operator!=( const void *p ) const { return (Get() != p); }
- bool operator==( const T *p ) const { return operator==((void*)p); }
- bool operator!=( const T *p ) const { return operator!=((void*)p); }
-
- T * operator->() { return (T *)Get(); }
- T & operator *() { return *((T *)Get()); }
-
- const T * operator->() const { return (T *)Get(); }
- const T & operator *() const { return *((T *)Get()); }
-
- const T & operator[]( int i ) const { return *((T *)Get() + i); }
- T & operator[]( int i ) { return *((T *)Get() + i); }
-
- private:
- // Disallowed operations
- CThreadLocalPtr( T *pFrom );
- CThreadLocalPtr( const CThreadLocalPtr<T> &from );
- T **operator &();
- T * const *operator &() const;
- void operator=( const CThreadLocalPtr<T> &from );
- bool operator==( const CThreadLocalPtr<T> &p ) const;
- bool operator!=( const CThreadLocalPtr<T> &p ) const;
- };
-
-#endif // NO_THREAD_LOCAL
-#endif // !__AFXTLS_H__
-
-//-----------------------------------------------------------------------------
-//
-// A super-fast thread-safe integer A simple class encapsulating the notion of an
-// atomic integer used across threads that uses the built in and faster
-// "interlocked" functionality rather than a full-blown mutex. Useful for simple
-// things like reference counts, etc.
-//
-//-----------------------------------------------------------------------------
-
-template <typename T>
-class CInterlockedIntT
-{
-public:
- CInterlockedIntT() : m_value( 0 ) { COMPILE_TIME_ASSERT( sizeof(T) == sizeof(long) ); }
- CInterlockedIntT( T value ) : m_value( value ) {}
-
- T GetRaw() const { return m_value; }
-
- operator T() const { return m_value; }
-
- bool operator!() const { return ( m_value == 0 ); }
- bool operator==( T rhs ) const { return ( m_value == rhs ); }
- bool operator!=( T rhs ) const { return ( m_value != rhs ); }
-
- T operator++() { return (T)ThreadInterlockedIncrement( (long *)&m_value ); }
- T operator++(int) { return operator++() - 1; }
-
- T operator--() { return (T)ThreadInterlockedDecrement( (long *)&m_value ); }
- T operator--(int) { return operator--() + 1; }
-
- bool AssignIf( T conditionValue, T newValue ) { return ThreadInterlockedAssignIf( (long *)&m_value, (long)newValue, (long)conditionValue ); }
-
- T operator=( T newValue ) { ThreadInterlockedExchange((long *)&m_value, newValue); return m_value; }
-
- void operator+=( T add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, (long)add ); }
- void operator-=( T subtract ) { operator+=( -subtract ); }
- void operator*=( T multiplier ) {
- T original, result;
- do
- {
- original = m_value;
- result = original * multiplier;
- } while ( !AssignIf( original, result ) );
- }
- void operator/=( T divisor ) {
- T original, result;
- do
- {
- original = m_value;
- result = original / divisor;
- } while ( !AssignIf( original, result ) );
- }
-
- T operator+( T rhs ) const { return m_value + rhs; }
- T operator-( T rhs ) const { return m_value - rhs; }
-
-private:
- volatile T m_value;
-};
-
-typedef CInterlockedIntT<int> CInterlockedInt;
-typedef CInterlockedIntT<unsigned> CInterlockedUInt;
-
-//-----------------------------------------------------------------------------
-
-template <typename T>
-class CInterlockedPtr
-{
-public:
- CInterlockedPtr() : m_value( 0 ) {}
- CInterlockedPtr( T *value ) : m_value( value ) {}
-
- operator T *() const { return m_value; }
-
- bool operator!() const { return ( m_value == 0 ); }
- bool operator==( T *rhs ) const { return ( m_value == rhs ); }
- bool operator!=( T *rhs ) const { return ( m_value != rhs ); }
-
-#ifdef X64BITS
- T *operator++() { return ((T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) )) + 1; }
- T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) ); }
-
- T *operator--() { return ((T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, -sizeof(T) )) - 1; }
- T *operator--(int) { return (T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, -sizeof(T) ); }
-
- bool AssignIf( T *conditionValue, T *newValue ) { return ThreadInterlockedAssignPointerToConstIf( (void const **) &m_value, (void const *) newValue, (void const *) conditionValue ); }
-
- T *operator=( T *newValue ) { ThreadInterlockedExchangePointerToConst( (void const **) &m_value, (void const *) newValue ); return newValue; }
-
- void operator+=( int add ) { ThreadInterlockedExchangeAdd64( (int64 *)&m_value, add * sizeof(T) ); }
-#else
- T *operator++() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) )) + 1; }
- T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) ); }
-
- T *operator--() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) )) - 1; }
- T *operator--(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) ); }
-
- bool AssignIf( T *conditionValue, T *newValue ) { return ThreadInterlockedAssignPointerToConstIf( (void const **) &m_value, (void const *) newValue, (void const *) conditionValue ); }
-
- T *operator=( T *newValue ) { ThreadInterlockedExchangePointerToConst( (void const **) &m_value, (void const *) newValue ); return newValue; }
-
- void operator+=( int add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, add * sizeof(T) ); }
-#endif
-
- void operator-=( int subtract ) { operator+=( -subtract ); }
-
- T *operator+( int rhs ) const { return m_value + rhs; }
- T *operator-( int rhs ) const { return m_value - rhs; }
- T *operator+( unsigned rhs ) const { return m_value + rhs; }
- T *operator-( unsigned rhs ) const { return m_value - rhs; }
- size_t operator-( T *p ) const { return m_value - p; }
- size_t operator-( const CInterlockedPtr<T> &p ) const { return m_value - p.m_value; }
-
-private:
- T * volatile m_value;
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// Platform independent for critical sections management
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThreadMutex
-{
-public:
- CThreadMutex();
- ~CThreadMutex();
-
- //------------------------------------------------------
- // Mutex acquisition/release. Const intentionally defeated.
- //------------------------------------------------------
- void Lock();
- void Lock() const { (const_cast<CThreadMutex *>(this))->Lock(); }
- void Unlock();
- void Unlock() const { (const_cast<CThreadMutex *>(this))->Unlock(); }
-
- bool TryLock();
- bool TryLock() const { return (const_cast<CThreadMutex *>(this))->TryLock(); }
-
- //------------------------------------------------------
- // Use this to make deadlocks easier to track by asserting
- // when it is expected that the current thread owns the mutex
- //------------------------------------------------------
- bool AssertOwnedByCurrentThread();
-
- //------------------------------------------------------
- // Enable tracing to track deadlock problems
- //------------------------------------------------------
- void SetTrace( bool );
-
-private:
- // Disallow copying
- CThreadMutex( const CThreadMutex & );
- CThreadMutex &operator=( const CThreadMutex & );
-
-#if defined( _WIN32 )
- // Efficient solution to breaking the windows.h dependency, invariant is tested.
-#ifdef _WIN64
- #define TT_SIZEOF_CRITICALSECTION 40
-#else
-#ifndef _X360
- #define TT_SIZEOF_CRITICALSECTION 24
-#else
- #define TT_SIZEOF_CRITICALSECTION 28
-#endif // !_XBOX
-#endif // _WIN64
- byte m_CriticalSection[TT_SIZEOF_CRITICALSECTION];
-#elif defined(POSIX)
- pthread_mutex_t m_Mutex;
- pthread_mutexattr_t m_Attr;
-#else
-#error
-#endif
-
-#ifdef THREAD_MUTEX_TRACING_SUPPORTED
- // Debugging (always here to allow mixed debug/release builds w/o changing size)
- uint m_currentOwnerID;
- uint16 m_lockCount;
- bool m_bTrace;
-#endif
-};
-
-//-----------------------------------------------------------------------------
-//
-// An alternative mutex that is useful for cases when thread contention is
-// rare, but a mutex is required. Instances should be declared volatile.
-// Sleep of 0 may not be sufficient to keep high priority threads from starving
-// lesser threads. This class is not a suitable replacement for a critical
-// section if the resource contention is high.
-//
-//-----------------------------------------------------------------------------
-
-#if !defined(THREAD_PROFILER)
-
-class CThreadFastMutex
-{
-public:
- CThreadFastMutex()
- : m_ownerID( 0 ),
- m_depth( 0 )
- {
- }
-
-private:
- FORCEINLINE bool TryLockInline( const uint32 threadId ) volatile
- {
- if ( threadId != m_ownerID && !ThreadInterlockedAssignIf( (volatile long *)&m_ownerID, (long)threadId, 0 ) )
- return false;
-
- ThreadMemoryBarrier();
- ++m_depth;
- return true;
- }
-
- bool TryLock( const uint32 threadId ) volatile
- {
- return TryLockInline( threadId );
- }
-
- PLATFORM_CLASS void Lock( const uint32 threadId, unsigned nSpinSleepTime ) volatile;
-
-public:
- bool TryLock() volatile
- {
-#ifdef _DEBUG
- if ( m_depth == INT_MAX )
- DebuggerBreak();
-
- if ( m_depth < 0 )
- DebuggerBreak();
-#endif
- return TryLockInline( ThreadGetCurrentId() );
- }
-
-#ifndef _DEBUG
- FORCEINLINE
-#endif
- void Lock( unsigned int nSpinSleepTime = 0 ) volatile
- {
- const uint32 threadId = ThreadGetCurrentId();
-
- if ( !TryLockInline( threadId ) )
- {
- ThreadPause();
- Lock( threadId, nSpinSleepTime );
- }
-#ifdef _DEBUG
- if ( m_ownerID != ThreadGetCurrentId() )
- DebuggerBreak();
-
- if ( m_depth == INT_MAX )
- DebuggerBreak();
-
- if ( m_depth < 0 )
- DebuggerBreak();
-#endif
- }
-
-#ifndef _DEBUG
- FORCEINLINE
-#endif
- void Unlock() volatile
- {
-#ifdef _DEBUG
- if ( m_ownerID != ThreadGetCurrentId() )
- DebuggerBreak();
-
- if ( m_depth <= 0 )
- DebuggerBreak();
-#endif
-
- --m_depth;
- if ( !m_depth )
- {
- ThreadMemoryBarrier();
- ThreadInterlockedExchange( &m_ownerID, 0 );
- }
- }
-
-#ifdef WIN32
- bool TryLock() const volatile { return (const_cast<CThreadFastMutex *>(this))->TryLock(); }
- void Lock(unsigned nSpinSleepTime = 1 ) const volatile { (const_cast<CThreadFastMutex *>(this))->Lock( nSpinSleepTime ); }
- void Unlock() const volatile { (const_cast<CThreadFastMutex *>(this))->Unlock(); }
-#endif
- // To match regular CThreadMutex:
- bool AssertOwnedByCurrentThread() { return true; }
- void SetTrace( bool ) {}
-
- uint32 GetOwnerId() const { return m_ownerID; }
- int GetDepth() const { return m_depth; }
-private:
- volatile uint32 m_ownerID;
- int m_depth;
-};
-
-class ALIGN128 CAlignedThreadFastMutex : public CThreadFastMutex
-{
-public:
- CAlignedThreadFastMutex()
- {
- Assert( (size_t)this % 128 == 0 && sizeof(*this) == 128 );
- }
-
-private:
- uint8 pad[128-sizeof(CThreadFastMutex)];
-} ALIGN128_POST;
-
-#else
-typedef CThreadMutex CThreadFastMutex;
-#endif
-
-//-----------------------------------------------------------------------------
-//
-//-----------------------------------------------------------------------------
-
-class CThreadNullMutex
-{
-public:
- static void Lock() {}
- static void Unlock() {}
-
- static bool TryLock() { return true; }
- static bool AssertOwnedByCurrentThread() { return true; }
- static void SetTrace( bool b ) {}
-
- static uint32 GetOwnerId() { return 0; }
- static int GetDepth() { return 0; }
-};
-
-//-----------------------------------------------------------------------------
-//
-// A mutex decorator class used to control the use of a mutex, to make it
-// less expensive when not multithreading
-//
-//-----------------------------------------------------------------------------
-
-template <class BaseClass, bool *pCondition>
-class CThreadConditionalMutex : public BaseClass
-{
-public:
- void Lock() { if ( *pCondition ) BaseClass::Lock(); }
- void Lock() const { if ( *pCondition ) BaseClass::Lock(); }
- void Unlock() { if ( *pCondition ) BaseClass::Unlock(); }
- void Unlock() const { if ( *pCondition ) BaseClass::Unlock(); }
-
- bool TryLock() { if ( *pCondition ) return BaseClass::TryLock(); else return true; }
- bool TryLock() const { if ( *pCondition ) return BaseClass::TryLock(); else return true; }
- bool AssertOwnedByCurrentThread() { if ( *pCondition ) return BaseClass::AssertOwnedByCurrentThread(); else return true; }
- void SetTrace( bool b ) { if ( *pCondition ) BaseClass::SetTrace( b ); }
-};
-
-//-----------------------------------------------------------------------------
-// Mutex decorator that blows up if another thread enters
-//-----------------------------------------------------------------------------
-
-template <class BaseClass>
-class CThreadTerminalMutex : public BaseClass
-{
-public:
- bool TryLock() { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; }
- bool TryLock() const { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; }
- void Lock() { if ( !TryLock() ) BaseClass::Lock(); }
- void Lock() const { if ( !TryLock() ) BaseClass::Lock(); }
-
-};
-
-//-----------------------------------------------------------------------------
-//
-// Class to Lock a critical section, and unlock it automatically
-// when the lock goes out of scope
-//
-//-----------------------------------------------------------------------------
-
-template <class MUTEX_TYPE = CThreadMutex>
-class CAutoLockT
-{
-public:
- FORCEINLINE CAutoLockT( MUTEX_TYPE &lock)
- : m_lock(lock)
- {
- m_lock.Lock();
- }
-
- FORCEINLINE CAutoLockT(const MUTEX_TYPE &lock)
- : m_lock(const_cast<MUTEX_TYPE &>(lock))
- {
- m_lock.Lock();
- }
-
- FORCEINLINE ~CAutoLockT()
- {
- m_lock.Unlock();
- }
-
-
-private:
- MUTEX_TYPE &m_lock;
-
- // Disallow copying
- CAutoLockT<MUTEX_TYPE>( const CAutoLockT<MUTEX_TYPE> & );
- CAutoLockT<MUTEX_TYPE> &operator=( const CAutoLockT<MUTEX_TYPE> & );
-};
-
-typedef CAutoLockT<CThreadMutex> CAutoLock;
-
-//---------------------------------------------------------
-
-template <int size> struct CAutoLockTypeDeducer {};
-template <> struct CAutoLockTypeDeducer<sizeof(CThreadMutex)> { typedef CThreadMutex Type_t; };
-template <> struct CAutoLockTypeDeducer<sizeof(CThreadNullMutex)> { typedef CThreadNullMutex Type_t; };
-#if !defined(THREAD_PROFILER)
-template <> struct CAutoLockTypeDeducer<sizeof(CThreadFastMutex)> { typedef CThreadFastMutex Type_t; };
-template <> struct CAutoLockTypeDeducer<sizeof(CAlignedThreadFastMutex)> { typedef CAlignedThreadFastMutex Type_t; };
-#endif
-
-#define AUTO_LOCK_( type, mutex ) \
- CAutoLockT< type > UNIQUE_ID( static_cast<const type &>( mutex ) )
-
-#if defined(GNUC)
-
-template<typename T> T strip_cv_quals_for_mutex(T&);
-template<typename T> T strip_cv_quals_for_mutex(const T&);
-template<typename T> T strip_cv_quals_for_mutex(volatile T&);
-template<typename T> T strip_cv_quals_for_mutex(const volatile T&);
-
-#define AUTO_LOCK( mutex ) \
- AUTO_LOCK_( typeof(::strip_cv_quals_for_mutex(mutex)), mutex )
-
-#else // GNUC
-
-#define AUTO_LOCK( mutex ) \
- AUTO_LOCK_( CAutoLockTypeDeducer<sizeof(mutex)>::Type_t, mutex )
-
-#endif
-
-#define AUTO_LOCK_FM( mutex ) \
- AUTO_LOCK_( CThreadFastMutex, mutex )
-
-#define LOCAL_THREAD_LOCK_( tag ) \
- ; \
- static CThreadFastMutex autoMutex_##tag; \
- AUTO_LOCK( autoMutex_##tag )
-
-#define LOCAL_THREAD_LOCK() \
- LOCAL_THREAD_LOCK_(_)
-
-//-----------------------------------------------------------------------------
-//
-// Base class for event, semaphore and mutex objects.
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThreadSyncObject
-{
-public:
- ~CThreadSyncObject();
-
- //-----------------------------------------------------
- // Query if object is useful
- //-----------------------------------------------------
- bool operator!() const;
-
- //-----------------------------------------------------
- // Access handle
- //-----------------------------------------------------
-#ifdef _WIN32
- operator HANDLE() { return GetHandle(); }
- const HANDLE GetHandle() const { return m_hSyncObject; }
-#endif
- //-----------------------------------------------------
- // Wait for a signal from the object
- //-----------------------------------------------------
- bool Wait( uint32 dwTimeout = TT_INFINITE );
-
-protected:
- CThreadSyncObject();
- void AssertUseable();
-
-#ifdef _WIN32
- HANDLE m_hSyncObject;
- bool m_bCreatedHandle;
-#elif defined(POSIX)
- pthread_mutex_t m_Mutex;
- pthread_cond_t m_Condition;
- bool m_bInitalized;
- int m_cSet;
- bool m_bManualReset;
- bool m_bWakeForEvent;
-#else
-#error "Implement me"
-#endif
-
-private:
- CThreadSyncObject( const CThreadSyncObject & );
- CThreadSyncObject &operator=( const CThreadSyncObject & );
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// Wrapper for unnamed event objects
-//
-//-----------------------------------------------------------------------------
-
-#if defined( _WIN32 )
-
-//-----------------------------------------------------------------------------
-//
-// CThreadSemaphore
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThreadSemaphore : public CThreadSyncObject
-{
-public:
- CThreadSemaphore(long initialValue, long maxValue);
-
- //-----------------------------------------------------
- // Increases the count of the semaphore object by a specified
- // amount. Wait() decreases the count by one on return.
- //-----------------------------------------------------
- bool Release(long releaseCount = 1, long * pPreviousCount = NULL );
-
-private:
- CThreadSemaphore(const CThreadSemaphore &);
- CThreadSemaphore &operator=(const CThreadSemaphore &);
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// A mutex suitable for out-of-process, multi-processor usage
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThreadFullMutex : public CThreadSyncObject
-{
-public:
- CThreadFullMutex( bool bEstablishInitialOwnership = false, const char * pszName = NULL );
-
- //-----------------------------------------------------
- // Release ownership of the mutex
- //-----------------------------------------------------
- bool Release();
-
- // To match regular CThreadMutex:
- void Lock() { Wait(); }
- void Lock( unsigned timeout ) { Wait( timeout ); }
- void Unlock() { Release(); }
- bool AssertOwnedByCurrentThread() { return true; }
- void SetTrace( bool ) {}
-
-private:
- CThreadFullMutex( const CThreadFullMutex & );
- CThreadFullMutex &operator=( const CThreadFullMutex & );
-};
-#endif
-
-
-class PLATFORM_CLASS CThreadEvent : public CThreadSyncObject
-{
-public:
- CThreadEvent( bool fManualReset = false );
-#ifdef WIN32
- CThreadEvent( HANDLE hHandle );
-#endif
- //-----------------------------------------------------
- // Set the state to signaled
- //-----------------------------------------------------
- bool Set();
-
- //-----------------------------------------------------
- // Set the state to nonsignaled
- //-----------------------------------------------------
- bool Reset();
-
- //-----------------------------------------------------
- // Check if the event is signaled
- //-----------------------------------------------------
- bool Check();
-
- bool Wait( uint32 dwTimeout = TT_INFINITE );
-
-private:
- CThreadEvent( const CThreadEvent & );
- CThreadEvent &operator=( const CThreadEvent & );
-};
-
-// Hard-wired manual event for use in array declarations
-class CThreadManualEvent : public CThreadEvent
-{
-public:
- CThreadManualEvent()
- : CThreadEvent( true )
- {
- }
-};
-
-inline int ThreadWaitForEvents( int nEvents, CThreadEvent * const *pEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE )
-{
-#ifdef POSIX
- Assert( nEvents == 1);
- if ( pEvents[0]->Wait( timeout ) )
- return WAIT_OBJECT_0;
- else
- return WAIT_TIMEOUT;
-#else
- HANDLE handles[64];
- for ( unsigned int i = 0; i < min( nEvents, ARRAYSIZE(handles) ); i++ )
- handles[i] = pEvents[i]->GetHandle();
- return ThreadWaitForObjects( nEvents, handles, bWaitAll, timeout );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-//
-// CThreadRWLock
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThreadRWLock
-{
-public:
- CThreadRWLock();
-
- void LockForRead();
- void UnlockRead();
- void LockForWrite();
- void UnlockWrite();
-
- void LockForRead() const { const_cast<CThreadRWLock *>(this)->LockForRead(); }
- void UnlockRead() const { const_cast<CThreadRWLock *>(this)->UnlockRead(); }
- void LockForWrite() const { const_cast<CThreadRWLock *>(this)->LockForWrite(); }
- void UnlockWrite() const { const_cast<CThreadRWLock *>(this)->UnlockWrite(); }
-
-private:
- void WaitForRead();
-
-#ifdef WIN32
- CThreadFastMutex m_mutex;
-#else
- CThreadMutex m_mutex;
-#endif
- CThreadEvent m_CanWrite;
- CThreadEvent m_CanRead;
-
- int m_nWriters;
- int m_nActiveReaders;
- int m_nPendingReaders;
-};
-
-//-----------------------------------------------------------------------------
-//
-// CThreadSpinRWLock
-//
-//-----------------------------------------------------------------------------
-
-class ALIGN8 PLATFORM_CLASS CThreadSpinRWLock
-{
-public:
- CThreadSpinRWLock() { COMPILE_TIME_ASSERT( sizeof( LockInfo_t ) == sizeof( int64 ) ); Assert( (intp)this % 8 == 0 ); memset( this, 0, sizeof( *this ) ); }
-
- bool TryLockForWrite();
- bool TryLockForRead();
-
- void LockForRead();
- void UnlockRead();
- void LockForWrite();
- void UnlockWrite();
-
- bool TryLockForWrite() const { return const_cast<CThreadSpinRWLock *>(this)->TryLockForWrite(); }
- bool TryLockForRead() const { return const_cast<CThreadSpinRWLock *>(this)->TryLockForRead(); }
- void LockForRead() const { const_cast<CThreadSpinRWLock *>(this)->LockForRead(); }
- void UnlockRead() const { const_cast<CThreadSpinRWLock *>(this)->UnlockRead(); }
- void LockForWrite() const { const_cast<CThreadSpinRWLock *>(this)->LockForWrite(); }
- void UnlockWrite() const { const_cast<CThreadSpinRWLock *>(this)->UnlockWrite(); }
-
-private:
- struct LockInfo_t
- {
- uint32 m_writerId;
- int m_nReaders;
- };
-
- bool AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand );
- bool TryLockForWrite( const uint32 threadId );
- void SpinLockForWrite( const uint32 threadId );
-
- volatile LockInfo_t m_lockInfo;
- CInterlockedInt m_nWriters;
-} ALIGN8_POST;
-
-//-----------------------------------------------------------------------------
-//
-// A thread wrapper similar to a Java thread.
-//
-//-----------------------------------------------------------------------------
-
-class PLATFORM_CLASS CThread
-{
-public:
- CThread();
- virtual ~CThread();
-
- //-----------------------------------------------------
-
- const char *GetName();
- void SetName( const char * );
-
- size_t CalcStackDepth( void *pStackVariable ) { return ((byte *)m_pStackBase - (byte *)pStackVariable); }
-
- //-----------------------------------------------------
- // Functions for the other threads
- //-----------------------------------------------------
-
- // Start thread running - error if already running
- virtual bool Start( unsigned nBytesStack = 0 );
-
- // Returns true if thread has been created and hasn't yet exited
- bool IsAlive();
-
- // This method causes the current thread to wait until this thread
- // is no longer alive.
- bool Join( unsigned timeout = TT_INFINITE );
-
-#ifdef _WIN32
- // Access the thread handle directly
- HANDLE GetThreadHandle();
- uint GetThreadId();
-#elif defined( LINUX )
- uint GetThreadId();
-#endif
-
- //-----------------------------------------------------
-
- int GetResult();
-
- //-----------------------------------------------------
- // Functions for both this, and maybe, and other threads
- //-----------------------------------------------------
-
- // Forcibly, abnormally, but relatively cleanly stop the thread
- void Stop( int exitCode = 0 );
-
- // Get the priority
- int GetPriority() const;
-
- // Set the priority
- bool SetPriority( int );
-
- // Request a thread to suspend, this must ONLY be called from the thread itself, not the main thread
- // This suspend variant causes the thread in question to suspend at a known point in its execution
- // which means you don't risk the global deadlocks/hangs potentially caused by the raw Suspend() call
- void SuspendCooperative();
-
- // Resume a previously suspended thread from the Cooperative call
- void ResumeCooperative();
-
- // wait for a thread to execute its SuspendCooperative call
- void BWaitForThreadSuspendCooperative();
-
-#ifndef LINUX
- // forcefully Suspend a thread
- unsigned int Suspend();
-
- // forcefully Resume a previously suspended thread
- unsigned int Resume();
-#endif
-
- // Force hard-termination of thread. Used for critical failures.
- bool Terminate( int exitCode = 0 );
-
- //-----------------------------------------------------
- // Global methods
- //-----------------------------------------------------
-
- // Get the Thread object that represents the current thread, if any.
- // Can return NULL if the current thread was not created using
- // CThread
- static CThread *GetCurrentCThread();
-
- // Offer a context switch. Under Win32, equivalent to Sleep(0)
-#ifdef Yield
-#undef Yield
-#endif
- static void Yield();
-
- // This method causes the current thread to yield and not to be
- // scheduled for further execution until a certain amount of real
- // time has elapsed, more or less.
- static void Sleep( unsigned duration );
-
-protected:
-
- // Optional pre-run call, with ability to fail-create. Note Init()
- // is forced synchronous with Start()
- virtual bool Init();
-
- // Thread will run this function on startup, must be supplied by
- // derived class, performs the intended action of the thread.
- virtual int Run() = 0;
-
- // Called when the thread is about to exit, by the about-to-exit thread.
- virtual void OnExit();
-
- // Called after OnExit when a thread finishes or is killed. Not virtual because no inherited classes
- // override it and we don't want to change the vtable from the published SDK version.
- void Cleanup();
-
- bool WaitForCreateComplete( CThreadEvent *pEvent );
-
- // "Virtual static" facility
- typedef unsigned (__stdcall *ThreadProc_t)( void * );
- virtual ThreadProc_t GetThreadProc();
- virtual bool IsThreadRunning();
-
- CThreadMutex m_Lock;
-
-#ifdef WIN32
- const ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; }
-#else
- const ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; }
-#endif
-
-private:
- enum Flags
- {
- SUPPORT_STOP_PROTOCOL = 1 << 0
- };
-
- // Thread initially runs this. param is actually 'this'. function
- // just gets this and calls ThreadProc
- struct ThreadInit_t
- {
- CThread * pThread;
- CThreadEvent *pInitCompleteEvent;
- bool * pfInitSuccess;
- };
-
- static unsigned __stdcall ThreadProc( void * pv );
-
- // make copy constructor and assignment operator inaccessible
- CThread( const CThread & );
- CThread &operator=( const CThread & );
-
-#ifdef _WIN32
- HANDLE m_hThread;
- ThreadId_t m_threadId;
-#elif defined(POSIX)
- pthread_t m_threadId;
-#endif
- CInterlockedInt m_nSuspendCount;
- CThreadEvent m_SuspendEvent;
- CThreadEvent m_SuspendEventSignal;
- int m_result;
- char m_szName[32];
- void * m_pStackBase;
- unsigned m_flags;
-};
-
-//-----------------------------------------------------------------------------
-//
-// A helper class to let you sleep a thread for memory validation, you need to handle
-// m_bSleepForValidate in your ::Run() call and set m_bSleepingForValidate when sleeping
-//
-//-----------------------------------------------------------------------------
-class PLATFORM_CLASS CValidatableThread : public CThread
-{
-public:
- CValidatableThread()
- {
- m_bSleepForValidate = false;
- m_bSleepingForValidate = false;
- }
-
-#ifdef DBGFLAG_VALIDATE
- virtual void SleepForValidate() { m_bSleepForValidate = true; }
- bool BSleepingForValidate() { return m_bSleepingForValidate; }
- virtual void WakeFromValidate() { m_bSleepForValidate = false; }
-#endif
-protected:
- bool m_bSleepForValidate;
- bool m_bSleepingForValidate;
-};
-
-//-----------------------------------------------------------------------------
-// Simple thread class encompasses the notion of a worker thread, handing
-// synchronized communication.
-//-----------------------------------------------------------------------------
-
-
-// These are internal reserved error results from a call attempt
-enum WTCallResult_t
-{
- WTCR_FAIL = -1,
- WTCR_TIMEOUT = -2,
- WTCR_THREAD_GONE = -3,
-};
-
-class CFunctor;
-class PLATFORM_CLASS CWorkerThread : public CThread
-{
-public:
- CWorkerThread();
-
- //-----------------------------------------------------
- //
- // Inter-thread communication
- //
- // Calls in either direction take place on the same "channel."
- // Seperate functions are specified to make identities obvious
- //
- //-----------------------------------------------------
-
- // Master: Signal the thread, and block for a response
- int CallWorker( unsigned, unsigned timeout = TT_INFINITE, bool fBoostWorkerPriorityToMaster = true, CFunctor *pParamFunctor = NULL );
-
- // Worker: Signal the thread, and block for a response
- int CallMaster( unsigned, unsigned timeout = TT_INFINITE );
-
- // Wait for the next request
- bool WaitForCall( unsigned dwTimeout, unsigned *pResult = NULL );
- bool WaitForCall( unsigned *pResult = NULL );
-
- // Is there a request?
- bool PeekCall( unsigned *pParam = NULL, CFunctor **ppParamFunctor = NULL );
-
- // Reply to the request
- void Reply( unsigned );
-
- // Wait for a reply in the case when CallWorker() with timeout != TT_INFINITE
- int WaitForReply( unsigned timeout = TT_INFINITE );
-
- // If you want to do WaitForMultipleObjects you'll need to include
- // this handle in your wait list or you won't be responsive
- CThreadEvent &GetCallHandle();
- // Find out what the request was
- unsigned GetCallParam( CFunctor **ppParamFunctor = NULL ) const;
-
- // Boost the worker thread to the master thread, if worker thread is lesser, return old priority
- int BoostPriority();
-
-protected:
-#ifndef _WIN32
-#define __stdcall
-#endif
- typedef uint32 (__stdcall *WaitFunc_t)( int nEvents, CThreadEvent * const *pEvents, int bWaitAll, uint32 timeout );
-
- int Call( unsigned, unsigned timeout, bool fBoost, WaitFunc_t = NULL, CFunctor *pParamFunctor = NULL );
- int WaitForReply( unsigned timeout, WaitFunc_t );
-
-private:
- CWorkerThread( const CWorkerThread & );
- CWorkerThread &operator=( const CWorkerThread & );
-
- CThreadEvent m_EventSend;
- CThreadEvent m_EventComplete;
-
- unsigned m_Param;
- CFunctor *m_pParamFunctor;
- int m_ReturnVal;
-};
-
-
-// a unidirectional message queue. A queue of type T. Not especially high speed since each message
-// is malloced/freed. Note that if your message class has destructors/constructors, they MUST be
-// thread safe!
-template<class T> class CMessageQueue
-{
- CThreadEvent SignalEvent; // signals presence of data
- CThreadMutex QueueAccessMutex;
-
- // the parts protected by the mutex
- struct MsgNode
- {
- MsgNode *Next;
- T Data;
- };
-
- MsgNode *Head;
- MsgNode *Tail;
-
-public:
- CMessageQueue( void )
- {
- Head = Tail = NULL;
- }
-
- // check for a message. not 100% reliable - someone could grab the message first
- bool MessageWaiting( void )
- {
- return ( Head != NULL );
- }
-
- void WaitMessage( T *pMsg )
- {
- for(;;)
- {
- while( ! MessageWaiting() )
- SignalEvent.Wait();
- QueueAccessMutex.Lock();
- if (! Head )
- {
- // multiple readers could make this null
- QueueAccessMutex.Unlock();
- continue;
- }
- *( pMsg ) = Head->Data;
- MsgNode *remove_this = Head;
- Head = Head->Next;
- if (! Head) // if empty, fix tail ptr
- Tail = NULL;
- QueueAccessMutex.Unlock();
- delete remove_this;
- break;
- }
- }
-
- void QueueMessage( T const &Msg)
- {
- MsgNode *new1=new MsgNode;
- new1->Data=Msg;
- new1->Next=NULL;
- QueueAccessMutex.Lock();
- if ( Tail )
- {
- Tail->Next=new1;
- Tail = new1;
- }
- else
- {
- Head = new1;
- Tail = new1;
- }
- SignalEvent.Set();
- QueueAccessMutex.Unlock();
- }
-};
-
-
-//-----------------------------------------------------------------------------
-//
-// CThreadMutex. Inlining to reduce overhead and to allow client code
-// to decide debug status (tracing)
-//
-//-----------------------------------------------------------------------------
-
-#ifdef _WIN32
-typedef struct _RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION;
-typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
-
-#ifndef _X360
-extern "C"
-{
- void __declspec(dllimport) __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
- void __declspec(dllimport) __stdcall EnterCriticalSection(CRITICAL_SECTION *);
- void __declspec(dllimport) __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
- void __declspec(dllimport) __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
-};
-#endif
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::Lock()
-{
-#ifdef THREAD_MUTEX_TRACING_ENABLED
- uint thisThreadID = ThreadGetCurrentId();
- if ( m_bTrace && m_currentOwnerID && ( m_currentOwnerID != thisThreadID ) )
- Msg( "Thread %u about to wait for lock %p owned by %u\n", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID );
- #endif
-
- VCRHook_EnterCriticalSection((CRITICAL_SECTION *)&m_CriticalSection);
-
- #ifdef THREAD_MUTEX_TRACING_ENABLED
- if (m_lockCount == 0)
- {
- // we now own it for the first time. Set owner information
- m_currentOwnerID = thisThreadID;
- if ( m_bTrace )
- Msg( "Thread %u now owns lock %p\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection );
- }
- m_lockCount++;
- #endif
-}
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::Unlock()
-{
- #ifdef THREAD_MUTEX_TRACING_ENABLED
- AssertMsg( m_lockCount >= 1, "Invalid unlock of thread lock" );
- m_lockCount--;
- if (m_lockCount == 0)
- {
- if ( m_bTrace )
- Msg( "Thread %u releasing lock %p\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection );
- m_currentOwnerID = 0;
- }
- #endif
- LeaveCriticalSection((CRITICAL_SECTION *)&m_CriticalSection);
-}
-
-//---------------------------------------------------------
-
-inline bool CThreadMutex::AssertOwnedByCurrentThread()
-{
-#ifdef THREAD_MUTEX_TRACING_ENABLED
- if (ThreadGetCurrentId() == m_currentOwnerID)
- return true;
- AssertMsg3( 0, "Expected thread %u as owner of lock %p, but %u owns", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID );
- return false;
-#else
- return true;
-#endif
-}
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::SetTrace( bool bTrace )
-{
-#ifdef THREAD_MUTEX_TRACING_ENABLED
- m_bTrace = bTrace;
-#endif
-}
-
-//---------------------------------------------------------
-
-#elif defined(POSIX)
-
-inline CThreadMutex::CThreadMutex()
-{
- // enable recursive locks as we need them
- pthread_mutexattr_init( &m_Attr );
- pthread_mutexattr_settype( &m_Attr, PTHREAD_MUTEX_RECURSIVE );
- pthread_mutex_init( &m_Mutex, &m_Attr );
-}
-
-//---------------------------------------------------------
-
-inline CThreadMutex::~CThreadMutex()
-{
- pthread_mutex_destroy( &m_Mutex );
-}
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::Lock()
-{
- pthread_mutex_lock( &m_Mutex );
-}
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::Unlock()
-{
- pthread_mutex_unlock( &m_Mutex );
-}
-
-//---------------------------------------------------------
-
-inline bool CThreadMutex::AssertOwnedByCurrentThread()
-{
- return true;
-}
-
-//---------------------------------------------------------
-
-inline void CThreadMutex::SetTrace(bool fTrace)
-{
-}
-
-#endif // POSIX
-
-//-----------------------------------------------------------------------------
-//
-// CThreadRWLock inline functions
-//
-//-----------------------------------------------------------------------------
-
-inline CThreadRWLock::CThreadRWLock()
-: m_CanRead( true ),
- m_nWriters( 0 ),
- m_nActiveReaders( 0 ),
- m_nPendingReaders( 0 )
-{
-}
-
-inline void CThreadRWLock::LockForRead()
-{
- m_mutex.Lock();
- if ( m_nWriters)
- {
- WaitForRead();
- }
- m_nActiveReaders++;
- m_mutex.Unlock();
-}
-
-inline void CThreadRWLock::UnlockRead()
-{
- m_mutex.Lock();
- m_nActiveReaders--;
- if ( m_nActiveReaders == 0 && m_nWriters != 0 )
- {
- m_CanWrite.Set();
- }
- m_mutex.Unlock();
-}
-
-
-//-----------------------------------------------------------------------------
-//
-// CThreadSpinRWLock inline functions
-//
-//-----------------------------------------------------------------------------
-
-inline bool CThreadSpinRWLock::AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand )
-{
- return ThreadInterlockedAssignIf64( (int64 *)&m_lockInfo, *((int64 *)&newValue), *((int64 *)&comperand) );
-}
-
-inline bool CThreadSpinRWLock::TryLockForWrite( const uint32 threadId )
-{
- // In order to grab a write lock, there can be no readers and no owners of the write lock
- if ( m_lockInfo.m_nReaders > 0 || ( m_lockInfo.m_writerId && m_lockInfo.m_writerId != threadId ) )
- {
- return false;
- }
-
- static const LockInfo_t oldValue = { 0, 0 };
- LockInfo_t newValue = { threadId, 0 };
- const bool bSuccess = AssignIf( newValue, oldValue );
-#if defined(_X360)
- if ( bSuccess )
- {
- // X360TBD: Serious perf implications. Not Yet. __sync();
- }
-#endif
- return bSuccess;
-}
-
-inline bool CThreadSpinRWLock::TryLockForWrite()
-{
- m_nWriters++;
- if ( !TryLockForWrite( ThreadGetCurrentId() ) )
- {
- m_nWriters--;
- return false;
- }
- return true;
-}
-
-inline bool CThreadSpinRWLock::TryLockForRead()
-{
- if ( m_nWriters != 0 )
- {
- return false;
- }
- // In order to grab a write lock, the number of readers must not change and no thread can own the write
- LockInfo_t oldValue;
- LockInfo_t newValue;
-
- oldValue.m_nReaders = m_lockInfo.m_nReaders;
- oldValue.m_writerId = 0;
- newValue.m_nReaders = oldValue.m_nReaders + 1;
- newValue.m_writerId = 0;
-
- const bool bSuccess = AssignIf( newValue, oldValue );
-#if defined(_X360)
- if ( bSuccess )
- {
- // X360TBD: Serious perf implications. Not Yet. __sync();
- }
-#endif
- return bSuccess;
-}
-
-inline void CThreadSpinRWLock::LockForWrite()
-{
- const uint32 threadId = ThreadGetCurrentId();
-
- m_nWriters++;
-
- if ( !TryLockForWrite( threadId ) )
- {
- ThreadPause();
- SpinLockForWrite( threadId );
- }
-}
-
-// read data from a memory address
-template<class T> FORCEINLINE T ReadVolatileMemory( T const *pPtr )
-{
- volatile const T * pVolatilePtr = ( volatile const T * ) pPtr;
- return *pVolatilePtr;
-}
-
-//-----------------------------------------------------------------------------
-
-#if defined( _WIN32 )
-#pragma warning(pop)
-#endif
-
-#endif // THREADTOOLS_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: A collection of utility classes to simplify thread handling, and
+// as much as possible contain portability problems. Here avoiding
+// including windows.h.
+//
+//=============================================================================
+
+#ifndef THREADTOOLS_H
+#define THREADTOOLS_H
+
+#include <limits.h>
+
+#include "tier0/platform.h"
+#include "tier0/dbg.h"
+#include "tier0/vcrmode.h"
+
+#ifdef PLATFORM_WINDOWS_PC
+#include <intrin.h>
+#endif
+
+#ifdef POSIX
+#include <pthread.h>
+#include <errno.h>
+#define WAIT_OBJECT_0 0
+#define WAIT_TIMEOUT 0x00000102
+#define WAIT_FAILED -1
+#define THREAD_PRIORITY_HIGHEST 2
+#endif
+
+#if defined( _WIN32 )
+#pragma once
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+// #define THREAD_PROFILER 1
+
+#ifndef _RETAIL
+#define THREAD_MUTEX_TRACING_SUPPORTED
+#if defined(_WIN32) && defined(_DEBUG)
+#define THREAD_MUTEX_TRACING_ENABLED
+#endif
+#endif
+
+#ifdef _WIN32
+typedef void *HANDLE;
+#endif
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+
+const unsigned TT_INFINITE = 0xffffffff;
+
+#ifndef NO_THREAD_LOCAL
+
+#ifndef THREAD_LOCAL
+#ifdef _WIN32
+#define THREAD_LOCAL __declspec(thread)
+#elif POSIX
+#define THREAD_LOCAL __thread
+#endif
+#endif
+
+#endif // NO_THREAD_LOCAL
+
+typedef unsigned long ThreadId_t;
+
+//-----------------------------------------------------------------------------
+//
+// Simple thread creation. Differs from VCR mode/CreateThread/_beginthreadex
+// in that it accepts a standard C function rather than compiler specific one.
+//
+//-----------------------------------------------------------------------------
+FORWARD_DECLARE_HANDLE( ThreadHandle_t );
+typedef unsigned (*ThreadFunc_t)( void *pParam );
+
+PLATFORM_OVERLOAD ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, ThreadId_t *pID, unsigned stackSize = 0 );
+PLATFORM_INTERFACE ThreadHandle_t CreateSimpleThread( ThreadFunc_t, void *pParam, unsigned stackSize = 0 );
+PLATFORM_INTERFACE bool ReleaseThreadHandle( ThreadHandle_t );
+
+
+//-----------------------------------------------------------------------------
+
+PLATFORM_INTERFACE void ThreadSleep(unsigned duration = 0);
+PLATFORM_INTERFACE uint ThreadGetCurrentId();
+PLATFORM_INTERFACE ThreadHandle_t ThreadGetCurrentHandle();
+PLATFORM_INTERFACE int ThreadGetPriority( ThreadHandle_t hThread = NULL );
+PLATFORM_INTERFACE bool ThreadSetPriority( ThreadHandle_t hThread, int priority );
+inline bool ThreadSetPriority( int priority ) { return ThreadSetPriority( NULL, priority ); }
+PLATFORM_INTERFACE bool ThreadInMainThread();
+PLATFORM_INTERFACE void DeclareCurrentThreadIsMainThread();
+
+// NOTE: ThreadedLoadLibraryFunc_t needs to return the sleep time in milliseconds or TT_INFINITE
+typedef int (*ThreadedLoadLibraryFunc_t)();
+PLATFORM_INTERFACE void SetThreadedLoadLibraryFunc( ThreadedLoadLibraryFunc_t func );
+PLATFORM_INTERFACE ThreadedLoadLibraryFunc_t GetThreadedLoadLibraryFunc();
+
+#if defined( _WIN32 ) && !defined( _WIN64 ) && !defined( _X360 )
+extern "C" unsigned long __declspec(dllimport) __stdcall GetCurrentThreadId();
+#define ThreadGetCurrentId GetCurrentThreadId
+#endif
+
+inline void ThreadPause()
+{
+#if defined( PLATFORM_WINDOWS_PC )
+ // Intrinsic for __asm pause; from <intrin.h>
+ _mm_pause();
+#elif POSIX
+ __asm __volatile( "pause" );
+#elif defined( _X360 )
+#else
+#error "implement me"
+#endif
+}
+
+PLATFORM_INTERFACE bool ThreadJoin( ThreadHandle_t, unsigned timeout = TT_INFINITE );
+// If you're not calling ThreadJoin, you need to call ThreadDetach so pthreads on Linux knows it can
+// free the memory for this thread. Otherwise you wind up leaking threads until you run out and
+// CreateSimpleThread() will fail.
+PLATFORM_INTERFACE void ThreadDetach( ThreadHandle_t );
+
+PLATFORM_INTERFACE void ThreadSetDebugName( ThreadId_t id, const char *pszName );
+inline void ThreadSetDebugName( const char *pszName ) { ThreadSetDebugName( (ThreadId_t)-1, pszName ); }
+
+PLATFORM_INTERFACE void ThreadSetAffinity( ThreadHandle_t hThread, int nAffinityMask );
+
+//-----------------------------------------------------------------------------
+
+enum ThreadWaitResult_t
+{
+ TW_FAILED = 0xffffffff, // WAIT_FAILED
+ TW_TIMEOUT = 0x00000102, // WAIT_TIMEOUT
+};
+
+#ifdef _WIN32
+PLATFORM_INTERFACE int ThreadWaitForObjects( int nEvents, const HANDLE *pHandles, bool bWaitAll = true, unsigned timeout = TT_INFINITE );
+inline int ThreadWaitForObject( HANDLE handle, bool bWaitAll = true, unsigned timeout = TT_INFINITE ) { return ThreadWaitForObjects( 1, &handle, bWaitAll, timeout ); }
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// Interlock methods. These perform very fast atomic thread
+// safe operations. These are especially relevant in a multi-core setting.
+//
+//-----------------------------------------------------------------------------
+
+#ifdef _WIN32
+#define NOINLINE
+#elif POSIX
+#define NOINLINE __attribute__ ((noinline))
+#endif
+
+// ThreadMemoryBarrier is a fence/barrier sufficient for most uses. It prevents reads
+// from moving past reads, and writes moving past writes. It is sufficient for
+// read-acquire and write-release barriers. It is not a full barrier and it does
+// not prevent reads from moving past writes -- that would require a full __sync()
+// on PPC and is significantly more expensive.
+#if defined( _X360 ) || defined( _PS3 )
+ #define ThreadMemoryBarrier() __lwsync()
+
+#elif defined(_MSC_VER)
+ // Prevent compiler reordering across this barrier. This is
+ // sufficient for most purposes on x86/x64.
+
+ #if _MSC_VER < 1500
+ // !KLUDGE! For VC 2005
+ // http://connect.microsoft.com/VisualStudio/feedback/details/100051
+ #pragma intrinsic(_ReadWriteBarrier)
+ #endif
+ #define ThreadMemoryBarrier() _ReadWriteBarrier()
+#elif defined(GNUC)
+ // Prevent compiler reordering across this barrier. This is
+ // sufficient for most purposes on x86/x64.
+ // http://preshing.com/20120625/memory-ordering-at-compile-time
+ #define ThreadMemoryBarrier() asm volatile("" ::: "memory")
+#else
+ #error Every platform needs to define ThreadMemoryBarrier to at least prevent compiler reordering
+#endif
+
+#if defined(_WIN32) && !defined(_X360)
+ #if ( _MSC_VER >= 1310 )
+ #define USE_INTRINSIC_INTERLOCKED
+ #endif
+#endif
+
+#ifdef USE_INTRINSIC_INTERLOCKED
+extern "C"
+{
+ long __cdecl _InterlockedIncrement(volatile long*);
+ long __cdecl _InterlockedDecrement(volatile long*);
+ long __cdecl _InterlockedExchange(volatile long*, long);
+ long __cdecl _InterlockedExchangeAdd(volatile long*, long);
+ long __cdecl _InterlockedCompareExchange(volatile long*, long, long);
+}
+
+#pragma intrinsic( _InterlockedCompareExchange )
+#pragma intrinsic( _InterlockedDecrement )
+#pragma intrinsic( _InterlockedExchange )
+#pragma intrinsic( _InterlockedExchangeAdd )
+#pragma intrinsic( _InterlockedIncrement )
+
+inline long ThreadInterlockedIncrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedIncrement( p ); }
+inline long ThreadInterlockedDecrement( long volatile *p ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedDecrement( p ); }
+inline long ThreadInterlockedExchange( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchange( p, value ); }
+inline long ThreadInterlockedExchangeAdd( long volatile *p, long value ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedExchangeAdd( p, value ); }
+inline long ThreadInterlockedCompareExchange( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return _InterlockedCompareExchange( p, value, comperand ); }
+inline bool ThreadInterlockedAssignIf( long volatile *p, long value, long comperand ) { Assert( (size_t)p % 4 == 0 ); return ( _InterlockedCompareExchange( p, value, comperand ) == comperand ); }
+#else
+PLATFORM_INTERFACE long ThreadInterlockedIncrement( long volatile * );
+PLATFORM_INTERFACE long ThreadInterlockedDecrement( long volatile * );
+PLATFORM_INTERFACE long ThreadInterlockedExchange( long volatile *, long value );
+PLATFORM_INTERFACE long ThreadInterlockedExchangeAdd( long volatile *, long value );
+PLATFORM_INTERFACE long ThreadInterlockedCompareExchange( long volatile *, long value, long comperand );
+PLATFORM_INTERFACE bool ThreadInterlockedAssignIf( long volatile *, long value, long comperand );
+#endif
+
+inline unsigned ThreadInterlockedExchangeSubtract( long volatile *p, long value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, -value ); }
+
+#if defined( USE_INTRINSIC_INTERLOCKED ) && !defined( _WIN64 )
+#define TIPTR()
+inline void *ThreadInterlockedExchangePointer( void * volatile *p, void *value ) { return (void *)_InterlockedExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value) ); }
+inline void *ThreadInterlockedCompareExchangePointer( void * volatile *p, void *value, void *comperand ) { return (void *)_InterlockedCompareExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value), reinterpret_cast<long>(comperand) ); }
+inline bool ThreadInterlockedAssignPointerIf( void * volatile *p, void *value, void *comperand ) { return ( _InterlockedCompareExchange( reinterpret_cast<long volatile *>(p), reinterpret_cast<long>(value), reinterpret_cast<long>(comperand) ) == reinterpret_cast<long>(comperand) ); }
+#else
+PLATFORM_INTERFACE void *ThreadInterlockedExchangePointer( void * volatile *, void *value ) NOINLINE;
+PLATFORM_INTERFACE void *ThreadInterlockedCompareExchangePointer( void * volatile *, void *value, void *comperand ) NOINLINE;
+PLATFORM_INTERFACE bool ThreadInterlockedAssignPointerIf( void * volatile *, void *value, void *comperand ) NOINLINE;
+#endif
+
+inline void const *ThreadInterlockedExchangePointerToConst( void const * volatile *p, void const *value ) { return ThreadInterlockedExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ) ); }
+inline void const *ThreadInterlockedCompareExchangePointerToConst( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedCompareExchangePointer( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); }
+inline bool ThreadInterlockedAssignPointerToConstIf( void const * volatile *p, void const *value, void const *comperand ) { return ThreadInterlockedAssignPointerIf( const_cast < void * volatile * > ( p ), const_cast < void * > ( value ), const_cast < void * > ( comperand ) ); }
+
+#if defined( X64BITS )
+#if defined (_WIN32)
+typedef __m128i int128;
+inline int128 int128_zero() { return _mm_setzero_si128(); }
+#else
+typedef __int128_t int128;
+#define int128_zero() 0
+#endif
+
+PLATFORM_INTERFACE bool ThreadInterlockedAssignIf128( volatile int128 *pDest, const int128 &value, const int128 &comperand ) NOINLINE;
+
+#endif
+
+PLATFORM_INTERFACE int64 ThreadInterlockedIncrement64( int64 volatile * ) NOINLINE;
+PLATFORM_INTERFACE int64 ThreadInterlockedDecrement64( int64 volatile * ) NOINLINE;
+PLATFORM_INTERFACE int64 ThreadInterlockedCompareExchange64( int64 volatile *, int64 value, int64 comperand ) NOINLINE;
+PLATFORM_INTERFACE int64 ThreadInterlockedExchange64( int64 volatile *, int64 value ) NOINLINE;
+PLATFORM_INTERFACE int64 ThreadInterlockedExchangeAdd64( int64 volatile *, int64 value ) NOINLINE;
+PLATFORM_INTERFACE bool ThreadInterlockedAssignIf64(volatile int64 *pDest, int64 value, int64 comperand ) NOINLINE;
+
+inline unsigned ThreadInterlockedExchangeSubtract( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
+inline unsigned ThreadInterlockedIncrement( unsigned volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); }
+inline unsigned ThreadInterlockedDecrement( unsigned volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); }
+inline unsigned ThreadInterlockedExchange( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); }
+inline unsigned ThreadInterlockedExchangeAdd( unsigned volatile *p, unsigned value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
+inline unsigned ThreadInterlockedCompareExchange( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); }
+inline bool ThreadInterlockedAssignIf( unsigned volatile *p, unsigned value, unsigned comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); }
+
+inline int ThreadInterlockedExchangeSubtract( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
+inline int ThreadInterlockedIncrement( int volatile *p ) { return ThreadInterlockedIncrement( (long volatile *)p ); }
+inline int ThreadInterlockedDecrement( int volatile *p ) { return ThreadInterlockedDecrement( (long volatile *)p ); }
+inline int ThreadInterlockedExchange( int volatile *p, int value ) { return ThreadInterlockedExchange( (long volatile *)p, value ); }
+inline int ThreadInterlockedExchangeAdd( int volatile *p, int value ) { return ThreadInterlockedExchangeAdd( (long volatile *)p, value ); }
+inline int ThreadInterlockedCompareExchange( int volatile *p, int value, int comperand ) { return ThreadInterlockedCompareExchange( (long volatile *)p, value, comperand ); }
+inline bool ThreadInterlockedAssignIf( int volatile *p, int value, int comperand ) { return ThreadInterlockedAssignIf( (long volatile *)p, value, comperand ); }
+
+//-----------------------------------------------------------------------------
+// Access to VTune thread profiling
+//-----------------------------------------------------------------------------
+#if defined(_WIN32) && defined(THREAD_PROFILER)
+PLATFORM_INTERFACE void ThreadNotifySyncPrepare(void *p);
+PLATFORM_INTERFACE void ThreadNotifySyncCancel(void *p);
+PLATFORM_INTERFACE void ThreadNotifySyncAcquired(void *p);
+PLATFORM_INTERFACE void ThreadNotifySyncReleasing(void *p);
+#else
+#define ThreadNotifySyncPrepare(p) ((void)0)
+#define ThreadNotifySyncCancel(p) ((void)0)
+#define ThreadNotifySyncAcquired(p) ((void)0)
+#define ThreadNotifySyncReleasing(p) ((void)0)
+#endif
+
+//-----------------------------------------------------------------------------
+// Encapsulation of a thread local datum (needed because THREAD_LOCAL doesn't
+// work in a DLL loaded with LoadLibrary()
+//-----------------------------------------------------------------------------
+
+#ifndef __AFXTLS_H__ // not compatible with some Windows headers
+#ifndef NO_THREAD_LOCAL
+
+class PLATFORM_CLASS CThreadLocalBase
+ {
+public:
+ CThreadLocalBase();
+ ~CThreadLocalBase();
+
+ void * Get() const;
+ void Set(void *);
+
+private:
+#ifdef _WIN32
+ uint32 m_index;
+#elif POSIX
+ pthread_key_t m_index;
+#endif
+ };
+
+ //---------------------------------------------------------
+
+#ifndef __AFXTLS_H__
+
+ template <class T>
+ class CThreadLocal : public CThreadLocalBase
+ {
+ public:
+ CThreadLocal()
+ {
+ COMPILE_TIME_ASSERT( sizeof(T) == sizeof(void *) );
+ }
+
+ T Get() const
+ {
+ return reinterpret_cast<T>( CThreadLocalBase::Get() );
+ }
+
+ void Set(T val)
+ {
+ CThreadLocalBase::Set( reinterpret_cast<void *>(val) );
+ }
+ };
+
+#endif
+
+ //---------------------------------------------------------
+
+template <class T = intp>
+ class CThreadLocalInt : public CThreadLocal<T>
+ {
+ public:
+ CThreadLocalInt()
+ {
+ COMPILE_TIME_ASSERT( sizeof(T) >= sizeof(int) );
+ }
+
+ operator const int() const { return (int)this->Get(); }
+ int operator=( int i ) { this->Set( (intp)i ); return i; }
+
+ int operator++() { T i = this->Get(); this->Set( ++i ); return (int)i; }
+ int operator++(int) { T i = this->Get(); this->Set( i + 1 ); return (int)i; }
+
+ int operator--() { T i = this->Get(); this->Set( --i ); return (int)i; }
+ int operator--(int) { T i = this->Get(); this->Set( i - 1 ); return (int)i; }
+ };
+
+
+ //---------------------------------------------------------
+
+ template <class T>
+ class CThreadLocalPtr : private CThreadLocalBase
+ {
+ public:
+ CThreadLocalPtr() {}
+
+ operator const void *() const { return (T *)Get(); }
+ operator void *() { return (T *)Get(); }
+
+ operator const T *() const { return (T *)Get(); }
+ operator const T *() { return (T *)Get(); }
+ operator T *() { return (T *)Get(); }
+
+ int operator=( int i ) { AssertMsg( i == 0, "Only NULL allowed on integer assign" ); Set( NULL ); return 0; }
+ T * operator=( T *p ) { Set( p ); return p; }
+
+ bool operator !() const { return (!Get()); }
+ bool operator!=( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() != NULL); }
+ bool operator==( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (Get() == NULL); }
+ bool operator==( const void *p ) const { return (Get() == p); }
+ bool operator!=( const void *p ) const { return (Get() != p); }
+ bool operator==( const T *p ) const { return operator==((void*)p); }
+ bool operator!=( const T *p ) const { return operator!=((void*)p); }
+
+ T * operator->() { return (T *)Get(); }
+ T & operator *() { return *((T *)Get()); }
+
+ const T * operator->() const { return (T *)Get(); }
+ const T & operator *() const { return *((T *)Get()); }
+
+ const T & operator[]( int i ) const { return *((T *)Get() + i); }
+ T & operator[]( int i ) { return *((T *)Get() + i); }
+
+ private:
+ // Disallowed operations
+ CThreadLocalPtr( T *pFrom );
+ CThreadLocalPtr( const CThreadLocalPtr<T> &from );
+ T **operator &();
+ T * const *operator &() const;
+ void operator=( const CThreadLocalPtr<T> &from );
+ bool operator==( const CThreadLocalPtr<T> &p ) const;
+ bool operator!=( const CThreadLocalPtr<T> &p ) const;
+ };
+
+#endif // NO_THREAD_LOCAL
+#endif // !__AFXTLS_H__
+
+//-----------------------------------------------------------------------------
+//
+// A super-fast thread-safe integer A simple class encapsulating the notion of an
+// atomic integer used across threads that uses the built in and faster
+// "interlocked" functionality rather than a full-blown mutex. Useful for simple
+// things like reference counts, etc.
+//
+//-----------------------------------------------------------------------------
+
+template <typename T>
+class CInterlockedIntT
+{
+public:
+ CInterlockedIntT() : m_value( 0 ) { COMPILE_TIME_ASSERT( sizeof(T) == sizeof(long) ); }
+ CInterlockedIntT( T value ) : m_value( value ) {}
+
+ T GetRaw() const { return m_value; }
+
+ operator T() const { return m_value; }
+
+ bool operator!() const { return ( m_value == 0 ); }
+ bool operator==( T rhs ) const { return ( m_value == rhs ); }
+ bool operator!=( T rhs ) const { return ( m_value != rhs ); }
+
+ T operator++() { return (T)ThreadInterlockedIncrement( (long *)&m_value ); }
+ T operator++(int) { return operator++() - 1; }
+
+ T operator--() { return (T)ThreadInterlockedDecrement( (long *)&m_value ); }
+ T operator--(int) { return operator--() + 1; }
+
+ bool AssignIf( T conditionValue, T newValue ) { return ThreadInterlockedAssignIf( (long *)&m_value, (long)newValue, (long)conditionValue ); }
+
+ T operator=( T newValue ) { ThreadInterlockedExchange((long *)&m_value, newValue); return m_value; }
+
+ void operator+=( T add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, (long)add ); }
+ void operator-=( T subtract ) { operator+=( -subtract ); }
+ void operator*=( T multiplier ) {
+ T original, result;
+ do
+ {
+ original = m_value;
+ result = original * multiplier;
+ } while ( !AssignIf( original, result ) );
+ }
+ void operator/=( T divisor ) {
+ T original, result;
+ do
+ {
+ original = m_value;
+ result = original / divisor;
+ } while ( !AssignIf( original, result ) );
+ }
+
+ T operator+( T rhs ) const { return m_value + rhs; }
+ T operator-( T rhs ) const { return m_value - rhs; }
+
+private:
+ volatile T m_value;
+};
+
+typedef CInterlockedIntT<int> CInterlockedInt;
+typedef CInterlockedIntT<unsigned> CInterlockedUInt;
+
+//-----------------------------------------------------------------------------
+
+template <typename T>
+class CInterlockedPtr
+{
+public:
+ CInterlockedPtr() : m_value( 0 ) {}
+ CInterlockedPtr( T *value ) : m_value( value ) {}
+
+ operator T *() const { return m_value; }
+
+ bool operator!() const { return ( m_value == 0 ); }
+ bool operator==( T *rhs ) const { return ( m_value == rhs ); }
+ bool operator!=( T *rhs ) const { return ( m_value != rhs ); }
+
+#ifdef X64BITS
+ T *operator++() { return ((T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) )) + 1; }
+ T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, sizeof(T) ); }
+
+ T *operator--() { return ((T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, -sizeof(T) )) - 1; }
+ T *operator--(int) { return (T *)ThreadInterlockedExchangeAdd64( (int64 *)&m_value, -sizeof(T) ); }
+
+ bool AssignIf( T *conditionValue, T *newValue ) { return ThreadInterlockedAssignPointerToConstIf( (void const **) &m_value, (void const *) newValue, (void const *) conditionValue ); }
+
+ T *operator=( T *newValue ) { ThreadInterlockedExchangePointerToConst( (void const **) &m_value, (void const *) newValue ); return newValue; }
+
+ void operator+=( int add ) { ThreadInterlockedExchangeAdd64( (int64 *)&m_value, add * sizeof(T) ); }
+#else
+ T *operator++() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) )) + 1; }
+ T *operator++(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, sizeof(T) ); }
+
+ T *operator--() { return ((T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) )) - 1; }
+ T *operator--(int) { return (T *)ThreadInterlockedExchangeAdd( (long *)&m_value, -sizeof(T) ); }
+
+ bool AssignIf( T *conditionValue, T *newValue ) { return ThreadInterlockedAssignPointerToConstIf( (void const **) &m_value, (void const *) newValue, (void const *) conditionValue ); }
+
+ T *operator=( T *newValue ) { ThreadInterlockedExchangePointerToConst( (void const **) &m_value, (void const *) newValue ); return newValue; }
+
+ void operator+=( int add ) { ThreadInterlockedExchangeAdd( (long *)&m_value, add * sizeof(T) ); }
+#endif
+
+ void operator-=( int subtract ) { operator+=( -subtract ); }
+
+ T *operator+( int rhs ) const { return m_value + rhs; }
+ T *operator-( int rhs ) const { return m_value - rhs; }
+ T *operator+( unsigned rhs ) const { return m_value + rhs; }
+ T *operator-( unsigned rhs ) const { return m_value - rhs; }
+ size_t operator-( T *p ) const { return m_value - p; }
+ size_t operator-( const CInterlockedPtr<T> &p ) const { return m_value - p.m_value; }
+
+private:
+ T * volatile m_value;
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// Platform independent for critical sections management
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThreadMutex
+{
+public:
+ CThreadMutex();
+ ~CThreadMutex();
+
+ //------------------------------------------------------
+ // Mutex acquisition/release. Const intentionally defeated.
+ //------------------------------------------------------
+ void Lock();
+ void Lock() const { (const_cast<CThreadMutex *>(this))->Lock(); }
+ void Unlock();
+ void Unlock() const { (const_cast<CThreadMutex *>(this))->Unlock(); }
+
+ bool TryLock();
+ bool TryLock() const { return (const_cast<CThreadMutex *>(this))->TryLock(); }
+
+ //------------------------------------------------------
+ // Use this to make deadlocks easier to track by asserting
+ // when it is expected that the current thread owns the mutex
+ //------------------------------------------------------
+ bool AssertOwnedByCurrentThread();
+
+ //------------------------------------------------------
+ // Enable tracing to track deadlock problems
+ //------------------------------------------------------
+ void SetTrace( bool );
+
+private:
+ // Disallow copying
+ CThreadMutex( const CThreadMutex & );
+ CThreadMutex &operator=( const CThreadMutex & );
+
+#if defined( _WIN32 )
+ // Efficient solution to breaking the windows.h dependency, invariant is tested.
+#ifdef _WIN64
+ #define TT_SIZEOF_CRITICALSECTION 40
+#else
+#ifndef _X360
+ #define TT_SIZEOF_CRITICALSECTION 24
+#else
+ #define TT_SIZEOF_CRITICALSECTION 28
+#endif // !_XBOX
+#endif // _WIN64
+ byte m_CriticalSection[TT_SIZEOF_CRITICALSECTION];
+#elif defined(POSIX)
+ pthread_mutex_t m_Mutex;
+ pthread_mutexattr_t m_Attr;
+#else
+#error
+#endif
+
+#ifdef THREAD_MUTEX_TRACING_SUPPORTED
+ // Debugging (always here to allow mixed debug/release builds w/o changing size)
+ uint m_currentOwnerID;
+ uint16 m_lockCount;
+ bool m_bTrace;
+#endif
+};
+
+//-----------------------------------------------------------------------------
+//
+// An alternative mutex that is useful for cases when thread contention is
+// rare, but a mutex is required. Instances should be declared volatile.
+// Sleep of 0 may not be sufficient to keep high priority threads from starving
+// lesser threads. This class is not a suitable replacement for a critical
+// section if the resource contention is high.
+//
+//-----------------------------------------------------------------------------
+
+#if !defined(THREAD_PROFILER)
+
+class CThreadFastMutex
+{
+public:
+ CThreadFastMutex()
+ : m_ownerID( 0 ),
+ m_depth( 0 )
+ {
+ }
+
+private:
+ FORCEINLINE bool TryLockInline( const uint32 threadId ) volatile
+ {
+ if ( threadId != m_ownerID && !ThreadInterlockedAssignIf( (volatile long *)&m_ownerID, (long)threadId, 0 ) )
+ return false;
+
+ ThreadMemoryBarrier();
+ ++m_depth;
+ return true;
+ }
+
+ bool TryLock( const uint32 threadId ) volatile
+ {
+ return TryLockInline( threadId );
+ }
+
+ PLATFORM_CLASS void Lock( const uint32 threadId, unsigned nSpinSleepTime ) volatile;
+
+public:
+ bool TryLock() volatile
+ {
+#ifdef _DEBUG
+ if ( m_depth == INT_MAX )
+ DebuggerBreak();
+
+ if ( m_depth < 0 )
+ DebuggerBreak();
+#endif
+ return TryLockInline( ThreadGetCurrentId() );
+ }
+
+#ifndef _DEBUG
+ FORCEINLINE
+#endif
+ void Lock( unsigned int nSpinSleepTime = 0 ) volatile
+ {
+ const uint32 threadId = ThreadGetCurrentId();
+
+ if ( !TryLockInline( threadId ) )
+ {
+ ThreadPause();
+ Lock( threadId, nSpinSleepTime );
+ }
+#ifdef _DEBUG
+ if ( m_ownerID != ThreadGetCurrentId() )
+ DebuggerBreak();
+
+ if ( m_depth == INT_MAX )
+ DebuggerBreak();
+
+ if ( m_depth < 0 )
+ DebuggerBreak();
+#endif
+ }
+
+#ifndef _DEBUG
+ FORCEINLINE
+#endif
+ void Unlock() volatile
+ {
+#ifdef _DEBUG
+ if ( m_ownerID != ThreadGetCurrentId() )
+ DebuggerBreak();
+
+ if ( m_depth <= 0 )
+ DebuggerBreak();
+#endif
+
+ --m_depth;
+ if ( !m_depth )
+ {
+ ThreadMemoryBarrier();
+ ThreadInterlockedExchange( &m_ownerID, 0 );
+ }
+ }
+
+#ifdef WIN32
+ bool TryLock() const volatile { return (const_cast<CThreadFastMutex *>(this))->TryLock(); }
+ void Lock(unsigned nSpinSleepTime = 1 ) const volatile { (const_cast<CThreadFastMutex *>(this))->Lock( nSpinSleepTime ); }
+ void Unlock() const volatile { (const_cast<CThreadFastMutex *>(this))->Unlock(); }
+#endif
+ // To match regular CThreadMutex:
+ bool AssertOwnedByCurrentThread() { return true; }
+ void SetTrace( bool ) {}
+
+ uint32 GetOwnerId() const { return m_ownerID; }
+ int GetDepth() const { return m_depth; }
+private:
+ volatile uint32 m_ownerID;
+ int m_depth;
+};
+
+class ALIGN128 CAlignedThreadFastMutex : public CThreadFastMutex
+{
+public:
+ CAlignedThreadFastMutex()
+ {
+ Assert( (size_t)this % 128 == 0 && sizeof(*this) == 128 );
+ }
+
+private:
+ uint8 pad[128-sizeof(CThreadFastMutex)];
+} ALIGN128_POST;
+
+#else
+typedef CThreadMutex CThreadFastMutex;
+#endif
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+
+class CThreadNullMutex
+{
+public:
+ static void Lock() {}
+ static void Unlock() {}
+
+ static bool TryLock() { return true; }
+ static bool AssertOwnedByCurrentThread() { return true; }
+ static void SetTrace( bool b ) {}
+
+ static uint32 GetOwnerId() { return 0; }
+ static int GetDepth() { return 0; }
+};
+
+//-----------------------------------------------------------------------------
+//
+// A mutex decorator class used to control the use of a mutex, to make it
+// less expensive when not multithreading
+//
+//-----------------------------------------------------------------------------
+
+template <class BaseClass, bool *pCondition>
+class CThreadConditionalMutex : public BaseClass
+{
+public:
+ void Lock() { if ( *pCondition ) BaseClass::Lock(); }
+ void Lock() const { if ( *pCondition ) BaseClass::Lock(); }
+ void Unlock() { if ( *pCondition ) BaseClass::Unlock(); }
+ void Unlock() const { if ( *pCondition ) BaseClass::Unlock(); }
+
+ bool TryLock() { if ( *pCondition ) return BaseClass::TryLock(); else return true; }
+ bool TryLock() const { if ( *pCondition ) return BaseClass::TryLock(); else return true; }
+ bool AssertOwnedByCurrentThread() { if ( *pCondition ) return BaseClass::AssertOwnedByCurrentThread(); else return true; }
+ void SetTrace( bool b ) { if ( *pCondition ) BaseClass::SetTrace( b ); }
+};
+
+//-----------------------------------------------------------------------------
+// Mutex decorator that blows up if another thread enters
+//-----------------------------------------------------------------------------
+
+template <class BaseClass>
+class CThreadTerminalMutex : public BaseClass
+{
+public:
+ bool TryLock() { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; }
+ bool TryLock() const { if ( !BaseClass::TryLock() ) { DebuggerBreak(); return false; } return true; }
+ void Lock() { if ( !TryLock() ) BaseClass::Lock(); }
+ void Lock() const { if ( !TryLock() ) BaseClass::Lock(); }
+
+};
+
+//-----------------------------------------------------------------------------
+//
+// Class to Lock a critical section, and unlock it automatically
+// when the lock goes out of scope
+//
+//-----------------------------------------------------------------------------
+
+template <class MUTEX_TYPE = CThreadMutex>
+class CAutoLockT
+{
+public:
+ FORCEINLINE CAutoLockT( MUTEX_TYPE &lock)
+ : m_lock(lock)
+ {
+ m_lock.Lock();
+ }
+
+ FORCEINLINE CAutoLockT(const MUTEX_TYPE &lock)
+ : m_lock(const_cast<MUTEX_TYPE &>(lock))
+ {
+ m_lock.Lock();
+ }
+
+ FORCEINLINE ~CAutoLockT()
+ {
+ m_lock.Unlock();
+ }
+
+
+private:
+ MUTEX_TYPE &m_lock;
+
+ // Disallow copying
+ CAutoLockT<MUTEX_TYPE>( const CAutoLockT<MUTEX_TYPE> & );
+ CAutoLockT<MUTEX_TYPE> &operator=( const CAutoLockT<MUTEX_TYPE> & );
+};
+
+typedef CAutoLockT<CThreadMutex> CAutoLock;
+
+//---------------------------------------------------------
+
+template <int size> struct CAutoLockTypeDeducer {};
+template <> struct CAutoLockTypeDeducer<sizeof(CThreadMutex)> { typedef CThreadMutex Type_t; };
+template <> struct CAutoLockTypeDeducer<sizeof(CThreadNullMutex)> { typedef CThreadNullMutex Type_t; };
+#if !defined(THREAD_PROFILER)
+template <> struct CAutoLockTypeDeducer<sizeof(CThreadFastMutex)> { typedef CThreadFastMutex Type_t; };
+template <> struct CAutoLockTypeDeducer<sizeof(CAlignedThreadFastMutex)> { typedef CAlignedThreadFastMutex Type_t; };
+#endif
+
+#define AUTO_LOCK_( type, mutex ) \
+ CAutoLockT< type > UNIQUE_ID( static_cast<const type &>( mutex ) )
+
+#if defined(GNUC)
+
+template<typename T> T strip_cv_quals_for_mutex(T&);
+template<typename T> T strip_cv_quals_for_mutex(const T&);
+template<typename T> T strip_cv_quals_for_mutex(volatile T&);
+template<typename T> T strip_cv_quals_for_mutex(const volatile T&);
+
+#define AUTO_LOCK( mutex ) \
+ AUTO_LOCK_( typeof(::strip_cv_quals_for_mutex(mutex)), mutex )
+
+#else // GNUC
+
+#define AUTO_LOCK( mutex ) \
+ AUTO_LOCK_( CAutoLockTypeDeducer<sizeof(mutex)>::Type_t, mutex )
+
+#endif
+
+#define AUTO_LOCK_FM( mutex ) \
+ AUTO_LOCK_( CThreadFastMutex, mutex )
+
+#define LOCAL_THREAD_LOCK_( tag ) \
+ ; \
+ static CThreadFastMutex autoMutex_##tag; \
+ AUTO_LOCK( autoMutex_##tag )
+
+#define LOCAL_THREAD_LOCK() \
+ LOCAL_THREAD_LOCK_(_)
+
+//-----------------------------------------------------------------------------
+//
+// Base class for event, semaphore and mutex objects.
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThreadSyncObject
+{
+public:
+ ~CThreadSyncObject();
+
+ //-----------------------------------------------------
+ // Query if object is useful
+ //-----------------------------------------------------
+ bool operator!() const;
+
+ //-----------------------------------------------------
+ // Access handle
+ //-----------------------------------------------------
+#ifdef _WIN32
+ operator HANDLE() { return GetHandle(); }
+ const HANDLE GetHandle() const { return m_hSyncObject; }
+#endif
+ //-----------------------------------------------------
+ // Wait for a signal from the object
+ //-----------------------------------------------------
+ bool Wait( uint32 dwTimeout = TT_INFINITE );
+
+protected:
+ CThreadSyncObject();
+ void AssertUseable();
+
+#ifdef _WIN32
+ HANDLE m_hSyncObject;
+ bool m_bCreatedHandle;
+#elif defined(POSIX)
+ pthread_mutex_t m_Mutex;
+ pthread_cond_t m_Condition;
+ bool m_bInitalized;
+ int m_cSet;
+ bool m_bManualReset;
+ bool m_bWakeForEvent;
+#else
+#error "Implement me"
+#endif
+
+private:
+ CThreadSyncObject( const CThreadSyncObject & );
+ CThreadSyncObject &operator=( const CThreadSyncObject & );
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// Wrapper for unnamed event objects
+//
+//-----------------------------------------------------------------------------
+
+#if defined( _WIN32 )
+
+//-----------------------------------------------------------------------------
+//
+// CThreadSemaphore
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThreadSemaphore : public CThreadSyncObject
+{
+public:
+ CThreadSemaphore(long initialValue, long maxValue);
+
+ //-----------------------------------------------------
+ // Increases the count of the semaphore object by a specified
+ // amount. Wait() decreases the count by one on return.
+ //-----------------------------------------------------
+ bool Release(long releaseCount = 1, long * pPreviousCount = NULL );
+
+private:
+ CThreadSemaphore(const CThreadSemaphore &);
+ CThreadSemaphore &operator=(const CThreadSemaphore &);
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// A mutex suitable for out-of-process, multi-processor usage
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThreadFullMutex : public CThreadSyncObject
+{
+public:
+ CThreadFullMutex( bool bEstablishInitialOwnership = false, const char * pszName = NULL );
+
+ //-----------------------------------------------------
+ // Release ownership of the mutex
+ //-----------------------------------------------------
+ bool Release();
+
+ // To match regular CThreadMutex:
+ void Lock() { Wait(); }
+ void Lock( unsigned timeout ) { Wait( timeout ); }
+ void Unlock() { Release(); }
+ bool AssertOwnedByCurrentThread() { return true; }
+ void SetTrace( bool ) {}
+
+private:
+ CThreadFullMutex( const CThreadFullMutex & );
+ CThreadFullMutex &operator=( const CThreadFullMutex & );
+};
+#endif
+
+
+class PLATFORM_CLASS CThreadEvent : public CThreadSyncObject
+{
+public:
+ CThreadEvent( bool fManualReset = false );
+#ifdef WIN32
+ CThreadEvent( HANDLE hHandle );
+#endif
+ //-----------------------------------------------------
+ // Set the state to signaled
+ //-----------------------------------------------------
+ bool Set();
+
+ //-----------------------------------------------------
+ // Set the state to nonsignaled
+ //-----------------------------------------------------
+ bool Reset();
+
+ //-----------------------------------------------------
+ // Check if the event is signaled
+ //-----------------------------------------------------
+ bool Check();
+
+ bool Wait( uint32 dwTimeout = TT_INFINITE );
+
+private:
+ CThreadEvent( const CThreadEvent & );
+ CThreadEvent &operator=( const CThreadEvent & );
+};
+
+// Hard-wired manual event for use in array declarations
+class CThreadManualEvent : public CThreadEvent
+{
+public:
+ CThreadManualEvent()
+ : CThreadEvent( true )
+ {
+ }
+};
+
+inline int ThreadWaitForEvents( int nEvents, CThreadEvent * const *pEvents, bool bWaitAll = true, unsigned timeout = TT_INFINITE )
+{
+#ifdef POSIX
+ Assert( nEvents == 1);
+ if ( pEvents[0]->Wait( timeout ) )
+ return WAIT_OBJECT_0;
+ else
+ return WAIT_TIMEOUT;
+#else
+ HANDLE handles[64];
+ for ( unsigned int i = 0; i < min( nEvents, ARRAYSIZE(handles) ); i++ )
+ handles[i] = pEvents[i]->GetHandle();
+ return ThreadWaitForObjects( nEvents, handles, bWaitAll, timeout );
+#endif
+}
+
+//-----------------------------------------------------------------------------
+//
+// CThreadRWLock
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThreadRWLock
+{
+public:
+ CThreadRWLock();
+
+ void LockForRead();
+ void UnlockRead();
+ void LockForWrite();
+ void UnlockWrite();
+
+ void LockForRead() const { const_cast<CThreadRWLock *>(this)->LockForRead(); }
+ void UnlockRead() const { const_cast<CThreadRWLock *>(this)->UnlockRead(); }
+ void LockForWrite() const { const_cast<CThreadRWLock *>(this)->LockForWrite(); }
+ void UnlockWrite() const { const_cast<CThreadRWLock *>(this)->UnlockWrite(); }
+
+private:
+ void WaitForRead();
+
+#ifdef WIN32
+ CThreadFastMutex m_mutex;
+#else
+ CThreadMutex m_mutex;
+#endif
+ CThreadEvent m_CanWrite;
+ CThreadEvent m_CanRead;
+
+ int m_nWriters;
+ int m_nActiveReaders;
+ int m_nPendingReaders;
+};
+
+//-----------------------------------------------------------------------------
+//
+// CThreadSpinRWLock
+//
+//-----------------------------------------------------------------------------
+
+class ALIGN8 PLATFORM_CLASS CThreadSpinRWLock
+{
+public:
+ CThreadSpinRWLock() { COMPILE_TIME_ASSERT( sizeof( LockInfo_t ) == sizeof( int64 ) ); Assert( (intp)this % 8 == 0 ); memset( this, 0, sizeof( *this ) ); }
+
+ bool TryLockForWrite();
+ bool TryLockForRead();
+
+ void LockForRead();
+ void UnlockRead();
+ void LockForWrite();
+ void UnlockWrite();
+
+ bool TryLockForWrite() const { return const_cast<CThreadSpinRWLock *>(this)->TryLockForWrite(); }
+ bool TryLockForRead() const { return const_cast<CThreadSpinRWLock *>(this)->TryLockForRead(); }
+ void LockForRead() const { const_cast<CThreadSpinRWLock *>(this)->LockForRead(); }
+ void UnlockRead() const { const_cast<CThreadSpinRWLock *>(this)->UnlockRead(); }
+ void LockForWrite() const { const_cast<CThreadSpinRWLock *>(this)->LockForWrite(); }
+ void UnlockWrite() const { const_cast<CThreadSpinRWLock *>(this)->UnlockWrite(); }
+
+private:
+ struct LockInfo_t
+ {
+ uint32 m_writerId;
+ int m_nReaders;
+ };
+
+ bool AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand );
+ bool TryLockForWrite( const uint32 threadId );
+ void SpinLockForWrite( const uint32 threadId );
+
+ volatile LockInfo_t m_lockInfo;
+ CInterlockedInt m_nWriters;
+} ALIGN8_POST;
+
+//-----------------------------------------------------------------------------
+//
+// A thread wrapper similar to a Java thread.
+//
+//-----------------------------------------------------------------------------
+
+class PLATFORM_CLASS CThread
+{
+public:
+ CThread();
+ virtual ~CThread();
+
+ //-----------------------------------------------------
+
+ const char *GetName();
+ void SetName( const char * );
+
+ size_t CalcStackDepth( void *pStackVariable ) { return ((byte *)m_pStackBase - (byte *)pStackVariable); }
+
+ //-----------------------------------------------------
+ // Functions for the other threads
+ //-----------------------------------------------------
+
+ // Start thread running - error if already running
+ virtual bool Start( unsigned nBytesStack = 0 );
+
+ // Returns true if thread has been created and hasn't yet exited
+ bool IsAlive();
+
+ // This method causes the current thread to wait until this thread
+ // is no longer alive.
+ bool Join( unsigned timeout = TT_INFINITE );
+
+#ifdef _WIN32
+ // Access the thread handle directly
+ HANDLE GetThreadHandle();
+ uint GetThreadId();
+#elif defined( LINUX )
+ uint GetThreadId();
+#endif
+
+ //-----------------------------------------------------
+
+ int GetResult();
+
+ //-----------------------------------------------------
+ // Functions for both this, and maybe, and other threads
+ //-----------------------------------------------------
+
+ // Forcibly, abnormally, but relatively cleanly stop the thread
+ void Stop( int exitCode = 0 );
+
+ // Get the priority
+ int GetPriority() const;
+
+ // Set the priority
+ bool SetPriority( int );
+
+ // Request a thread to suspend, this must ONLY be called from the thread itself, not the main thread
+ // This suspend variant causes the thread in question to suspend at a known point in its execution
+ // which means you don't risk the global deadlocks/hangs potentially caused by the raw Suspend() call
+ void SuspendCooperative();
+
+ // Resume a previously suspended thread from the Cooperative call
+ void ResumeCooperative();
+
+ // wait for a thread to execute its SuspendCooperative call
+ void BWaitForThreadSuspendCooperative();
+
+#ifndef LINUX
+ // forcefully Suspend a thread
+ unsigned int Suspend();
+
+ // forcefully Resume a previously suspended thread
+ unsigned int Resume();
+#endif
+
+ // Force hard-termination of thread. Used for critical failures.
+ bool Terminate( int exitCode = 0 );
+
+ //-----------------------------------------------------
+ // Global methods
+ //-----------------------------------------------------
+
+ // Get the Thread object that represents the current thread, if any.
+ // Can return NULL if the current thread was not created using
+ // CThread
+ static CThread *GetCurrentCThread();
+
+ // Offer a context switch. Under Win32, equivalent to Sleep(0)
+#ifdef Yield
+#undef Yield
+#endif
+ static void Yield();
+
+ // This method causes the current thread to yield and not to be
+ // scheduled for further execution until a certain amount of real
+ // time has elapsed, more or less.
+ static void Sleep( unsigned duration );
+
+protected:
+
+ // Optional pre-run call, with ability to fail-create. Note Init()
+ // is forced synchronous with Start()
+ virtual bool Init();
+
+ // Thread will run this function on startup, must be supplied by
+ // derived class, performs the intended action of the thread.
+ virtual int Run() = 0;
+
+ // Called when the thread is about to exit, by the about-to-exit thread.
+ virtual void OnExit();
+
+ // Called after OnExit when a thread finishes or is killed. Not virtual because no inherited classes
+ // override it and we don't want to change the vtable from the published SDK version.
+ void Cleanup();
+
+ bool WaitForCreateComplete( CThreadEvent *pEvent );
+
+ // "Virtual static" facility
+ typedef unsigned (__stdcall *ThreadProc_t)( void * );
+ virtual ThreadProc_t GetThreadProc();
+ virtual bool IsThreadRunning();
+
+ CThreadMutex m_Lock;
+
+#ifdef WIN32
+ const ThreadHandle_t GetThreadID() const { return (ThreadHandle_t)m_hThread; }
+#else
+ const ThreadId_t GetThreadID() const { return (ThreadId_t)m_threadId; }
+#endif
+
+private:
+ enum Flags
+ {
+ SUPPORT_STOP_PROTOCOL = 1 << 0
+ };
+
+ // Thread initially runs this. param is actually 'this'. function
+ // just gets this and calls ThreadProc
+ struct ThreadInit_t
+ {
+ CThread * pThread;
+ CThreadEvent *pInitCompleteEvent;
+ bool * pfInitSuccess;
+ };
+
+ static unsigned __stdcall ThreadProc( void * pv );
+
+ // make copy constructor and assignment operator inaccessible
+ CThread( const CThread & );
+ CThread &operator=( const CThread & );
+
+#ifdef _WIN32
+ HANDLE m_hThread;
+ ThreadId_t m_threadId;
+#elif defined(POSIX)
+ pthread_t m_threadId;
+#endif
+ CInterlockedInt m_nSuspendCount;
+ CThreadEvent m_SuspendEvent;
+ CThreadEvent m_SuspendEventSignal;
+ int m_result;
+ char m_szName[32];
+ void * m_pStackBase;
+ unsigned m_flags;
+};
+
+//-----------------------------------------------------------------------------
+//
+// A helper class to let you sleep a thread for memory validation, you need to handle
+// m_bSleepForValidate in your ::Run() call and set m_bSleepingForValidate when sleeping
+//
+//-----------------------------------------------------------------------------
+class PLATFORM_CLASS CValidatableThread : public CThread
+{
+public:
+ CValidatableThread()
+ {
+ m_bSleepForValidate = false;
+ m_bSleepingForValidate = false;
+ }
+
+#ifdef DBGFLAG_VALIDATE
+ virtual void SleepForValidate() { m_bSleepForValidate = true; }
+ bool BSleepingForValidate() { return m_bSleepingForValidate; }
+ virtual void WakeFromValidate() { m_bSleepForValidate = false; }
+#endif
+protected:
+ bool m_bSleepForValidate;
+ bool m_bSleepingForValidate;
+};
+
+//-----------------------------------------------------------------------------
+// Simple thread class encompasses the notion of a worker thread, handing
+// synchronized communication.
+//-----------------------------------------------------------------------------
+
+
+// These are internal reserved error results from a call attempt
+enum WTCallResult_t
+{
+ WTCR_FAIL = -1,
+ WTCR_TIMEOUT = -2,
+ WTCR_THREAD_GONE = -3,
+};
+
+class CFunctor;
+class PLATFORM_CLASS CWorkerThread : public CThread
+{
+public:
+ CWorkerThread();
+
+ //-----------------------------------------------------
+ //
+ // Inter-thread communication
+ //
+ // Calls in either direction take place on the same "channel."
+ // Seperate functions are specified to make identities obvious
+ //
+ //-----------------------------------------------------
+
+ // Master: Signal the thread, and block for a response
+ int CallWorker( unsigned, unsigned timeout = TT_INFINITE, bool fBoostWorkerPriorityToMaster = true, CFunctor *pParamFunctor = NULL );
+
+ // Worker: Signal the thread, and block for a response
+ int CallMaster( unsigned, unsigned timeout = TT_INFINITE );
+
+ // Wait for the next request
+ bool WaitForCall( unsigned dwTimeout, unsigned *pResult = NULL );
+ bool WaitForCall( unsigned *pResult = NULL );
+
+ // Is there a request?
+ bool PeekCall( unsigned *pParam = NULL, CFunctor **ppParamFunctor = NULL );
+
+ // Reply to the request
+ void Reply( unsigned );
+
+ // Wait for a reply in the case when CallWorker() with timeout != TT_INFINITE
+ int WaitForReply( unsigned timeout = TT_INFINITE );
+
+ // If you want to do WaitForMultipleObjects you'll need to include
+ // this handle in your wait list or you won't be responsive
+ CThreadEvent &GetCallHandle();
+ // Find out what the request was
+ unsigned GetCallParam( CFunctor **ppParamFunctor = NULL ) const;
+
+ // Boost the worker thread to the master thread, if worker thread is lesser, return old priority
+ int BoostPriority();
+
+protected:
+#ifndef _WIN32
+#define __stdcall
+#endif
+ typedef uint32 (__stdcall *WaitFunc_t)( int nEvents, CThreadEvent * const *pEvents, int bWaitAll, uint32 timeout );
+
+ int Call( unsigned, unsigned timeout, bool fBoost, WaitFunc_t = NULL, CFunctor *pParamFunctor = NULL );
+ int WaitForReply( unsigned timeout, WaitFunc_t );
+
+private:
+ CWorkerThread( const CWorkerThread & );
+ CWorkerThread &operator=( const CWorkerThread & );
+
+ CThreadEvent m_EventSend;
+ CThreadEvent m_EventComplete;
+
+ unsigned m_Param;
+ CFunctor *m_pParamFunctor;
+ int m_ReturnVal;
+};
+
+
+// a unidirectional message queue. A queue of type T. Not especially high speed since each message
+// is malloced/freed. Note that if your message class has destructors/constructors, they MUST be
+// thread safe!
+template<class T> class CMessageQueue
+{
+ CThreadEvent SignalEvent; // signals presence of data
+ CThreadMutex QueueAccessMutex;
+
+ // the parts protected by the mutex
+ struct MsgNode
+ {
+ MsgNode *Next;
+ T Data;
+ };
+
+ MsgNode *Head;
+ MsgNode *Tail;
+
+public:
+ CMessageQueue( void )
+ {
+ Head = Tail = NULL;
+ }
+
+ // check for a message. not 100% reliable - someone could grab the message first
+ bool MessageWaiting( void )
+ {
+ return ( Head != NULL );
+ }
+
+ void WaitMessage( T *pMsg )
+ {
+ for(;;)
+ {
+ while( ! MessageWaiting() )
+ SignalEvent.Wait();
+ QueueAccessMutex.Lock();
+ if (! Head )
+ {
+ // multiple readers could make this null
+ QueueAccessMutex.Unlock();
+ continue;
+ }
+ *( pMsg ) = Head->Data;
+ MsgNode *remove_this = Head;
+ Head = Head->Next;
+ if (! Head) // if empty, fix tail ptr
+ Tail = NULL;
+ QueueAccessMutex.Unlock();
+ delete remove_this;
+ break;
+ }
+ }
+
+ void QueueMessage( T const &Msg)
+ {
+ MsgNode *new1=new MsgNode;
+ new1->Data=Msg;
+ new1->Next=NULL;
+ QueueAccessMutex.Lock();
+ if ( Tail )
+ {
+ Tail->Next=new1;
+ Tail = new1;
+ }
+ else
+ {
+ Head = new1;
+ Tail = new1;
+ }
+ SignalEvent.Set();
+ QueueAccessMutex.Unlock();
+ }
+};
+
+
+//-----------------------------------------------------------------------------
+//
+// CThreadMutex. Inlining to reduce overhead and to allow client code
+// to decide debug status (tracing)
+//
+//-----------------------------------------------------------------------------
+
+#ifdef _WIN32
+typedef struct _RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION;
+typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;
+
+#ifndef _X360
+extern "C"
+{
+ void __declspec(dllimport) __stdcall InitializeCriticalSection(CRITICAL_SECTION *);
+ void __declspec(dllimport) __stdcall EnterCriticalSection(CRITICAL_SECTION *);
+ void __declspec(dllimport) __stdcall LeaveCriticalSection(CRITICAL_SECTION *);
+ void __declspec(dllimport) __stdcall DeleteCriticalSection(CRITICAL_SECTION *);
+};
+#endif
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::Lock()
+{
+#ifdef THREAD_MUTEX_TRACING_ENABLED
+ uint thisThreadID = ThreadGetCurrentId();
+ if ( m_bTrace && m_currentOwnerID && ( m_currentOwnerID != thisThreadID ) )
+ Msg( "Thread %u about to wait for lock %p owned by %u\n", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID );
+ #endif
+
+ VCRHook_EnterCriticalSection((CRITICAL_SECTION *)&m_CriticalSection);
+
+ #ifdef THREAD_MUTEX_TRACING_ENABLED
+ if (m_lockCount == 0)
+ {
+ // we now own it for the first time. Set owner information
+ m_currentOwnerID = thisThreadID;
+ if ( m_bTrace )
+ Msg( "Thread %u now owns lock %p\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection );
+ }
+ m_lockCount++;
+ #endif
+}
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::Unlock()
+{
+ #ifdef THREAD_MUTEX_TRACING_ENABLED
+ AssertMsg( m_lockCount >= 1, "Invalid unlock of thread lock" );
+ m_lockCount--;
+ if (m_lockCount == 0)
+ {
+ if ( m_bTrace )
+ Msg( "Thread %u releasing lock %p\n", m_currentOwnerID, (CRITICAL_SECTION *)&m_CriticalSection );
+ m_currentOwnerID = 0;
+ }
+ #endif
+ LeaveCriticalSection((CRITICAL_SECTION *)&m_CriticalSection);
+}
+
+//---------------------------------------------------------
+
+inline bool CThreadMutex::AssertOwnedByCurrentThread()
+{
+#ifdef THREAD_MUTEX_TRACING_ENABLED
+ if (ThreadGetCurrentId() == m_currentOwnerID)
+ return true;
+ AssertMsg3( 0, "Expected thread %u as owner of lock %p, but %u owns", ThreadGetCurrentId(), (CRITICAL_SECTION *)&m_CriticalSection, m_currentOwnerID );
+ return false;
+#else
+ return true;
+#endif
+}
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::SetTrace( bool bTrace )
+{
+#ifdef THREAD_MUTEX_TRACING_ENABLED
+ m_bTrace = bTrace;
+#endif
+}
+
+//---------------------------------------------------------
+
+#elif defined(POSIX)
+
+inline CThreadMutex::CThreadMutex()
+{
+ // enable recursive locks as we need them
+ pthread_mutexattr_init( &m_Attr );
+ pthread_mutexattr_settype( &m_Attr, PTHREAD_MUTEX_RECURSIVE );
+ pthread_mutex_init( &m_Mutex, &m_Attr );
+}
+
+//---------------------------------------------------------
+
+inline CThreadMutex::~CThreadMutex()
+{
+ pthread_mutex_destroy( &m_Mutex );
+}
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::Lock()
+{
+ pthread_mutex_lock( &m_Mutex );
+}
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::Unlock()
+{
+ pthread_mutex_unlock( &m_Mutex );
+}
+
+//---------------------------------------------------------
+
+inline bool CThreadMutex::AssertOwnedByCurrentThread()
+{
+ return true;
+}
+
+//---------------------------------------------------------
+
+inline void CThreadMutex::SetTrace(bool fTrace)
+{
+}
+
+#endif // POSIX
+
+//-----------------------------------------------------------------------------
+//
+// CThreadRWLock inline functions
+//
+//-----------------------------------------------------------------------------
+
+inline CThreadRWLock::CThreadRWLock()
+: m_CanRead( true ),
+ m_nWriters( 0 ),
+ m_nActiveReaders( 0 ),
+ m_nPendingReaders( 0 )
+{
+}
+
+inline void CThreadRWLock::LockForRead()
+{
+ m_mutex.Lock();
+ if ( m_nWriters)
+ {
+ WaitForRead();
+ }
+ m_nActiveReaders++;
+ m_mutex.Unlock();
+}
+
+inline void CThreadRWLock::UnlockRead()
+{
+ m_mutex.Lock();
+ m_nActiveReaders--;
+ if ( m_nActiveReaders == 0 && m_nWriters != 0 )
+ {
+ m_CanWrite.Set();
+ }
+ m_mutex.Unlock();
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// CThreadSpinRWLock inline functions
+//
+//-----------------------------------------------------------------------------
+
+inline bool CThreadSpinRWLock::AssignIf( const LockInfo_t &newValue, const LockInfo_t &comperand )
+{
+ return ThreadInterlockedAssignIf64( (int64 *)&m_lockInfo, *((int64 *)&newValue), *((int64 *)&comperand) );
+}
+
+inline bool CThreadSpinRWLock::TryLockForWrite( const uint32 threadId )
+{
+ // In order to grab a write lock, there can be no readers and no owners of the write lock
+ if ( m_lockInfo.m_nReaders > 0 || ( m_lockInfo.m_writerId && m_lockInfo.m_writerId != threadId ) )
+ {
+ return false;
+ }
+
+ static const LockInfo_t oldValue = { 0, 0 };
+ LockInfo_t newValue = { threadId, 0 };
+ const bool bSuccess = AssignIf( newValue, oldValue );
+#if defined(_X360)
+ if ( bSuccess )
+ {
+ // X360TBD: Serious perf implications. Not Yet. __sync();
+ }
+#endif
+ return bSuccess;
+}
+
+inline bool CThreadSpinRWLock::TryLockForWrite()
+{
+ m_nWriters++;
+ if ( !TryLockForWrite( ThreadGetCurrentId() ) )
+ {
+ m_nWriters--;
+ return false;
+ }
+ return true;
+}
+
+inline bool CThreadSpinRWLock::TryLockForRead()
+{
+ if ( m_nWriters != 0 )
+ {
+ return false;
+ }
+ // In order to grab a write lock, the number of readers must not change and no thread can own the write
+ LockInfo_t oldValue;
+ LockInfo_t newValue;
+
+ oldValue.m_nReaders = m_lockInfo.m_nReaders;
+ oldValue.m_writerId = 0;
+ newValue.m_nReaders = oldValue.m_nReaders + 1;
+ newValue.m_writerId = 0;
+
+ const bool bSuccess = AssignIf( newValue, oldValue );
+#if defined(_X360)
+ if ( bSuccess )
+ {
+ // X360TBD: Serious perf implications. Not Yet. __sync();
+ }
+#endif
+ return bSuccess;
+}
+
+inline void CThreadSpinRWLock::LockForWrite()
+{
+ const uint32 threadId = ThreadGetCurrentId();
+
+ m_nWriters++;
+
+ if ( !TryLockForWrite( threadId ) )
+ {
+ ThreadPause();
+ SpinLockForWrite( threadId );
+ }
+}
+
+// read data from a memory address
+template<class T> FORCEINLINE T ReadVolatileMemory( T const *pPtr )
+{
+ volatile const T * pVolatilePtr = ( volatile const T * ) pPtr;
+ return *pVolatilePtr;
+}
+
+//-----------------------------------------------------------------------------
+
+#if defined( _WIN32 )
+#pragma warning(pop)
+#endif
+
+#endif // THREADTOOLS_H
diff --git a/sp/src/public/tier0/tmapi_dummy.h b/sp/src/public/tier0/tmapi_dummy.h
index 348d2c9d..f50a039a 100644
--- a/sp/src/public/tier0/tmapi_dummy.h
+++ b/sp/src/public/tier0/tmapi_dummy.h
@@ -1,78 +1,78 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-// This is the null header file used to remove Telemetry calls.
-
-#define TMERR_DISABLED 1
-#define TMPRINTF_TOKEN_NONE 0
-
-#define tmGetSessionName(...)
-#define tmEndTryLock(...)
-#define tmEndTryLockEx(...)
-#define tmSetLockState(...)
-#define tmSetLockStateEx(...)
-#define tmSetLockStateMinTime(...) 0
-#define tmSetLockStateMinTimeEx(...) 0
-#define tmSignalLockCount(...)
-
-#define tmCheckVersion(...) 0
-#define tmGetCallStack(...) 0
-#define tmSendCallStack( ... ) TMPRINTF_TOKEN_NONE
-#define tmGetCallStackR(...) 0
-#define tmSendCallStackR(...) TMPRINTF_TOKEN_NONE
-#define tmSendCallStackWithSkipR(...) TMPRINTF_TOKEN_NONE
-
-#define tmGetVersion(...) 0
-#define tmStartup(...) TMERR_DISABLED
-#define tmGetPlatformInformation(...) TMERR_DISABLED
-#define tmInitializeContext(...) TMERR_DISABLED
-#define tmShutdown(...) TMERR_DISABLED
-
-#define tmEnter(...)
-#define tmEnterEx(...)
-#define tmZone(...)
-#define tmZoneFiltered(...)
-#define tmLeaveEx(...)
-
-#define tmBeginTimeSpan(...)
-#define tmEndTimeSpan(...)
-
-#define tmEmitAccumulationZone(...)
-
-#define tmGetStati(...) 0
-
-#define tmSetVariable(...)
-
-#define tmBlob(...)
-#define tmDisjointBlob(...)
-#define tmSetTimelineSectionName(...)
-#define tmThreadName(...)
-#define tmLockName(...)
-#define tmMessage(...)
-#define tmAlloc(...)
-#define tmAllocEx(...)
-
-#define tmTryLock(...)
-#define tmTryLockEx(...)
-
-#define tmPlot(...)
-#define tmPlotF32(...)
-#define tmPlotF64(...)
-#define tmPlotI32(...)
-#define tmPlotU32(...)
-#define tmPlotS32(...)
-#define tmPlotI64(...)
-#define tmPlotU64(...)
-#define tmPlotS64(...)
-
-#define tmPPUGetListener(...) TMERR_DISABLED
-#define tmPPURegisterSPUProgram(...) TMERR_DISABLED
-#define tmSPUBindContextToListener(...)
-#define tmSPUUpdateTime(...)
-#define tmSPUFlushImage(...)
-
-#define NTELEMETRY 1
-
-#define TM_CONTEXT_LITE(val) ((char*)(val))
-#define TM_CONTEXT_FULL(val) ((char*)(val))
-
-typedef char *HTELEMETRY;
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+// This is the null header file used to remove Telemetry calls.
+
+#define TMERR_DISABLED 1
+#define TMPRINTF_TOKEN_NONE 0
+
+#define tmGetSessionName(...)
+#define tmEndTryLock(...)
+#define tmEndTryLockEx(...)
+#define tmSetLockState(...)
+#define tmSetLockStateEx(...)
+#define tmSetLockStateMinTime(...) 0
+#define tmSetLockStateMinTimeEx(...) 0
+#define tmSignalLockCount(...)
+
+#define tmCheckVersion(...) 0
+#define tmGetCallStack(...) 0
+#define tmSendCallStack( ... ) TMPRINTF_TOKEN_NONE
+#define tmGetCallStackR(...) 0
+#define tmSendCallStackR(...) TMPRINTF_TOKEN_NONE
+#define tmSendCallStackWithSkipR(...) TMPRINTF_TOKEN_NONE
+
+#define tmGetVersion(...) 0
+#define tmStartup(...) TMERR_DISABLED
+#define tmGetPlatformInformation(...) TMERR_DISABLED
+#define tmInitializeContext(...) TMERR_DISABLED
+#define tmShutdown(...) TMERR_DISABLED
+
+#define tmEnter(...)
+#define tmEnterEx(...)
+#define tmZone(...)
+#define tmZoneFiltered(...)
+#define tmLeaveEx(...)
+
+#define tmBeginTimeSpan(...)
+#define tmEndTimeSpan(...)
+
+#define tmEmitAccumulationZone(...)
+
+#define tmGetStati(...) 0
+
+#define tmSetVariable(...)
+
+#define tmBlob(...)
+#define tmDisjointBlob(...)
+#define tmSetTimelineSectionName(...)
+#define tmThreadName(...)
+#define tmLockName(...)
+#define tmMessage(...)
+#define tmAlloc(...)
+#define tmAllocEx(...)
+
+#define tmTryLock(...)
+#define tmTryLockEx(...)
+
+#define tmPlot(...)
+#define tmPlotF32(...)
+#define tmPlotF64(...)
+#define tmPlotI32(...)
+#define tmPlotU32(...)
+#define tmPlotS32(...)
+#define tmPlotI64(...)
+#define tmPlotU64(...)
+#define tmPlotS64(...)
+
+#define tmPPUGetListener(...) TMERR_DISABLED
+#define tmPPURegisterSPUProgram(...) TMERR_DISABLED
+#define tmSPUBindContextToListener(...)
+#define tmSPUUpdateTime(...)
+#define tmSPUFlushImage(...)
+
+#define NTELEMETRY 1
+
+#define TM_CONTEXT_LITE(val) ((char*)(val))
+#define TM_CONTEXT_FULL(val) ((char*)(val))
+
+typedef char *HTELEMETRY;
+
diff --git a/sp/src/public/tier0/tslist.h b/sp/src/public/tier0/tslist.h
index 9ee200a3..d6610e0c 100644
--- a/sp/src/public/tier0/tslist.h
+++ b/sp/src/public/tier0/tslist.h
@@ -1,1004 +1,1004 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// LIFO from disassembly of Windows API and http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
-// FIFO from http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
-//
-//=============================================================================
-
-#ifndef TSLIST_H
-#define TSLIST_H
-
-#if defined( _WIN32 )
-#pragma once
-// Suppress this spurious warning:
-// warning C4700: uninitialized local variable 'oldHead' used
-#pragma warning( push )
-#pragma warning( disable : 4700 )
-#endif
-
-#if defined( USE_NATIVE_SLIST ) && !defined( _X360 )
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-
-#include "tier0/dbg.h"
-#include "tier0/threadtools.h"
-#include "tier0/memalloc.h"
-#include "tier0/memdbgoff.h"
-
-#if defined( _X360 )
-#define USE_NATIVE_SLIST
-#endif
-
-//-----------------------------------------------------------------------------
-
-#if defined( PLATFORM_64BITS )
-
-#define TSLIST_HEAD_ALIGNMENT 16
-#define TSLIST_NODE_ALIGNMENT 16
-inline bool ThreadInterlockedAssignIf64x128( volatile int128 *pDest, const int128 &value, const int128 &comperand )
- { return ThreadInterlockedAssignIf128( pDest, value, comperand ); }
-#else
-#define TSLIST_HEAD_ALIGNMENT 8
-#define TSLIST_NODE_ALIGNMENT 8
-inline bool ThreadInterlockedAssignIf64x128( volatile int64 *pDest, const int64 value, const int64 comperand )
- { return ThreadInterlockedAssignIf64( pDest, value, comperand ); }
-#endif
-
-#ifdef _MSC_VER
-#define TSLIST_HEAD_ALIGN DECL_ALIGN(TSLIST_HEAD_ALIGNMENT)
-#define TSLIST_NODE_ALIGN DECL_ALIGN(TSLIST_NODE_ALIGNMENT)
-#define TSLIST_HEAD_ALIGN_POST
-#define TSLIST_NODE_ALIGN_POST
-#elif defined( GNUC )
-#define TSLIST_HEAD_ALIGN
-#define TSLIST_NODE_ALIGN
-#define TSLIST_HEAD_ALIGN_POST DECL_ALIGN(TSLIST_HEAD_ALIGNMENT)
-#define TSLIST_NODE_ALIGN_POST DECL_ALIGN(TSLIST_NODE_ALIGNMENT)
-#elif defined( _PS3 )
-#define TSLIST_HEAD_ALIGNMENT 8
-#define TSLIST_NODE_ALIGNMENT 8
-
-#define TSLIST_HEAD_ALIGN ALIGN8
-#define TSLIST_NODE_ALIGN ALIGN8
-#define TSLIST_HEAD_ALIGN_POST ALIGN8_POST
-#define TSLIST_NODE_ALIGN_POST ALIGN8_POST
-
-#else
-#error
-#endif
-
-//-----------------------------------------------------------------------------
-
-PLATFORM_INTERFACE bool RunTSQueueTests( int nListSize = 10000, int nTests = 1 );
-PLATFORM_INTERFACE bool RunTSListTests( int nListSize = 10000, int nTests = 1 );
-
-//-----------------------------------------------------------------------------
-// Lock free list.
-//-----------------------------------------------------------------------------
-//#define USE_NATIVE_SLIST
-
-#ifdef USE_NATIVE_SLIST
-typedef SLIST_ENTRY TSLNodeBase_t;
-typedef SLIST_HEADER TSLHead_t;
-#else
-struct TSLIST_NODE_ALIGN TSLNodeBase_t
-{
- TSLNodeBase_t *Next; // name to match Windows
-} TSLIST_NODE_ALIGN_POST;
-
-union TSLIST_HEAD_ALIGN TSLHead_t
-{
- struct Value_t
- {
- TSLNodeBase_t *Next;
- // <sergiy> Depth must be in the least significant halfword when atomically loading into register,
- // to avoid carrying digits from Sequence. Carrying digits from Depth to Sequence is ok,
- // because Sequence can be pretty much random. We could operate on both of them separately,
- // but it could perhaps (?) lead to problems with store forwarding. I don't know 'cause I didn't
- // performance-test or design original code, I'm just making it work on PowerPC.
- #ifdef VALVE_BIG_ENDIAN
- int16 Sequence;
- int16 Depth;
- #else
- int16 Depth;
- int16 Sequence;
- #endif
-#ifdef PLATFORM_64BITS
- int32 Padding;
-#endif
- } value;
-
- struct Value32_t
- {
- TSLNodeBase_t *Next_do_not_use_me;
- int32 DepthAndSequence;
- } value32;
-
-#ifdef PLATFORM_64BITS
- int128 value64x128;
-#else
- int64 value64x128;
-#endif
-} TSLIST_HEAD_ALIGN_POST;
-
-#endif
-
-//-------------------------------------
-class CTSListBase
-{
-public:
-
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size )
- {
- CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
- return pNode;
- }
-
- static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
- {
- CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
- return pNode;
- }
-
- static void operator delete( void *p)
- {
- MemAlloc_FreeAligned( p );
- }
-
- static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
- {
- MemAlloc_FreeAligned( p );
- }
-
-private:
- // These ain't gonna work
- static void * operator new[] ( size_t size );
- static void operator delete [] ( void *p);
-
-public:
-
- CTSListBase()
- {
- if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
- {
- Error( "CTSListBase: Misaligned list\n" );
- DebuggerBreak();
- }
-
-#ifdef USE_NATIVE_SLIST
- InitializeSListHead( &m_Head );
-#elif defined(PLATFORM_64BITS)
- m_Head.value64x128 = int128_zero();
-#else
- m_Head.value64x128 = (int64)0;
-#endif
- }
-
- ~CTSListBase()
- {
- Detach();
- }
-
- TSLNodeBase_t *Push( TSLNodeBase_t *pNode )
- {
-#ifdef _DEBUG
- if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
- {
- Error( "CTSListBase: Misaligned node\n" );
- DebuggerBreak();
- }
-#endif
-
-#ifdef USE_NATIVE_SLIST
-#ifdef _X360
- // integrated write-release barrier
- return (TSLNodeBase_t *)InterlockedPushEntrySListRelease( &m_Head, pNode );
-#else
- return (TSLNodeBase_t *)InterlockedPushEntrySList( &m_Head, pNode );
-#endif
-#else
- TSLHead_t oldHead;
- TSLHead_t newHead;
-
- #if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
- __lwsync(); // write-release barrier
- #endif
-
-#ifdef PLATFORM_64BITS
- newHead.value.Padding = 0;
-#endif
- for (;;)
- {
- oldHead.value64x128 = m_Head.value64x128;
- pNode->Next = oldHead.value.Next;
- newHead.value.Next = pNode;
-
- newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence + 0x10001;
-
-
- if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
- {
- break;
- }
- ThreadPause();
- };
-
- return (TSLNodeBase_t *)oldHead.value.Next;
-#endif
- }
-
- TSLNodeBase_t *Pop()
- {
-#ifdef USE_NATIVE_SLIST
-#ifdef _X360
- // integrated read-acquire barrier
- TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySListAcquire( &m_Head );
-#else
- TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySList( &m_Head );
-#endif
- return pNode;
-#else
- TSLHead_t oldHead;
- TSLHead_t newHead;
-
-#ifdef PLATFORM_64BITS
- newHead.value.Padding = 0;
-#endif
- for (;;)
- {
- oldHead.value64x128 = m_Head.value64x128;
- if ( !oldHead.value.Next )
- return NULL;
-
- newHead.value.Next = oldHead.value.Next->Next;
- newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1;
-
-
- if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
- {
- #if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
- __lwsync(); // read-acquire barrier
- #endif
- break;
- }
- ThreadPause();
- };
-
- return (TSLNodeBase_t *)oldHead.value.Next;
-#endif
- }
-
- TSLNodeBase_t *Detach()
- {
-#ifdef USE_NATIVE_SLIST
- TSLNodeBase_t *pBase = (TSLNodeBase_t *)InterlockedFlushSList( &m_Head );
-#if defined( _X360 ) || defined( _PS3 )
- __lwsync(); // read-acquire barrier
-#endif
- return pBase;
-#else
- TSLHead_t oldHead;
- TSLHead_t newHead;
-
-#ifdef PLATFORM_64BITS
- newHead.value.Padding = 0;
-#endif
- do
- {
- ThreadPause();
-
- oldHead.value64x128 = m_Head.value64x128;
- if ( !oldHead.value.Next )
- return NULL;
-
- newHead.value.Next = NULL;
- // <sergiy> the reason for AND'ing it instead of poking a short into memory
- // is probably to avoid store forward issues, but I'm not sure because
- // I didn't construct this code. In any case, leaving it as is on big-endian
- newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence & 0xffff0000;
-
- } while( !ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) );
-
- return (TSLNodeBase_t *)oldHead.value.Next;
-#endif
- }
-
- TSLHead_t *AccessUnprotected()
- {
- return &m_Head;
- }
-
- int Count() const
- {
-#ifdef USE_NATIVE_SLIST
- return QueryDepthSList( const_cast<TSLHead_t*>( &m_Head ) );
-#else
- return m_Head.value.Depth;
-#endif
- }
-
-private:
- TSLHead_t m_Head;
-} TSLIST_HEAD_ALIGN_POST;
-
-//-------------------------------------
-
-template <typename T>
-class TSLIST_HEAD_ALIGN CTSSimpleList : public CTSListBase
-{
-public:
- void Push( T *pNode )
- {
- Assert( sizeof(T) >= sizeof(TSLNodeBase_t) );
- CTSListBase::Push( (TSLNodeBase_t *)pNode );
- }
-
- T *Pop()
- {
- return (T *)CTSListBase::Pop();
- }
-} TSLIST_HEAD_ALIGN_POST;
-
-//-------------------------------------
-// this is a replacement for CTSList<> and CObjectPool<> that does not
-// have a per-item, per-alloc new/delete overhead
-// similar to CTSSimpleList except that it allocates it's own pool objects
-// and frees them on destruct. Also it does not overlay the TSNodeBase_t memory
-// on T's memory
-template< class T >
-class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase
-{
- // packs the node and the item (T) into a single struct and pools those
- struct TSLIST_NODE_ALIGN simpleTSPoolStruct_t : public TSLNodeBase_t
- {
- T elem;
- } TSLIST_NODE_ALIGN_POST;
-
-public:
-
- ~CTSPool()
- {
- Purge();
- }
-
- void Purge()
- {
- simpleTSPoolStruct_t *pNode = NULL;
- while ( 1 )
- {
- pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
- if ( !pNode )
- break;
- delete pNode;
- }
- }
-
- void PutObject( T *pInfo )
- {
- char *pElem = (char *)pInfo;
- pElem -= offsetof(simpleTSPoolStruct_t,elem);
- simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)pElem;
-
- CTSListBase::Push( pNode );
- }
-
- T *GetObject()
- {
- simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
- if ( !pNode )
- {
- pNode = new simpleTSPoolStruct_t;
- }
- return &pNode->elem;
- }
-
- // omg windows sdk - why do you #define GetObject()?
- FORCEINLINE T *Get()
- {
- return GetObject();
- }
-} TSLIST_HEAD_ALIGN_POST;
-//-------------------------------------
-
-template <typename T>
-class TSLIST_HEAD_ALIGN CTSList : public CTSListBase
-{
-public:
- struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
- {
- Node_t() {}
- Node_t( const T &init ) : elem( init ) {}
- T elem;
-
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size )
- {
- Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, __FILE__, __LINE__ );
- return pNode;
- }
-
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
- {
- Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, pFileName, nLine );
- return pNode;
- }
-
- static void operator delete( void *p)
- {
- MemAlloc_FreeAligned( p );
- }
- static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
- {
- MemAlloc_FreeAligned( p );
- }
-
- } TSLIST_NODE_ALIGN_POST;
-
- ~CTSList()
- {
- Purge();
- }
-
- void Purge()
- {
- Node_t *pCurrent = Detach();
- Node_t *pNext;
- while ( pCurrent )
- {
- pNext = (Node_t *)pCurrent->Next;
- delete pCurrent;
- pCurrent = pNext;
- }
- }
-
- void RemoveAll()
- {
- Purge();
- }
-
- Node_t *Push( Node_t *pNode )
- {
- return (Node_t *)CTSListBase::Push( pNode );
- }
-
- Node_t *Pop()
- {
- return (Node_t *)CTSListBase::Pop();
- }
-
- void PushItem( const T &init )
- {
- Push( new Node_t( init ) );
- }
-
- bool PopItem( T *pResult)
- {
- Node_t *pNode = Pop();
- if ( !pNode )
- return false;
- *pResult = pNode->elem;
- delete pNode;
- return true;
- }
-
- Node_t *Detach()
- {
- return (Node_t *)CTSListBase::Detach();
- }
-
-} TSLIST_HEAD_ALIGN_POST;
-
-//-------------------------------------
-
-template <typename T>
-class TSLIST_HEAD_ALIGN CTSListWithFreeList : public CTSListBase
-{
-public:
- struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
- {
- Node_t() {}
- Node_t( const T &init ) : elem( init ) {}
-
- T elem;
- } TSLIST_NODE_ALIGN_POST;
-
- ~CTSListWithFreeList()
- {
- Purge();
- }
-
- void Purge()
- {
- Node_t *pCurrent = Detach();
- Node_t *pNext;
- while ( pCurrent )
- {
- pNext = (Node_t *)pCurrent->Next;
- delete pCurrent;
- pCurrent = pNext;
- }
- pCurrent = (Node_t *)m_FreeList.Detach();
- while ( pCurrent )
- {
- pNext = (Node_t *)pCurrent->Next;
- delete pCurrent;
- pCurrent = pNext;
- }
- }
-
- void RemoveAll()
- {
- Node_t *pCurrent = Detach();
- Node_t *pNext;
- while ( pCurrent )
- {
- pNext = (Node_t *)pCurrent->Next;
- m_FreeList.Push( pCurrent );
- pCurrent = pNext;
- }
- }
-
- Node_t *Push( Node_t *pNode )
- {
- return (Node_t *)CTSListBase::Push( pNode );
- }
-
- Node_t *Pop()
- {
- return (Node_t *)CTSListBase::Pop();
- }
-
- void PushItem( const T &init )
- {
- Node_t *pNode = (Node_t *)m_FreeList.Pop();
- if ( !pNode )
- {
- pNode = new Node_t;
- }
- pNode->elem = init;
- Push( pNode );
- }
-
- bool PopItem( T *pResult)
- {
- Node_t *pNode = Pop();
- if ( !pNode )
- return false;
- *pResult = pNode->elem;
- m_FreeList.Push( pNode );
- return true;
- }
-
- Node_t *Detach()
- {
- return (Node_t *)CTSListBase::Detach();
- }
-
- void FreeNode( Node_t *pNode )
- {
- m_FreeList.Push( pNode );
- }
-
-private:
- CTSListBase m_FreeList;
-} TSLIST_HEAD_ALIGN_POST;
-
-//-----------------------------------------------------------------------------
-// Lock free queue
-//
-// A special consideration: the element type should be simple. This code
-// actually dereferences freed nodes as part of pop, but later detects
-// that. If the item in the queue is a complex type, only bad things can
-// come of that. Also, therefore, if you're using Push/Pop instead of
-// push item, be aware that the node memory cannot be freed until
-// all threads that might have been popping have completed the pop.
-// The PushItem()/PopItem() for handles this by keeping a persistent
-// free list. Dont mix Push/PushItem. Note also nodes will be freed at the end,
-// and are expected to have been allocated with operator new.
-//-----------------------------------------------------------------------------
-
-template <typename T, bool bTestOptimizer = false>
-class TSLIST_HEAD_ALIGN CTSQueue
-{
-public:
-
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size )
- {
- CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
- return pNode;
- }
-
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
- {
- CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
- return pNode;
- }
-
- static void operator delete( void *p)
- {
- MemAlloc_FreeAligned( p );
- }
-
- static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
- {
- MemAlloc_FreeAligned( p );
- }
-
-private:
- // These ain't gonna work
- static void * operator new[] ( size_t size ) throw()
- {
- return NULL;
- }
-
- static void operator delete [] ( void *p)
- {
- }
-
-public:
-
- struct TSLIST_NODE_ALIGN Node_t
- {
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size )
- {
- Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
- return pNode;
- }
-
- static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
- {
- Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
- return pNode;
- }
-
- static void operator delete( void *p)
- {
- MemAlloc_FreeAligned( p );
- }
-
- static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
- {
- MemAlloc_FreeAligned( p );
- }
-
- Node_t() {}
- Node_t( const T &init ) : elem( init ) {}
-
- Node_t *pNext;
- T elem;
- } TSLIST_NODE_ALIGN_POST;
-
- union TSLIST_HEAD_ALIGN NodeLink_t
- {
- // override new/delete so we can guarantee 8-byte aligned allocs
- static void * operator new( size_t size )
- {
- NodeLink_t *pNode = (NodeLink_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
- return pNode;
- }
-
- static void operator delete( void *p)
- {
- MemAlloc_FreeAligned( p );
- }
-
- struct Value_t
- {
- Node_t *pNode;
- intp sequence;
- } value;
-
-#ifdef PLATFORM_64BITS
- int128 value64x128;
-#else
- int64 value64x128;
-#endif
- } TSLIST_HEAD_ALIGN_POST;
-
- CTSQueue()
- {
- COMPILE_TIME_ASSERT( sizeof(Node_t) >= sizeof(TSLNodeBase_t) );
- if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
- {
- Error( "CTSQueue: Misaligned queue\n" );
- DebuggerBreak();
- }
- if ( ((size_t)&m_Tail) % TSLIST_HEAD_ALIGNMENT != 0 )
- {
- Error( "CTSQueue: Misaligned queue\n" );
- DebuggerBreak();
- }
- m_Count = 0;
- m_Head.value.sequence = m_Tail.value.sequence = 0;
- m_Head.value.pNode = m_Tail.value.pNode = new Node_t; // list always contains a dummy node
- m_Head.value.pNode->pNext = End();
- }
-
- ~CTSQueue()
- {
- Purge();
- Assert( m_Count == 0 );
- Assert( m_Head.value.pNode == m_Tail.value.pNode );
- Assert( m_Head.value.pNode->pNext == End() );
- delete m_Head.value.pNode;
- }
-
- // Note: Purge, RemoveAll, and Validate are *not* threadsafe
- void Purge()
- {
- if ( IsDebug() )
- {
- ValidateQueue();
- }
-
- Node_t *pNode;
- while ( ( pNode = Pop() ) != NULL )
- {
- delete pNode;
- }
-
- while ( ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL )
- {
- delete pNode;
- }
-
- Assert( m_Count == 0 );
- Assert( m_Head.value.pNode == m_Tail.value.pNode );
- Assert( m_Head.value.pNode->pNext == End() );
-
- m_Head.value.sequence = m_Tail.value.sequence = 0;
- }
-
- void RemoveAll()
- {
- if ( IsDebug() )
- {
- ValidateQueue();
- }
-
- Node_t *pNode;
- while ( ( pNode = Pop() ) != NULL )
- {
- m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
- }
- }
-
- bool ValidateQueue()
- {
- if ( IsDebug() )
- {
- bool bResult = true;
- int nNodes = 0;
- if ( m_Tail.value.pNode->pNext != End() )
- {
- DebuggerBreakIfDebugging();
- bResult = false;
- }
-
- if ( m_Count == 0 )
- {
- if ( m_Head.value.pNode != m_Tail.value.pNode )
- {
- DebuggerBreakIfDebugging();
- bResult = false;
- }
- }
-
- Node_t *pNode = m_Head.value.pNode;
- while ( pNode != End() )
- {
- nNodes++;
- pNode = pNode->pNext;
- }
-
- nNodes--;// skip dummy node
-
- if ( nNodes != m_Count )
- {
- DebuggerBreakIfDebugging();
- bResult = false;
- }
-
- if ( !bResult )
- {
- Msg( "Corrupt CTSQueueDetected" );
- }
-
- return bResult;
- }
- else
- {
- return true;
- }
- }
-
- void FinishPush( Node_t *pNode, const NodeLink_t &oldTail )
- {
- NodeLink_t newTail;
-
- newTail.value.pNode = pNode;
- newTail.value.sequence = oldTail.value.sequence + 1;
-
- ThreadMemoryBarrier();
-
- InterlockedCompareExchangeNodeLink( &m_Tail, newTail, oldTail );
- }
-
- Node_t *Push( Node_t *pNode )
- {
-#ifdef _DEBUG
- if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
- {
- Error( "CTSListBase: Misaligned node\n" );
- DebuggerBreak();
- }
-#endif
-
- NodeLink_t oldTail;
-
- pNode->pNext = End();
-
- for (;;)
- {
- oldTail.value.sequence = m_Tail.value.sequence;
- oldTail.value.pNode = m_Tail.value.pNode;
- if ( InterlockedCompareExchangeNode( &(oldTail.value.pNode->pNext), pNode, End() ) == End() )
- {
- break;
- }
- else
- {
- // Another thread is trying to push, help it along
- FinishPush( oldTail.value.pNode->pNext, oldTail );
- }
- }
-
- FinishPush( pNode, oldTail ); // This can fail if another thread pushed between the sequence and node grabs above. Later pushes or pops corrects
-
- m_Count++;
-
- return oldTail.value.pNode;
- }
-
- Node_t *Pop()
- {
- #define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) )
- NodeLink_t * volatile pHead = &m_Head;
- NodeLink_t * volatile pTail = &m_Tail;
- Node_t * volatile * pHeadNode = &m_Head.value.pNode;
- volatile intp * volatile pHeadSequence = &m_Head.value.sequence;
- Node_t * volatile * pTailNode = &pTail->value.pNode;
-
- NodeLink_t head;
- NodeLink_t newHead;
- Node_t *pNext;
- intp tailSequence;
- T elem;
-
- for (;;)
- {
- head.value.sequence = *pHeadSequence; // must grab sequence first, which allows condition below to ensure pNext is valid
- ThreadMemoryBarrier(); // need a barrier to prevent reordering of these assignments
- head.value.pNode = *pHeadNode;
- tailSequence = pTail->value.sequence;
- pNext = head.value.pNode->pNext;
-
- // Checking pNext only to force optimizer to not reorder the assignment
- // to pNext and the compare of the sequence
- if ( !pNext || head.value.sequence != *pHeadSequence )
- continue;
-
- if ( bTestOptimizer )
- {
- if ( pNext == TSQUEUE_BAD_NODE_LINK )
- {
- Msg( "Bad node link detected\n" );
- continue;
- }
- }
-
- if ( head.value.pNode == *pTailNode )
- {
- if ( pNext == End() )
- return NULL;
-
- // Another thread is trying to push, help it along
- NodeLink_t &oldTail = head; // just reuse local memory for head to build old tail
- oldTail.value.sequence = tailSequence; // reuse head pNode
- FinishPush( pNext, oldTail );
- continue;
- }
-
- if ( pNext != End() )
- {
- elem = pNext->elem; // NOTE: next could be a freed node here, by design
- newHead.value.pNode = pNext;
- newHead.value.sequence = head.value.sequence + 1;
- if ( InterlockedCompareExchangeNodeLink( pHead, newHead, head ) )
- {
- ThreadMemoryBarrier();
- if ( bTestOptimizer )
- {
- head.value.pNode->pNext = TSQUEUE_BAD_NODE_LINK;
- }
- break;
- }
- }
- }
-
- m_Count--;
- head.value.pNode->elem = elem;
- return head.value.pNode;
- }
-
- void FreeNode( Node_t *pNode )
- {
- m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
- }
-
- void PushItem( const T &init )
- {
- Node_t *pNode = (Node_t *)m_FreeNodes.Pop();
- if ( pNode )
- {
- pNode->elem = init;
- }
- else
- {
- pNode = new Node_t( init );
- }
- Push( pNode );
- }
-
- bool PopItem( T *pResult )
- {
- Node_t *pNode = Pop();
- if ( !pNode )
- return false;
-
- *pResult = pNode->elem;
- m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
- return true;
- }
-
- int Count() const
- {
- return m_Count;
- }
-
-private:
- Node_t *End() { return (Node_t *)this; } // just need a unique signifier
-
- Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand )
- {
- return (Node_t *)::ThreadInterlockedCompareExchangePointer( (void **)ppNode, value, comperand );
- }
-
- bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand )
- {
- return ThreadInterlockedAssignIf64x128( &pLink->value64x128, value.value64x128, comperand.value64x128 );
- }
-
- NodeLink_t m_Head;
- NodeLink_t m_Tail;
-
- CInterlockedInt m_Count;
-
- CTSListBase m_FreeNodes;
-} TSLIST_NODE_ALIGN_POST;
-
-#if defined( _WIN32 )
-// Suppress this spurious warning:
-// warning C4700: uninitialized local variable 'oldHead' used
-#pragma warning( pop )
-#endif
-
-#endif // TSLIST_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// LIFO from disassembly of Windows API and http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
+// FIFO from http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
+//
+//=============================================================================
+
+#ifndef TSLIST_H
+#define TSLIST_H
+
+#if defined( _WIN32 )
+#pragma once
+// Suppress this spurious warning:
+// warning C4700: uninitialized local variable 'oldHead' used
+#pragma warning( push )
+#pragma warning( disable : 4700 )
+#endif
+
+#if defined( USE_NATIVE_SLIST ) && !defined( _X360 )
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+#include "tier0/dbg.h"
+#include "tier0/threadtools.h"
+#include "tier0/memalloc.h"
+#include "tier0/memdbgoff.h"
+
+#if defined( _X360 )
+#define USE_NATIVE_SLIST
+#endif
+
+//-----------------------------------------------------------------------------
+
+#if defined( PLATFORM_64BITS )
+
+#define TSLIST_HEAD_ALIGNMENT 16
+#define TSLIST_NODE_ALIGNMENT 16
+inline bool ThreadInterlockedAssignIf64x128( volatile int128 *pDest, const int128 &value, const int128 &comperand )
+ { return ThreadInterlockedAssignIf128( pDest, value, comperand ); }
+#else
+#define TSLIST_HEAD_ALIGNMENT 8
+#define TSLIST_NODE_ALIGNMENT 8
+inline bool ThreadInterlockedAssignIf64x128( volatile int64 *pDest, const int64 value, const int64 comperand )
+ { return ThreadInterlockedAssignIf64( pDest, value, comperand ); }
+#endif
+
+#ifdef _MSC_VER
+#define TSLIST_HEAD_ALIGN DECL_ALIGN(TSLIST_HEAD_ALIGNMENT)
+#define TSLIST_NODE_ALIGN DECL_ALIGN(TSLIST_NODE_ALIGNMENT)
+#define TSLIST_HEAD_ALIGN_POST
+#define TSLIST_NODE_ALIGN_POST
+#elif defined( GNUC )
+#define TSLIST_HEAD_ALIGN
+#define TSLIST_NODE_ALIGN
+#define TSLIST_HEAD_ALIGN_POST DECL_ALIGN(TSLIST_HEAD_ALIGNMENT)
+#define TSLIST_NODE_ALIGN_POST DECL_ALIGN(TSLIST_NODE_ALIGNMENT)
+#elif defined( _PS3 )
+#define TSLIST_HEAD_ALIGNMENT 8
+#define TSLIST_NODE_ALIGNMENT 8
+
+#define TSLIST_HEAD_ALIGN ALIGN8
+#define TSLIST_NODE_ALIGN ALIGN8
+#define TSLIST_HEAD_ALIGN_POST ALIGN8_POST
+#define TSLIST_NODE_ALIGN_POST ALIGN8_POST
+
+#else
+#error
+#endif
+
+//-----------------------------------------------------------------------------
+
+PLATFORM_INTERFACE bool RunTSQueueTests( int nListSize = 10000, int nTests = 1 );
+PLATFORM_INTERFACE bool RunTSListTests( int nListSize = 10000, int nTests = 1 );
+
+//-----------------------------------------------------------------------------
+// Lock free list.
+//-----------------------------------------------------------------------------
+//#define USE_NATIVE_SLIST
+
+#ifdef USE_NATIVE_SLIST
+typedef SLIST_ENTRY TSLNodeBase_t;
+typedef SLIST_HEADER TSLHead_t;
+#else
+struct TSLIST_NODE_ALIGN TSLNodeBase_t
+{
+ TSLNodeBase_t *Next; // name to match Windows
+} TSLIST_NODE_ALIGN_POST;
+
+union TSLIST_HEAD_ALIGN TSLHead_t
+{
+ struct Value_t
+ {
+ TSLNodeBase_t *Next;
+ // <sergiy> Depth must be in the least significant halfword when atomically loading into register,
+ // to avoid carrying digits from Sequence. Carrying digits from Depth to Sequence is ok,
+ // because Sequence can be pretty much random. We could operate on both of them separately,
+ // but it could perhaps (?) lead to problems with store forwarding. I don't know 'cause I didn't
+ // performance-test or design original code, I'm just making it work on PowerPC.
+ #ifdef VALVE_BIG_ENDIAN
+ int16 Sequence;
+ int16 Depth;
+ #else
+ int16 Depth;
+ int16 Sequence;
+ #endif
+#ifdef PLATFORM_64BITS
+ int32 Padding;
+#endif
+ } value;
+
+ struct Value32_t
+ {
+ TSLNodeBase_t *Next_do_not_use_me;
+ int32 DepthAndSequence;
+ } value32;
+
+#ifdef PLATFORM_64BITS
+ int128 value64x128;
+#else
+ int64 value64x128;
+#endif
+} TSLIST_HEAD_ALIGN_POST;
+
+#endif
+
+//-------------------------------------
+class CTSListBase
+{
+public:
+
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size )
+ {
+ CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
+ return pNode;
+ }
+
+ static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
+ {
+ CTSListBase *pNode = (CTSListBase *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
+ return pNode;
+ }
+
+ static void operator delete( void *p)
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+private:
+ // These ain't gonna work
+ static void * operator new[] ( size_t size );
+ static void operator delete [] ( void *p);
+
+public:
+
+ CTSListBase()
+ {
+ if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
+ {
+ Error( "CTSListBase: Misaligned list\n" );
+ DebuggerBreak();
+ }
+
+#ifdef USE_NATIVE_SLIST
+ InitializeSListHead( &m_Head );
+#elif defined(PLATFORM_64BITS)
+ m_Head.value64x128 = int128_zero();
+#else
+ m_Head.value64x128 = (int64)0;
+#endif
+ }
+
+ ~CTSListBase()
+ {
+ Detach();
+ }
+
+ TSLNodeBase_t *Push( TSLNodeBase_t *pNode )
+ {
+#ifdef _DEBUG
+ if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
+ {
+ Error( "CTSListBase: Misaligned node\n" );
+ DebuggerBreak();
+ }
+#endif
+
+#ifdef USE_NATIVE_SLIST
+#ifdef _X360
+ // integrated write-release barrier
+ return (TSLNodeBase_t *)InterlockedPushEntrySListRelease( &m_Head, pNode );
+#else
+ return (TSLNodeBase_t *)InterlockedPushEntrySList( &m_Head, pNode );
+#endif
+#else
+ TSLHead_t oldHead;
+ TSLHead_t newHead;
+
+ #if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
+ __lwsync(); // write-release barrier
+ #endif
+
+#ifdef PLATFORM_64BITS
+ newHead.value.Padding = 0;
+#endif
+ for (;;)
+ {
+ oldHead.value64x128 = m_Head.value64x128;
+ pNode->Next = oldHead.value.Next;
+ newHead.value.Next = pNode;
+
+ newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence + 0x10001;
+
+
+ if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
+ {
+ break;
+ }
+ ThreadPause();
+ };
+
+ return (TSLNodeBase_t *)oldHead.value.Next;
+#endif
+ }
+
+ TSLNodeBase_t *Pop()
+ {
+#ifdef USE_NATIVE_SLIST
+#ifdef _X360
+ // integrated read-acquire barrier
+ TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySListAcquire( &m_Head );
+#else
+ TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySList( &m_Head );
+#endif
+ return pNode;
+#else
+ TSLHead_t oldHead;
+ TSLHead_t newHead;
+
+#ifdef PLATFORM_64BITS
+ newHead.value.Padding = 0;
+#endif
+ for (;;)
+ {
+ oldHead.value64x128 = m_Head.value64x128;
+ if ( !oldHead.value.Next )
+ return NULL;
+
+ newHead.value.Next = oldHead.value.Next->Next;
+ newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1;
+
+
+ if ( ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) )
+ {
+ #if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
+ __lwsync(); // read-acquire barrier
+ #endif
+ break;
+ }
+ ThreadPause();
+ };
+
+ return (TSLNodeBase_t *)oldHead.value.Next;
+#endif
+ }
+
+ TSLNodeBase_t *Detach()
+ {
+#ifdef USE_NATIVE_SLIST
+ TSLNodeBase_t *pBase = (TSLNodeBase_t *)InterlockedFlushSList( &m_Head );
+#if defined( _X360 ) || defined( _PS3 )
+ __lwsync(); // read-acquire barrier
+#endif
+ return pBase;
+#else
+ TSLHead_t oldHead;
+ TSLHead_t newHead;
+
+#ifdef PLATFORM_64BITS
+ newHead.value.Padding = 0;
+#endif
+ do
+ {
+ ThreadPause();
+
+ oldHead.value64x128 = m_Head.value64x128;
+ if ( !oldHead.value.Next )
+ return NULL;
+
+ newHead.value.Next = NULL;
+ // <sergiy> the reason for AND'ing it instead of poking a short into memory
+ // is probably to avoid store forward issues, but I'm not sure because
+ // I didn't construct this code. In any case, leaving it as is on big-endian
+ newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence & 0xffff0000;
+
+ } while( !ThreadInterlockedAssignIf64x128( &m_Head.value64x128, newHead.value64x128, oldHead.value64x128 ) );
+
+ return (TSLNodeBase_t *)oldHead.value.Next;
+#endif
+ }
+
+ TSLHead_t *AccessUnprotected()
+ {
+ return &m_Head;
+ }
+
+ int Count() const
+ {
+#ifdef USE_NATIVE_SLIST
+ return QueryDepthSList( const_cast<TSLHead_t*>( &m_Head ) );
+#else
+ return m_Head.value.Depth;
+#endif
+ }
+
+private:
+ TSLHead_t m_Head;
+} TSLIST_HEAD_ALIGN_POST;
+
+//-------------------------------------
+
+template <typename T>
+class TSLIST_HEAD_ALIGN CTSSimpleList : public CTSListBase
+{
+public:
+ void Push( T *pNode )
+ {
+ Assert( sizeof(T) >= sizeof(TSLNodeBase_t) );
+ CTSListBase::Push( (TSLNodeBase_t *)pNode );
+ }
+
+ T *Pop()
+ {
+ return (T *)CTSListBase::Pop();
+ }
+} TSLIST_HEAD_ALIGN_POST;
+
+//-------------------------------------
+// this is a replacement for CTSList<> and CObjectPool<> that does not
+// have a per-item, per-alloc new/delete overhead
+// similar to CTSSimpleList except that it allocates it's own pool objects
+// and frees them on destruct. Also it does not overlay the TSNodeBase_t memory
+// on T's memory
+template< class T >
+class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase
+{
+ // packs the node and the item (T) into a single struct and pools those
+ struct TSLIST_NODE_ALIGN simpleTSPoolStruct_t : public TSLNodeBase_t
+ {
+ T elem;
+ } TSLIST_NODE_ALIGN_POST;
+
+public:
+
+ ~CTSPool()
+ {
+ Purge();
+ }
+
+ void Purge()
+ {
+ simpleTSPoolStruct_t *pNode = NULL;
+ while ( 1 )
+ {
+ pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
+ if ( !pNode )
+ break;
+ delete pNode;
+ }
+ }
+
+ void PutObject( T *pInfo )
+ {
+ char *pElem = (char *)pInfo;
+ pElem -= offsetof(simpleTSPoolStruct_t,elem);
+ simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)pElem;
+
+ CTSListBase::Push( pNode );
+ }
+
+ T *GetObject()
+ {
+ simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
+ if ( !pNode )
+ {
+ pNode = new simpleTSPoolStruct_t;
+ }
+ return &pNode->elem;
+ }
+
+ // omg windows sdk - why do you #define GetObject()?
+ FORCEINLINE T *Get()
+ {
+ return GetObject();
+ }
+} TSLIST_HEAD_ALIGN_POST;
+//-------------------------------------
+
+template <typename T>
+class TSLIST_HEAD_ALIGN CTSList : public CTSListBase
+{
+public:
+ struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
+ {
+ Node_t() {}
+ Node_t( const T &init ) : elem( init ) {}
+ T elem;
+
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size )
+ {
+ Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, __FILE__, __LINE__ );
+ return pNode;
+ }
+
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
+ {
+ Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_NODE_ALIGNMENT, pFileName, nLine );
+ return pNode;
+ }
+
+ static void operator delete( void *p)
+ {
+ MemAlloc_FreeAligned( p );
+ }
+ static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ } TSLIST_NODE_ALIGN_POST;
+
+ ~CTSList()
+ {
+ Purge();
+ }
+
+ void Purge()
+ {
+ Node_t *pCurrent = Detach();
+ Node_t *pNext;
+ while ( pCurrent )
+ {
+ pNext = (Node_t *)pCurrent->Next;
+ delete pCurrent;
+ pCurrent = pNext;
+ }
+ }
+
+ void RemoveAll()
+ {
+ Purge();
+ }
+
+ Node_t *Push( Node_t *pNode )
+ {
+ return (Node_t *)CTSListBase::Push( pNode );
+ }
+
+ Node_t *Pop()
+ {
+ return (Node_t *)CTSListBase::Pop();
+ }
+
+ void PushItem( const T &init )
+ {
+ Push( new Node_t( init ) );
+ }
+
+ bool PopItem( T *pResult)
+ {
+ Node_t *pNode = Pop();
+ if ( !pNode )
+ return false;
+ *pResult = pNode->elem;
+ delete pNode;
+ return true;
+ }
+
+ Node_t *Detach()
+ {
+ return (Node_t *)CTSListBase::Detach();
+ }
+
+} TSLIST_HEAD_ALIGN_POST;
+
+//-------------------------------------
+
+template <typename T>
+class TSLIST_HEAD_ALIGN CTSListWithFreeList : public CTSListBase
+{
+public:
+ struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
+ {
+ Node_t() {}
+ Node_t( const T &init ) : elem( init ) {}
+
+ T elem;
+ } TSLIST_NODE_ALIGN_POST;
+
+ ~CTSListWithFreeList()
+ {
+ Purge();
+ }
+
+ void Purge()
+ {
+ Node_t *pCurrent = Detach();
+ Node_t *pNext;
+ while ( pCurrent )
+ {
+ pNext = (Node_t *)pCurrent->Next;
+ delete pCurrent;
+ pCurrent = pNext;
+ }
+ pCurrent = (Node_t *)m_FreeList.Detach();
+ while ( pCurrent )
+ {
+ pNext = (Node_t *)pCurrent->Next;
+ delete pCurrent;
+ pCurrent = pNext;
+ }
+ }
+
+ void RemoveAll()
+ {
+ Node_t *pCurrent = Detach();
+ Node_t *pNext;
+ while ( pCurrent )
+ {
+ pNext = (Node_t *)pCurrent->Next;
+ m_FreeList.Push( pCurrent );
+ pCurrent = pNext;
+ }
+ }
+
+ Node_t *Push( Node_t *pNode )
+ {
+ return (Node_t *)CTSListBase::Push( pNode );
+ }
+
+ Node_t *Pop()
+ {
+ return (Node_t *)CTSListBase::Pop();
+ }
+
+ void PushItem( const T &init )
+ {
+ Node_t *pNode = (Node_t *)m_FreeList.Pop();
+ if ( !pNode )
+ {
+ pNode = new Node_t;
+ }
+ pNode->elem = init;
+ Push( pNode );
+ }
+
+ bool PopItem( T *pResult)
+ {
+ Node_t *pNode = Pop();
+ if ( !pNode )
+ return false;
+ *pResult = pNode->elem;
+ m_FreeList.Push( pNode );
+ return true;
+ }
+
+ Node_t *Detach()
+ {
+ return (Node_t *)CTSListBase::Detach();
+ }
+
+ void FreeNode( Node_t *pNode )
+ {
+ m_FreeList.Push( pNode );
+ }
+
+private:
+ CTSListBase m_FreeList;
+} TSLIST_HEAD_ALIGN_POST;
+
+//-----------------------------------------------------------------------------
+// Lock free queue
+//
+// A special consideration: the element type should be simple. This code
+// actually dereferences freed nodes as part of pop, but later detects
+// that. If the item in the queue is a complex type, only bad things can
+// come of that. Also, therefore, if you're using Push/Pop instead of
+// push item, be aware that the node memory cannot be freed until
+// all threads that might have been popping have completed the pop.
+// The PushItem()/PopItem() for handles this by keeping a persistent
+// free list. Dont mix Push/PushItem. Note also nodes will be freed at the end,
+// and are expected to have been allocated with operator new.
+//-----------------------------------------------------------------------------
+
+template <typename T, bool bTestOptimizer = false>
+class TSLIST_HEAD_ALIGN CTSQueue
+{
+public:
+
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size )
+ {
+ CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
+ return pNode;
+ }
+
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
+ {
+ CTSQueue *pNode = (CTSQueue *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
+ return pNode;
+ }
+
+ static void operator delete( void *p)
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+private:
+ // These ain't gonna work
+ static void * operator new[] ( size_t size ) throw()
+ {
+ return NULL;
+ }
+
+ static void operator delete [] ( void *p)
+ {
+ }
+
+public:
+
+ struct TSLIST_NODE_ALIGN Node_t
+ {
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size )
+ {
+ Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
+ return pNode;
+ }
+
+ static void * operator new( size_t size, int nBlockUse, const char *pFileName, int nLine )
+ {
+ Node_t *pNode = (Node_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, pFileName, nLine );
+ return pNode;
+ }
+
+ static void operator delete( void *p)
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ static void operator delete( void *p, int nBlockUse, const char *pFileName, int nLine )
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ Node_t() {}
+ Node_t( const T &init ) : elem( init ) {}
+
+ Node_t *pNext;
+ T elem;
+ } TSLIST_NODE_ALIGN_POST;
+
+ union TSLIST_HEAD_ALIGN NodeLink_t
+ {
+ // override new/delete so we can guarantee 8-byte aligned allocs
+ static void * operator new( size_t size )
+ {
+ NodeLink_t *pNode = (NodeLink_t *)MemAlloc_AllocAligned( size, TSLIST_HEAD_ALIGNMENT, __FILE__, __LINE__ );
+ return pNode;
+ }
+
+ static void operator delete( void *p)
+ {
+ MemAlloc_FreeAligned( p );
+ }
+
+ struct Value_t
+ {
+ Node_t *pNode;
+ intp sequence;
+ } value;
+
+#ifdef PLATFORM_64BITS
+ int128 value64x128;
+#else
+ int64 value64x128;
+#endif
+ } TSLIST_HEAD_ALIGN_POST;
+
+ CTSQueue()
+ {
+ COMPILE_TIME_ASSERT( sizeof(Node_t) >= sizeof(TSLNodeBase_t) );
+ if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
+ {
+ Error( "CTSQueue: Misaligned queue\n" );
+ DebuggerBreak();
+ }
+ if ( ((size_t)&m_Tail) % TSLIST_HEAD_ALIGNMENT != 0 )
+ {
+ Error( "CTSQueue: Misaligned queue\n" );
+ DebuggerBreak();
+ }
+ m_Count = 0;
+ m_Head.value.sequence = m_Tail.value.sequence = 0;
+ m_Head.value.pNode = m_Tail.value.pNode = new Node_t; // list always contains a dummy node
+ m_Head.value.pNode->pNext = End();
+ }
+
+ ~CTSQueue()
+ {
+ Purge();
+ Assert( m_Count == 0 );
+ Assert( m_Head.value.pNode == m_Tail.value.pNode );
+ Assert( m_Head.value.pNode->pNext == End() );
+ delete m_Head.value.pNode;
+ }
+
+ // Note: Purge, RemoveAll, and Validate are *not* threadsafe
+ void Purge()
+ {
+ if ( IsDebug() )
+ {
+ ValidateQueue();
+ }
+
+ Node_t *pNode;
+ while ( ( pNode = Pop() ) != NULL )
+ {
+ delete pNode;
+ }
+
+ while ( ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL )
+ {
+ delete pNode;
+ }
+
+ Assert( m_Count == 0 );
+ Assert( m_Head.value.pNode == m_Tail.value.pNode );
+ Assert( m_Head.value.pNode->pNext == End() );
+
+ m_Head.value.sequence = m_Tail.value.sequence = 0;
+ }
+
+ void RemoveAll()
+ {
+ if ( IsDebug() )
+ {
+ ValidateQueue();
+ }
+
+ Node_t *pNode;
+ while ( ( pNode = Pop() ) != NULL )
+ {
+ m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
+ }
+ }
+
+ bool ValidateQueue()
+ {
+ if ( IsDebug() )
+ {
+ bool bResult = true;
+ int nNodes = 0;
+ if ( m_Tail.value.pNode->pNext != End() )
+ {
+ DebuggerBreakIfDebugging();
+ bResult = false;
+ }
+
+ if ( m_Count == 0 )
+ {
+ if ( m_Head.value.pNode != m_Tail.value.pNode )
+ {
+ DebuggerBreakIfDebugging();
+ bResult = false;
+ }
+ }
+
+ Node_t *pNode = m_Head.value.pNode;
+ while ( pNode != End() )
+ {
+ nNodes++;
+ pNode = pNode->pNext;
+ }
+
+ nNodes--;// skip dummy node
+
+ if ( nNodes != m_Count )
+ {
+ DebuggerBreakIfDebugging();
+ bResult = false;
+ }
+
+ if ( !bResult )
+ {
+ Msg( "Corrupt CTSQueueDetected" );
+ }
+
+ return bResult;
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ void FinishPush( Node_t *pNode, const NodeLink_t &oldTail )
+ {
+ NodeLink_t newTail;
+
+ newTail.value.pNode = pNode;
+ newTail.value.sequence = oldTail.value.sequence + 1;
+
+ ThreadMemoryBarrier();
+
+ InterlockedCompareExchangeNodeLink( &m_Tail, newTail, oldTail );
+ }
+
+ Node_t *Push( Node_t *pNode )
+ {
+#ifdef _DEBUG
+ if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
+ {
+ Error( "CTSListBase: Misaligned node\n" );
+ DebuggerBreak();
+ }
+#endif
+
+ NodeLink_t oldTail;
+
+ pNode->pNext = End();
+
+ for (;;)
+ {
+ oldTail.value.sequence = m_Tail.value.sequence;
+ oldTail.value.pNode = m_Tail.value.pNode;
+ if ( InterlockedCompareExchangeNode( &(oldTail.value.pNode->pNext), pNode, End() ) == End() )
+ {
+ break;
+ }
+ else
+ {
+ // Another thread is trying to push, help it along
+ FinishPush( oldTail.value.pNode->pNext, oldTail );
+ }
+ }
+
+ FinishPush( pNode, oldTail ); // This can fail if another thread pushed between the sequence and node grabs above. Later pushes or pops corrects
+
+ m_Count++;
+
+ return oldTail.value.pNode;
+ }
+
+ Node_t *Pop()
+ {
+ #define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) )
+ NodeLink_t * volatile pHead = &m_Head;
+ NodeLink_t * volatile pTail = &m_Tail;
+ Node_t * volatile * pHeadNode = &m_Head.value.pNode;
+ volatile intp * volatile pHeadSequence = &m_Head.value.sequence;
+ Node_t * volatile * pTailNode = &pTail->value.pNode;
+
+ NodeLink_t head;
+ NodeLink_t newHead;
+ Node_t *pNext;
+ intp tailSequence;
+ T elem;
+
+ for (;;)
+ {
+ head.value.sequence = *pHeadSequence; // must grab sequence first, which allows condition below to ensure pNext is valid
+ ThreadMemoryBarrier(); // need a barrier to prevent reordering of these assignments
+ head.value.pNode = *pHeadNode;
+ tailSequence = pTail->value.sequence;
+ pNext = head.value.pNode->pNext;
+
+ // Checking pNext only to force optimizer to not reorder the assignment
+ // to pNext and the compare of the sequence
+ if ( !pNext || head.value.sequence != *pHeadSequence )
+ continue;
+
+ if ( bTestOptimizer )
+ {
+ if ( pNext == TSQUEUE_BAD_NODE_LINK )
+ {
+ Msg( "Bad node link detected\n" );
+ continue;
+ }
+ }
+
+ if ( head.value.pNode == *pTailNode )
+ {
+ if ( pNext == End() )
+ return NULL;
+
+ // Another thread is trying to push, help it along
+ NodeLink_t &oldTail = head; // just reuse local memory for head to build old tail
+ oldTail.value.sequence = tailSequence; // reuse head pNode
+ FinishPush( pNext, oldTail );
+ continue;
+ }
+
+ if ( pNext != End() )
+ {
+ elem = pNext->elem; // NOTE: next could be a freed node here, by design
+ newHead.value.pNode = pNext;
+ newHead.value.sequence = head.value.sequence + 1;
+ if ( InterlockedCompareExchangeNodeLink( pHead, newHead, head ) )
+ {
+ ThreadMemoryBarrier();
+ if ( bTestOptimizer )
+ {
+ head.value.pNode->pNext = TSQUEUE_BAD_NODE_LINK;
+ }
+ break;
+ }
+ }
+ }
+
+ m_Count--;
+ head.value.pNode->elem = elem;
+ return head.value.pNode;
+ }
+
+ void FreeNode( Node_t *pNode )
+ {
+ m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
+ }
+
+ void PushItem( const T &init )
+ {
+ Node_t *pNode = (Node_t *)m_FreeNodes.Pop();
+ if ( pNode )
+ {
+ pNode->elem = init;
+ }
+ else
+ {
+ pNode = new Node_t( init );
+ }
+ Push( pNode );
+ }
+
+ bool PopItem( T *pResult )
+ {
+ Node_t *pNode = Pop();
+ if ( !pNode )
+ return false;
+
+ *pResult = pNode->elem;
+ m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
+ return true;
+ }
+
+ int Count() const
+ {
+ return m_Count;
+ }
+
+private:
+ Node_t *End() { return (Node_t *)this; } // just need a unique signifier
+
+ Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand )
+ {
+ return (Node_t *)::ThreadInterlockedCompareExchangePointer( (void **)ppNode, value, comperand );
+ }
+
+ bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand )
+ {
+ return ThreadInterlockedAssignIf64x128( &pLink->value64x128, value.value64x128, comperand.value64x128 );
+ }
+
+ NodeLink_t m_Head;
+ NodeLink_t m_Tail;
+
+ CInterlockedInt m_Count;
+
+ CTSListBase m_FreeNodes;
+} TSLIST_NODE_ALIGN_POST;
+
+#if defined( _WIN32 )
+// Suppress this spurious warning:
+// warning C4700: uninitialized local variable 'oldHead' used
+#pragma warning( pop )
+#endif
+
+#endif // TSLIST_H
diff --git a/sp/src/public/tier0/validator.h b/sp/src/public/tier0/validator.h
index 8a00f887..6af0f51a 100644
--- a/sp/src/public/tier0/validator.h
+++ b/sp/src/public/tier0/validator.h
@@ -1,73 +1,73 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#include "valobject.h"
-
-#ifndef VALIDATOR_H
-#define VALIDATOR_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#ifdef DBGFLAG_VALIDATE
-
-
-class CValidator
-{
-public:
- // Constructors & destructors
- CValidator( void );
- ~CValidator( void );
-
- // Call this each time we enter a new Validate function
- void Push( tchar *pchType, void *pvObj, tchar *pchName );
-
- // Call this each time we exit a Validate function
- void Pop( void );
-
- // Claim ownership of a memory block
- void ClaimMemory( void *pvMem );
-
- // Finish performing a check and perform necessary computations
- void Finalize( void );
-
- // Render our results to the console
- void RenderObjects( int cubThreshold ); // Render all reported objects
- void RenderLeaks( void ); // Render all memory leaks
-
- // List manipulation functions:
- CValObject *FindObject( void *pvObj ); // Returns CValObject containing pvObj, or NULL.
- void DiffAgainst( CValidator *pOtherValidator ); // Removes any entries from this validator that are also present in the other.
-
- // Accessors
- bool BMemLeaks( void ) { return m_bMemLeaks; };
- CValObject *PValObjectFirst( void ) { return m_pValObjectFirst; };
-
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-
-
-private:
- CValObject *m_pValObjectFirst; // Linked list of all ValObjects
- CValObject *m_pValObjectLast; // Last ValObject on the linked list
-
- CValObject *m_pValObjectCur; // Object we're current processing
-
- int m_cpvOwned; // Total # of blocks owned
-
- int m_cpubLeaked; // # of leaked memory blocks
- int m_cubLeaked; // Amount of leaked memory
- bool m_bMemLeaks; // Has any memory leaked?
-};
-
-
-#endif // DBGFLAG_VALIDATE
-
-
-#endif // VALIDATOR_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#include "valobject.h"
+
+#ifndef VALIDATOR_H
+#define VALIDATOR_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#ifdef DBGFLAG_VALIDATE
+
+
+class CValidator
+{
+public:
+ // Constructors & destructors
+ CValidator( void );
+ ~CValidator( void );
+
+ // Call this each time we enter a new Validate function
+ void Push( tchar *pchType, void *pvObj, tchar *pchName );
+
+ // Call this each time we exit a Validate function
+ void Pop( void );
+
+ // Claim ownership of a memory block
+ void ClaimMemory( void *pvMem );
+
+ // Finish performing a check and perform necessary computations
+ void Finalize( void );
+
+ // Render our results to the console
+ void RenderObjects( int cubThreshold ); // Render all reported objects
+ void RenderLeaks( void ); // Render all memory leaks
+
+ // List manipulation functions:
+ CValObject *FindObject( void *pvObj ); // Returns CValObject containing pvObj, or NULL.
+ void DiffAgainst( CValidator *pOtherValidator ); // Removes any entries from this validator that are also present in the other.
+
+ // Accessors
+ bool BMemLeaks( void ) { return m_bMemLeaks; };
+ CValObject *PValObjectFirst( void ) { return m_pValObjectFirst; };
+
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+
+
+private:
+ CValObject *m_pValObjectFirst; // Linked list of all ValObjects
+ CValObject *m_pValObjectLast; // Last ValObject on the linked list
+
+ CValObject *m_pValObjectCur; // Object we're current processing
+
+ int m_cpvOwned; // Total # of blocks owned
+
+ int m_cpubLeaked; // # of leaked memory blocks
+ int m_cubLeaked; // Amount of leaked memory
+ bool m_bMemLeaks; // Has any memory leaked?
+};
+
+
+#endif // DBGFLAG_VALIDATE
+
+
+#endif // VALIDATOR_H
diff --git a/sp/src/public/tier0/valobject.h b/sp/src/public/tier0/valobject.h
index 8b25cc78..c139e9e3 100644
--- a/sp/src/public/tier0/valobject.h
+++ b/sp/src/public/tier0/valobject.h
@@ -1,72 +1,72 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: CValObject is used for tracking individual objects that report
-// in to CValidator. Whenever a new object reports in (via CValidator::Push),
-// we create a new CValObject to aggregate stats for it.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef VALOBJECT_H
-#define VALOBJECT_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#ifdef DBGFLAG_VALIDATE
-class CValObject
-{
-public:
- // Constructors & destructors
- CValObject( void ) { };
- ~CValObject( void );
-
- void Init( tchar *pchType, void *pvObj, tchar *pchName, CValObject *pValObjectParent,
- CValObject *pValObjectPrev );
-
- // Our object has claimed ownership of a memory block
- void ClaimMemoryBlock( void *pvMem );
-
- // A child of ours has claimed ownership of a memory block
- void ClaimChildMemoryBlock( int cubUser );
-
- // Accessors
- tchar *PchType( void ) { return m_rgchType; };
- void *PvObj( void ) { return m_pvObj; };
- tchar *PchName( void ) { return m_rgchName; };
- CValObject *PValObjectParent( void ) { return m_pValObjectParent; };
- int NLevel( void ) { return m_nLevel; };
- CValObject *PValObjectNext( void ) { return m_pValObjectNext; };
- int CpubMemSelf( void ) { return m_cpubMemSelf; };
- int CubMemSelf( void ) { return m_cubMemSelf; };
- int CpubMemTree( void ) { return m_cpubMemTree; };
- int CubMemTree( void ) { return m_cubMemTree; };
- int NUser( void ) { return m_nUser; };
- void SetNUser( int nUser ) { m_nUser = nUser; };
- void SetBNewSinceSnapshot( bool bNewSinceSnapshot ) { m_bNewSinceSnapshot = bNewSinceSnapshot; }
- bool BNewSinceSnapshot( void ) { return m_bNewSinceSnapshot; }
-
-private:
- bool m_bNewSinceSnapshot; // If this block is new since the snapshot.
- tchar m_rgchType[64]; // Type of the object we represent
- tchar m_rgchName[64]; // Name of this particular object
- void *m_pvObj; // Pointer to the object we represent
-
- CValObject *m_pValObjectParent; // Our parent object in the tree.
- int m_nLevel; // Our depth in the tree
-
- CValObject *m_pValObjectNext; // Next ValObject in the linked list
-
- int m_cpubMemSelf; // # of memory blocks we own directly
- int m_cubMemSelf; // Total size of the memory blocks we own directly
-
- int m_cpubMemTree; // # of memory blocks owned by us and our children
- int m_cubMemTree; // Total size of the memory blocks owned by us and our children
-
- int m_nUser; // Field provided for use by our users
-};
-#endif // DBGFLAG_VALIDATE
-
-
-#endif // VALOBJECT_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: CValObject is used for tracking individual objects that report
+// in to CValidator. Whenever a new object reports in (via CValidator::Push),
+// we create a new CValObject to aggregate stats for it.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VALOBJECT_H
+#define VALOBJECT_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#ifdef DBGFLAG_VALIDATE
+class CValObject
+{
+public:
+ // Constructors & destructors
+ CValObject( void ) { };
+ ~CValObject( void );
+
+ void Init( tchar *pchType, void *pvObj, tchar *pchName, CValObject *pValObjectParent,
+ CValObject *pValObjectPrev );
+
+ // Our object has claimed ownership of a memory block
+ void ClaimMemoryBlock( void *pvMem );
+
+ // A child of ours has claimed ownership of a memory block
+ void ClaimChildMemoryBlock( int cubUser );
+
+ // Accessors
+ tchar *PchType( void ) { return m_rgchType; };
+ void *PvObj( void ) { return m_pvObj; };
+ tchar *PchName( void ) { return m_rgchName; };
+ CValObject *PValObjectParent( void ) { return m_pValObjectParent; };
+ int NLevel( void ) { return m_nLevel; };
+ CValObject *PValObjectNext( void ) { return m_pValObjectNext; };
+ int CpubMemSelf( void ) { return m_cpubMemSelf; };
+ int CubMemSelf( void ) { return m_cubMemSelf; };
+ int CpubMemTree( void ) { return m_cpubMemTree; };
+ int CubMemTree( void ) { return m_cubMemTree; };
+ int NUser( void ) { return m_nUser; };
+ void SetNUser( int nUser ) { m_nUser = nUser; };
+ void SetBNewSinceSnapshot( bool bNewSinceSnapshot ) { m_bNewSinceSnapshot = bNewSinceSnapshot; }
+ bool BNewSinceSnapshot( void ) { return m_bNewSinceSnapshot; }
+
+private:
+ bool m_bNewSinceSnapshot; // If this block is new since the snapshot.
+ tchar m_rgchType[64]; // Type of the object we represent
+ tchar m_rgchName[64]; // Name of this particular object
+ void *m_pvObj; // Pointer to the object we represent
+
+ CValObject *m_pValObjectParent; // Our parent object in the tree.
+ int m_nLevel; // Our depth in the tree
+
+ CValObject *m_pValObjectNext; // Next ValObject in the linked list
+
+ int m_cpubMemSelf; // # of memory blocks we own directly
+ int m_cubMemSelf; // Total size of the memory blocks we own directly
+
+ int m_cpubMemTree; // # of memory blocks owned by us and our children
+ int m_cubMemTree; // Total size of the memory blocks owned by us and our children
+
+ int m_nUser; // Field provided for use by our users
+};
+#endif // DBGFLAG_VALIDATE
+
+
+#endif // VALOBJECT_H
diff --git a/sp/src/public/tier0/valve_minmax_off.h b/sp/src/public/tier0/valve_minmax_off.h
index 382c55b5..633a3780 100644
--- a/sp/src/public/tier0/valve_minmax_off.h
+++ b/sp/src/public/tier0/valve_minmax_off.h
@@ -1,7 +1,7 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-#ifdef min
- #undef min
-#endif
-#ifdef max
- #undef max
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+#ifdef min
+ #undef min
+#endif
+#ifdef max
+ #undef max
+#endif
diff --git a/sp/src/public/tier0/valve_minmax_on.h b/sp/src/public/tier0/valve_minmax_on.h
index c15f8b80..738eabc1 100644
--- a/sp/src/public/tier0/valve_minmax_on.h
+++ b/sp/src/public/tier0/valve_minmax_on.h
@@ -1,9 +1,9 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-#if !defined(POSIX)
-#ifndef min
- #define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef max
- #define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+#if !defined(POSIX)
+#ifndef min
+ #define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+ #define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#endif
diff --git a/sp/src/public/tier0/valve_off.h b/sp/src/public/tier0/valve_off.h
index 4c30cfae..796408ee 100644
--- a/sp/src/public/tier0/valve_off.h
+++ b/sp/src/public/tier0/valve_off.h
@@ -1,30 +1,30 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This turns off all Valve-specific #defines. Because we sometimes
-// call external include files from inside .cpp files, we need to
-// wrap those includes like this:
-// #include "tier0/valve_off.h"
-// #include <external.h>
-// #include "tier0/valve_on.h"
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#ifdef STEAM
-
-//-----------------------------------------------------------------------------
-// Unicode-related #defines (see wchartypes.h)
-//-----------------------------------------------------------------------------
-#undef char
-
-
-//-----------------------------------------------------------------------------
-// Memory-related #defines
-//-----------------------------------------------------------------------------
-#undef malloc
-#undef realloc
-#undef _expand
-#undef free
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This turns off all Valve-specific #defines. Because we sometimes
+// call external include files from inside .cpp files, we need to
+// wrap those includes like this:
+// #include "tier0/valve_off.h"
+// #include <external.h>
+// #include "tier0/valve_on.h"
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#ifdef STEAM
+
+//-----------------------------------------------------------------------------
+// Unicode-related #defines (see wchartypes.h)
+//-----------------------------------------------------------------------------
+#undef char
+
+
+//-----------------------------------------------------------------------------
+// Memory-related #defines
+//-----------------------------------------------------------------------------
+#undef malloc
+#undef realloc
+#undef _expand
+#undef free
+
+#endif
diff --git a/sp/src/public/tier0/valve_on.h b/sp/src/public/tier0/valve_on.h
index 8bc35dd8..ffc9b89d 100644
--- a/sp/src/public/tier0/valve_on.h
+++ b/sp/src/public/tier0/valve_on.h
@@ -1,31 +1,31 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: This turns on all Valve-specific #defines. Because we sometimes
-// call external include files from inside .cpp files, we need to
-// wrap those includes like this:
-// #include "tier0/valve_off.h"
-// #include <external.h>
-// #include "tier0/valve_on.h"
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#ifdef STEAM
-//-----------------------------------------------------------------------------
-// Unicode-related #defines (see wchartypes.h)
-//-----------------------------------------------------------------------------
-#ifdef ENFORCE_WCHAR
-#define char DontUseChar_SeeWcharOn.h
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Memory-related #defines
-//-----------------------------------------------------------------------------
-#define malloc( cub ) HEY_DONT_USE_MALLOC_USE_PVALLOC
-#define realloc( pvOld, cub ) HEY_DONT_USE_REALLOC_USE_PVREALLOC
-#define _expand( pvOld, cub ) HEY_DONT_USE_EXPAND_USE_PVEXPAND
-#define free( pv ) HEY_DONT_USE_FREE_USE_FREEPV
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: This turns on all Valve-specific #defines. Because we sometimes
+// call external include files from inside .cpp files, we need to
+// wrap those includes like this:
+// #include "tier0/valve_off.h"
+// #include <external.h>
+// #include "tier0/valve_on.h"
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#ifdef STEAM
+//-----------------------------------------------------------------------------
+// Unicode-related #defines (see wchartypes.h)
+//-----------------------------------------------------------------------------
+#ifdef ENFORCE_WCHAR
+#define char DontUseChar_SeeWcharOn.h
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Memory-related #defines
+//-----------------------------------------------------------------------------
+#define malloc( cub ) HEY_DONT_USE_MALLOC_USE_PVALLOC
+#define realloc( pvOld, cub ) HEY_DONT_USE_REALLOC_USE_PVREALLOC
+#define _expand( pvOld, cub ) HEY_DONT_USE_EXPAND_USE_PVEXPAND
+#define free( pv ) HEY_DONT_USE_FREE_USE_FREEPV
+
+#endif
diff --git a/sp/src/public/tier0/vcr_shared.h b/sp/src/public/tier0/vcr_shared.h
index 36ce85ac..d2d5ac75 100644
--- a/sp/src/public/tier0/vcr_shared.h
+++ b/sp/src/public/tier0/vcr_shared.h
@@ -1,54 +1,54 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef VCR_SHARED_H
-#define VCR_SHARED_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-
-#define VCRFILE_VERSION 2
-
-
-// Identifiers for the things we record. When playing back, these things should
-// be asked for in the exact same order (otherwise, the engine isn't making all
-// the calls in the same order).
-typedef enum
-{
- VCREvent_Sys_FloatTime=0,
- VCREvent_recvfrom,
- VCREvent_SyncToken,
- VCREvent_GetCursorPos,
- VCREvent_SetCursorPos,
- VCREvent_ScreenToClient,
- VCREvent_Cmd_Exec,
- VCREvent_CmdLine,
- VCREvent_RegOpenKeyEx,
- VCREvent_RegSetValueEx,
- VCREvent_RegQueryValueEx,
- VCREvent_RegCreateKeyEx,
- VCREvent_RegCloseKey,
- VCREvent_PeekMessage,
- VCREvent_GameMsg,
- VCREvent_GetNumberOfConsoleInputEvents,
- VCREvent_ReadConsoleInput,
- VCREvent_GetKeyState,
- VCREvent_recv,
- VCREvent_send,
- VCREvent_Generic,
- VCREvent_CreateThread,
- VCREvent_WaitForSingleObject,
- VCREvent_EnterCriticalSection,
- VCREvent_Time,
- VCREvent_LocalTime,
- VCREvent_GenericString,
- VCREvent_NUMEVENTS
-} VCREvent;
-
-
-#endif // VCR_SHARED_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VCR_SHARED_H
+#define VCR_SHARED_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#define VCRFILE_VERSION 2
+
+
+// Identifiers for the things we record. When playing back, these things should
+// be asked for in the exact same order (otherwise, the engine isn't making all
+// the calls in the same order).
+typedef enum
+{
+ VCREvent_Sys_FloatTime=0,
+ VCREvent_recvfrom,
+ VCREvent_SyncToken,
+ VCREvent_GetCursorPos,
+ VCREvent_SetCursorPos,
+ VCREvent_ScreenToClient,
+ VCREvent_Cmd_Exec,
+ VCREvent_CmdLine,
+ VCREvent_RegOpenKeyEx,
+ VCREvent_RegSetValueEx,
+ VCREvent_RegQueryValueEx,
+ VCREvent_RegCreateKeyEx,
+ VCREvent_RegCloseKey,
+ VCREvent_PeekMessage,
+ VCREvent_GameMsg,
+ VCREvent_GetNumberOfConsoleInputEvents,
+ VCREvent_ReadConsoleInput,
+ VCREvent_GetKeyState,
+ VCREvent_recv,
+ VCREvent_send,
+ VCREvent_Generic,
+ VCREvent_CreateThread,
+ VCREvent_WaitForSingleObject,
+ VCREvent_EnterCriticalSection,
+ VCREvent_Time,
+ VCREvent_LocalTime,
+ VCREvent_GenericString,
+ VCREvent_NUMEVENTS
+} VCREvent;
+
+
+#endif // VCR_SHARED_H
diff --git a/sp/src/public/tier0/vcrmode.h b/sp/src/public/tier0/vcrmode.h
index d4f43d92..2af8a608 100644
--- a/sp/src/public/tier0/vcrmode.h
+++ b/sp/src/public/tier0/vcrmode.h
@@ -1,306 +1,306 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: VCR mode records a client's game and allows you to
-// play it back and reproduce it exactly. When playing it back, nothing
-// is simulated on the server, but all server packets are recorded.
-//
-// Most of the VCR mode functionality is accomplished through hooks
-// called at various points in the engine.
-//
-// $NoKeywords: $
-//===========================================================================//
-#ifndef VCRMODE_H
-#define VCRMODE_H
-
-#ifdef _WIN32
-#include <process.h>
-#endif
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "tier0/platform.h"
-#include "tier0/vcr_shared.h"
-#include "tier0/dbg.h"
-
-#ifdef POSIX
-DBG_INTERFACE const char *BuildCmdLine( int argc, char **argv, bool fAddSteam = true );
-tchar *GetCommandLine();
-#endif
-
-#ifdef _X360
-#define NO_VCR 1
-#endif
-
-
-// Enclose lines of code in this if you don't want anything in them written to or read from the VCR file.
-#ifndef NO_VCR
-#define NOVCR(x) \
-{\
- VCRSetEnabled(0);\
- x;\
- VCRSetEnabled(1);\
-}
-#else
-#define NOVCR(x) \
-{\
- x;\
-}
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Forward declarations
-//-----------------------------------------------------------------------------
-struct InputEvent_t;
-
-
-//-----------------------------------------------------------------------------
-// Definitions.
-//-----------------------------------------------------------------------------
-enum VCRMode_t
-{
- VCR_Invalid=-1,
- VCR_Disabled=0,
- VCR_Record,
- VCR_Playback
-};
-
-
-//-----------------------------------------------------------------------------
-// Functions.
-//-----------------------------------------------------------------------------
-abstract_class IVCRHelpers
-{
-public:
- virtual void ErrorMessage( const tchar *pMsg ) = 0;
- virtual void* GetMainWindow() = 0;
-};
-
-
-// Used by the vcrtrace program.
-abstract_class IVCRTrace
-{
-public:
- virtual VCREvent ReadEvent() = 0;
- virtual void Read( void *pDest, int size ) = 0;
-};
-
-typedef struct VCR_s
-{
- // Start VCR record or play.
- int (*Start)( tchar const *pFilename, bool bRecord, IVCRHelpers *pHelpers );
- void (*End)();
-
- // Used by the VCR trace app.
- IVCRTrace* (*GetVCRTraceInterface)();
-
- // Get the current mode the VCR is in.
- VCRMode_t (*GetMode)();
-
- // This can be used to block out areas of code that are unpredictable (like things triggered by WM_TIMER messages).
- // Note: this enables/disables VCR mode usage on a PER-THREAD basis. The assumption is that you're marking out
- // specific sections of code that you don't want to use VCR mode inside of, but you're not intending to
- // stop all the other threads from using VCR mode.
- void (*SetEnabled)(int bEnabled);
-
- // This can be called any time to put in a debug check to make sure things are synchronized.
- void (*SyncToken)(tchar const *pToken);
-
- // Hook for Sys_FloatTime().
- double (*Hook_Sys_FloatTime)(double time);
-
- // Note: this makes no guarantees about msg.hwnd being the same on playback. If it needs to be, then we need to add
- // an ID system for Windows and store the ID like in Goldsrc.
- int (*Hook_PeekMessage)(
- struct tagMSG *msg,
- void *hWnd,
- unsigned int wMsgFilterMin,
- unsigned int wMsgFilterMax,
- unsigned int wRemoveMsg
- );
-
- // Call this to record game messages.
- void (*Hook_RecordGameMsg)( const InputEvent_t &event );
- void (*Hook_RecordEndGameMsg)();
-
- // Call this to playback game messages until it returns false.
- bool (*Hook_PlaybackGameMsg)( InputEvent_t *pEvent );
-
- // Hook for recvfrom() calls. This replaces the recvfrom() call.
- int (*Hook_recvfrom)(int s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
-
- void (*Hook_GetCursorPos)(struct tagPOINT *pt);
- void (*Hook_ScreenToClient)(void *hWnd, struct tagPOINT *pt);
-
- void (*Hook_Cmd_Exec)(tchar **f);
-
- tchar* (*Hook_GetCommandLine)();
-
- // Registry hooks.
- long (*Hook_RegOpenKeyEx)( void *hKey, const tchar *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void *pHKey );
- long (*Hook_RegSetValueEx)(void *hKey, tchar const *lpValueName, unsigned long Reserved, unsigned long dwType, uint8 const *lpData, unsigned long cbData);
- long (*Hook_RegQueryValueEx)(void *hKey, tchar const *lpValueName, unsigned long *lpReserved, unsigned long *lpType, uint8 *lpData, unsigned long *lpcbData);
- long (*Hook_RegCreateKeyEx)(void *hKey, tchar const *lpSubKey, unsigned long Reserved, tchar *lpClass, unsigned long dwOptions, unsigned long samDesired, void *lpSecurityAttributes, void *phkResult, unsigned long *lpdwDisposition);
- void (*Hook_RegCloseKey)(void *hKey);
-
- // hInput is a HANDLE.
- int (*Hook_GetNumberOfConsoleInputEvents)( void *hInput, unsigned long *pNumEvents );
-
- // hInput is a HANDLE.
- // pRecs is an INPUT_RECORD pointer.
- int (*Hook_ReadConsoleInput)( void *hInput, void *pRecs, int nMaxRecs, unsigned long *pNumRead );
-
-
- // This calls time() then gives you localtime()'s result.
- void (*Hook_LocalTime)( struct tm *today );
-
- short (*Hook_GetKeyState)( int nVirtKey );
-
- // TCP calls.
- int (*Hook_recv)( int s, char *buf, int len, int flags );
- int (*Hook_send)( int s, const char *buf, int len, int flags );
-
- // These can be used to add events without having to modify VCR mode.
- // pEventName is used for verification to make sure it's playing back correctly.
- // If pEventName is null, then verification is not performed.
- void (*GenericRecord)( const tchar *pEventName, const void *pData, int len );
-
-
- // Returns the number of bytes written in the generic event.
- // If bForceLenSame is true, then it will error out unless the value in the VCR file is the same as maxLen.
- int (*GenericPlayback)( const tchar *pEventName, void *pOutData, int maxLen, bool bForceLenSame );
-
- // If you just want to record and playback a value and not worry about whether or not you're
- // recording or playing back, use this. It also will do nothing if you're not recording or playing back.
- //
- // NOTE: also see GenericValueVerify, which allows you to have it VERIFY that pData's contents are the same upon playback
- // (rather than just copying whatever is in the VCR file into pData).
- void (*GenericValue)( const tchar *pEventName, void *pData, int maxLen );
-
- // Get the current percent (0.0 - 1.0) that it's played back through the file (only valid in playback).
- double (*GetPercentCompleted)();
-
- // If you use this, then any VCR stuff the thread does will work with VCR mode.
- // This mirrors the Windows API CreateThread function and returns a HANDLE the same way.
- void* (*Hook_CreateThread)(
- void *lpThreadAttributes,
- unsigned long dwStackSize,
- void *lpStartAddress,
- void *lpParameter,
- unsigned long dwCreationFlags,
- unsigned long *lpThreadID );
-
- unsigned long (*Hook_WaitForSingleObject)(
- void *handle,
- unsigned long dwMilliseconds );
-
- void (*Hook_EnterCriticalSection)( void *pCS );
-
- void (*Hook_Time)( long *pTime );
-
- // String value. Playback just verifies that the incoming string is the same as it was when recording.
- void (*GenericString)( const char *pEventName, const char *pString );
-
- // Works like GenericValue, except upon playback it will verify that pData's contents are the same as it was during recording.
- void (*GenericValueVerify)( const tchar *pEventName, const void *pData, int maxLen );
-
- unsigned long (*Hook_WaitForMultipleObjects)( uint32 nHandles, const void **pHandles, int bWaitAll, uint32 timeout );
-
-} VCR_t;
-
-#ifndef NO_VCR
-
-// In the launcher, this is created by vcrmode.c.
-// In the engine, this is set when the launcher initializes its DLL.
-PLATFORM_INTERFACE VCR_t *g_pVCR;
-
-#endif
-
-
-#ifndef NO_VCR
-#define VCRStart g_pVCR->Start
-#define VCREnd g_pVCR->End
-#define VCRGetVCRTraceInterface g_pVCR->GetVCRTraceInterface
-#define VCRGetMode g_pVCR->GetMode
-#define VCRSetEnabled g_pVCR->SetEnabled
-#define VCRSyncToken g_pVCR->SyncToken
-#define VCRGenericString g_pVCR->GenericString
-#define VCRGenericValueVerify g_pVCR->GenericValueVerify
-#define VCRHook_Sys_FloatTime g_pVCR->Hook_Sys_FloatTime
-#define VCRHook_PeekMessage g_pVCR->Hook_PeekMessage
-#define VCRHook_RecordGameMsg g_pVCR->Hook_RecordGameMsg
-#define VCRHook_RecordEndGameMsg g_pVCR->Hook_RecordEndGameMsg
-#define VCRHook_PlaybackGameMsg g_pVCR->Hook_PlaybackGameMsg
-#define VCRHook_recvfrom g_pVCR->Hook_recvfrom
-#define VCRHook_GetCursorPos g_pVCR->Hook_GetCursorPos
-#define VCRHook_ScreenToClient g_pVCR->Hook_ScreenToClient
-#define VCRHook_Cmd_Exec g_pVCR->Hook_Cmd_Exec
-#define VCRHook_GetCommandLine g_pVCR->Hook_GetCommandLine
-#define VCRHook_RegOpenKeyEx g_pVCR->Hook_RegOpenKeyEx
-#define VCRHook_RegSetValueEx g_pVCR->Hook_RegSetValueEx
-#define VCRHook_RegQueryValueEx g_pVCR->Hook_RegQueryValueEx
-#define VCRHook_RegCreateKeyEx g_pVCR->Hook_RegCreateKeyEx
-#define VCRHook_RegCloseKey g_pVCR->Hook_RegCloseKey
-#define VCRHook_GetNumberOfConsoleInputEvents g_pVCR->Hook_GetNumberOfConsoleInputEvents
-#define VCRHook_ReadConsoleInput g_pVCR->Hook_ReadConsoleInput
-#define VCRHook_LocalTime g_pVCR->Hook_LocalTime
-#define VCRHook_GetKeyState g_pVCR->Hook_GetKeyState
-#define VCRHook_recv g_pVCR->Hook_recv
-#define VCRHook_send g_pVCR->Hook_send
-#define VCRGenericRecord g_pVCR->GenericRecord
-#define VCRGenericPlayback g_pVCR->GenericPlayback
-#define VCRGenericValue g_pVCR->GenericValue
-#define VCRGetPercentCompleted g_pVCR->GetPercentCompleted
-#define VCRHook_CreateThread g_pVCR->Hook_CreateThread
-#define VCRHook_WaitForSingleObject g_pVCR->Hook_WaitForSingleObject
-#define VCRHook_EnterCriticalSection g_pVCR->Hook_EnterCriticalSection
-#define VCRHook_Time g_pVCR->Hook_Time
-#define VCRHook_WaitForMultipleObjects( a, b, c, d) g_pVCR->Hook_WaitForMultipleObjects( a, (const void **)b, c, d)
-#else
-#define VCRStart( a, b, c ) (1)
-#define VCREnd ((void)(0))
-#define VCRGetVCRTraceInterface (NULL)
-#define VCRGetMode() (VCR_Disabled)
-#define VCRSetEnabled( a ) ((void)(0))
-#define VCRSyncToken( a ) ((void)(0))
-#define VCRGenericRecord MUST_IFDEF_OUT_GenericRecord
-#define VCRGenericPlayback MUST_IFDEF_OUT_GenericPlayback
-#define VCRGenericValue MUST_IFDEF_OUT_GenericValue
-#define VCRGenericString MUST_IFDEF_OUT_GenericString
-#define VCRGenericValueVerify MUST_IFDEF_OUT_GenericValueVerify
-#define VCRGetPercentCompleted() (0.0f)
-#define VCRHook_Sys_FloatTime Sys_FloatTime
-#define VCRHook_PeekMessage PeekMessage
-#define VCRHook_RecordGameMsg RecordGameMsg
-#define VCRHook_RecordEndGameMsg RecordEndGameMsg
-#define VCRHook_PlaybackGameMsg PlaybackGameMsg
-#define VCRHook_recvfrom recvfrom
-#define VCRHook_GetCursorPos GetCursorPos
-#define VCRHook_ScreenToClient ScreenToClient
-#define VCRHook_Cmd_Exec( a ) ((void)(0))
-#define VCRHook_GetCommandLine GetCommandLine
-#define VCRHook_RegOpenKeyEx RegOpenKeyEx
-#define VCRHook_RegSetValueEx RegSetValueEx
-#define VCRHook_RegQueryValueEx RegQueryValueEx
-#define VCRHook_RegCreateKeyEx RegCreateKeyEx
-#define VCRHook_RegCloseKey RegCloseKey
-#define VCRHook_GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents
-#define VCRHook_ReadConsoleInput ReadConsoleInput
-#define VCRHook_LocalTime( a ) memset(a, 0, sizeof(*a));
-#define VCRHook_GetKeyState GetKeyState
-#define VCRHook_recv recv
-#define VCRHook_send send
-#if defined( _X360 )
-#define VCRHook_CreateThread CreateThread
-#else
-#define VCRHook_CreateThread (void*)_beginthreadex
-#endif
-#define VCRHook_WaitForSingleObject WaitForSingleObject
-#define VCRHook_EnterCriticalSection EnterCriticalSection
-#define VCRHook_WaitForMultipleObjects( a, b, c, d) WaitForMultipleObjects( a, (const HANDLE *)b, c, d)
-#define VCRHook_Time Time
-#endif
-
-#endif // VCRMODE_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: VCR mode records a client's game and allows you to
+// play it back and reproduce it exactly. When playing it back, nothing
+// is simulated on the server, but all server packets are recorded.
+//
+// Most of the VCR mode functionality is accomplished through hooks
+// called at various points in the engine.
+//
+// $NoKeywords: $
+//===========================================================================//
+#ifndef VCRMODE_H
+#define VCRMODE_H
+
+#ifdef _WIN32
+#include <process.h>
+#endif
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "tier0/platform.h"
+#include "tier0/vcr_shared.h"
+#include "tier0/dbg.h"
+
+#ifdef POSIX
+DBG_INTERFACE const char *BuildCmdLine( int argc, char **argv, bool fAddSteam = true );
+tchar *GetCommandLine();
+#endif
+
+#ifdef _X360
+#define NO_VCR 1
+#endif
+
+
+// Enclose lines of code in this if you don't want anything in them written to or read from the VCR file.
+#ifndef NO_VCR
+#define NOVCR(x) \
+{\
+ VCRSetEnabled(0);\
+ x;\
+ VCRSetEnabled(1);\
+}
+#else
+#define NOVCR(x) \
+{\
+ x;\
+}
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+struct InputEvent_t;
+
+
+//-----------------------------------------------------------------------------
+// Definitions.
+//-----------------------------------------------------------------------------
+enum VCRMode_t
+{
+ VCR_Invalid=-1,
+ VCR_Disabled=0,
+ VCR_Record,
+ VCR_Playback
+};
+
+
+//-----------------------------------------------------------------------------
+// Functions.
+//-----------------------------------------------------------------------------
+abstract_class IVCRHelpers
+{
+public:
+ virtual void ErrorMessage( const tchar *pMsg ) = 0;
+ virtual void* GetMainWindow() = 0;
+};
+
+
+// Used by the vcrtrace program.
+abstract_class IVCRTrace
+{
+public:
+ virtual VCREvent ReadEvent() = 0;
+ virtual void Read( void *pDest, int size ) = 0;
+};
+
+typedef struct VCR_s
+{
+ // Start VCR record or play.
+ int (*Start)( tchar const *pFilename, bool bRecord, IVCRHelpers *pHelpers );
+ void (*End)();
+
+ // Used by the VCR trace app.
+ IVCRTrace* (*GetVCRTraceInterface)();
+
+ // Get the current mode the VCR is in.
+ VCRMode_t (*GetMode)();
+
+ // This can be used to block out areas of code that are unpredictable (like things triggered by WM_TIMER messages).
+ // Note: this enables/disables VCR mode usage on a PER-THREAD basis. The assumption is that you're marking out
+ // specific sections of code that you don't want to use VCR mode inside of, but you're not intending to
+ // stop all the other threads from using VCR mode.
+ void (*SetEnabled)(int bEnabled);
+
+ // This can be called any time to put in a debug check to make sure things are synchronized.
+ void (*SyncToken)(tchar const *pToken);
+
+ // Hook for Sys_FloatTime().
+ double (*Hook_Sys_FloatTime)(double time);
+
+ // Note: this makes no guarantees about msg.hwnd being the same on playback. If it needs to be, then we need to add
+ // an ID system for Windows and store the ID like in Goldsrc.
+ int (*Hook_PeekMessage)(
+ struct tagMSG *msg,
+ void *hWnd,
+ unsigned int wMsgFilterMin,
+ unsigned int wMsgFilterMax,
+ unsigned int wRemoveMsg
+ );
+
+ // Call this to record game messages.
+ void (*Hook_RecordGameMsg)( const InputEvent_t &event );
+ void (*Hook_RecordEndGameMsg)();
+
+ // Call this to playback game messages until it returns false.
+ bool (*Hook_PlaybackGameMsg)( InputEvent_t *pEvent );
+
+ // Hook for recvfrom() calls. This replaces the recvfrom() call.
+ int (*Hook_recvfrom)(int s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
+
+ void (*Hook_GetCursorPos)(struct tagPOINT *pt);
+ void (*Hook_ScreenToClient)(void *hWnd, struct tagPOINT *pt);
+
+ void (*Hook_Cmd_Exec)(tchar **f);
+
+ tchar* (*Hook_GetCommandLine)();
+
+ // Registry hooks.
+ long (*Hook_RegOpenKeyEx)( void *hKey, const tchar *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void *pHKey );
+ long (*Hook_RegSetValueEx)(void *hKey, tchar const *lpValueName, unsigned long Reserved, unsigned long dwType, uint8 const *lpData, unsigned long cbData);
+ long (*Hook_RegQueryValueEx)(void *hKey, tchar const *lpValueName, unsigned long *lpReserved, unsigned long *lpType, uint8 *lpData, unsigned long *lpcbData);
+ long (*Hook_RegCreateKeyEx)(void *hKey, tchar const *lpSubKey, unsigned long Reserved, tchar *lpClass, unsigned long dwOptions, unsigned long samDesired, void *lpSecurityAttributes, void *phkResult, unsigned long *lpdwDisposition);
+ void (*Hook_RegCloseKey)(void *hKey);
+
+ // hInput is a HANDLE.
+ int (*Hook_GetNumberOfConsoleInputEvents)( void *hInput, unsigned long *pNumEvents );
+
+ // hInput is a HANDLE.
+ // pRecs is an INPUT_RECORD pointer.
+ int (*Hook_ReadConsoleInput)( void *hInput, void *pRecs, int nMaxRecs, unsigned long *pNumRead );
+
+
+ // This calls time() then gives you localtime()'s result.
+ void (*Hook_LocalTime)( struct tm *today );
+
+ short (*Hook_GetKeyState)( int nVirtKey );
+
+ // TCP calls.
+ int (*Hook_recv)( int s, char *buf, int len, int flags );
+ int (*Hook_send)( int s, const char *buf, int len, int flags );
+
+ // These can be used to add events without having to modify VCR mode.
+ // pEventName is used for verification to make sure it's playing back correctly.
+ // If pEventName is null, then verification is not performed.
+ void (*GenericRecord)( const tchar *pEventName, const void *pData, int len );
+
+
+ // Returns the number of bytes written in the generic event.
+ // If bForceLenSame is true, then it will error out unless the value in the VCR file is the same as maxLen.
+ int (*GenericPlayback)( const tchar *pEventName, void *pOutData, int maxLen, bool bForceLenSame );
+
+ // If you just want to record and playback a value and not worry about whether or not you're
+ // recording or playing back, use this. It also will do nothing if you're not recording or playing back.
+ //
+ // NOTE: also see GenericValueVerify, which allows you to have it VERIFY that pData's contents are the same upon playback
+ // (rather than just copying whatever is in the VCR file into pData).
+ void (*GenericValue)( const tchar *pEventName, void *pData, int maxLen );
+
+ // Get the current percent (0.0 - 1.0) that it's played back through the file (only valid in playback).
+ double (*GetPercentCompleted)();
+
+ // If you use this, then any VCR stuff the thread does will work with VCR mode.
+ // This mirrors the Windows API CreateThread function and returns a HANDLE the same way.
+ void* (*Hook_CreateThread)(
+ void *lpThreadAttributes,
+ unsigned long dwStackSize,
+ void *lpStartAddress,
+ void *lpParameter,
+ unsigned long dwCreationFlags,
+ unsigned long *lpThreadID );
+
+ unsigned long (*Hook_WaitForSingleObject)(
+ void *handle,
+ unsigned long dwMilliseconds );
+
+ void (*Hook_EnterCriticalSection)( void *pCS );
+
+ void (*Hook_Time)( long *pTime );
+
+ // String value. Playback just verifies that the incoming string is the same as it was when recording.
+ void (*GenericString)( const char *pEventName, const char *pString );
+
+ // Works like GenericValue, except upon playback it will verify that pData's contents are the same as it was during recording.
+ void (*GenericValueVerify)( const tchar *pEventName, const void *pData, int maxLen );
+
+ unsigned long (*Hook_WaitForMultipleObjects)( uint32 nHandles, const void **pHandles, int bWaitAll, uint32 timeout );
+
+} VCR_t;
+
+#ifndef NO_VCR
+
+// In the launcher, this is created by vcrmode.c.
+// In the engine, this is set when the launcher initializes its DLL.
+PLATFORM_INTERFACE VCR_t *g_pVCR;
+
+#endif
+
+
+#ifndef NO_VCR
+#define VCRStart g_pVCR->Start
+#define VCREnd g_pVCR->End
+#define VCRGetVCRTraceInterface g_pVCR->GetVCRTraceInterface
+#define VCRGetMode g_pVCR->GetMode
+#define VCRSetEnabled g_pVCR->SetEnabled
+#define VCRSyncToken g_pVCR->SyncToken
+#define VCRGenericString g_pVCR->GenericString
+#define VCRGenericValueVerify g_pVCR->GenericValueVerify
+#define VCRHook_Sys_FloatTime g_pVCR->Hook_Sys_FloatTime
+#define VCRHook_PeekMessage g_pVCR->Hook_PeekMessage
+#define VCRHook_RecordGameMsg g_pVCR->Hook_RecordGameMsg
+#define VCRHook_RecordEndGameMsg g_pVCR->Hook_RecordEndGameMsg
+#define VCRHook_PlaybackGameMsg g_pVCR->Hook_PlaybackGameMsg
+#define VCRHook_recvfrom g_pVCR->Hook_recvfrom
+#define VCRHook_GetCursorPos g_pVCR->Hook_GetCursorPos
+#define VCRHook_ScreenToClient g_pVCR->Hook_ScreenToClient
+#define VCRHook_Cmd_Exec g_pVCR->Hook_Cmd_Exec
+#define VCRHook_GetCommandLine g_pVCR->Hook_GetCommandLine
+#define VCRHook_RegOpenKeyEx g_pVCR->Hook_RegOpenKeyEx
+#define VCRHook_RegSetValueEx g_pVCR->Hook_RegSetValueEx
+#define VCRHook_RegQueryValueEx g_pVCR->Hook_RegQueryValueEx
+#define VCRHook_RegCreateKeyEx g_pVCR->Hook_RegCreateKeyEx
+#define VCRHook_RegCloseKey g_pVCR->Hook_RegCloseKey
+#define VCRHook_GetNumberOfConsoleInputEvents g_pVCR->Hook_GetNumberOfConsoleInputEvents
+#define VCRHook_ReadConsoleInput g_pVCR->Hook_ReadConsoleInput
+#define VCRHook_LocalTime g_pVCR->Hook_LocalTime
+#define VCRHook_GetKeyState g_pVCR->Hook_GetKeyState
+#define VCRHook_recv g_pVCR->Hook_recv
+#define VCRHook_send g_pVCR->Hook_send
+#define VCRGenericRecord g_pVCR->GenericRecord
+#define VCRGenericPlayback g_pVCR->GenericPlayback
+#define VCRGenericValue g_pVCR->GenericValue
+#define VCRGetPercentCompleted g_pVCR->GetPercentCompleted
+#define VCRHook_CreateThread g_pVCR->Hook_CreateThread
+#define VCRHook_WaitForSingleObject g_pVCR->Hook_WaitForSingleObject
+#define VCRHook_EnterCriticalSection g_pVCR->Hook_EnterCriticalSection
+#define VCRHook_Time g_pVCR->Hook_Time
+#define VCRHook_WaitForMultipleObjects( a, b, c, d) g_pVCR->Hook_WaitForMultipleObjects( a, (const void **)b, c, d)
+#else
+#define VCRStart( a, b, c ) (1)
+#define VCREnd ((void)(0))
+#define VCRGetVCRTraceInterface (NULL)
+#define VCRGetMode() (VCR_Disabled)
+#define VCRSetEnabled( a ) ((void)(0))
+#define VCRSyncToken( a ) ((void)(0))
+#define VCRGenericRecord MUST_IFDEF_OUT_GenericRecord
+#define VCRGenericPlayback MUST_IFDEF_OUT_GenericPlayback
+#define VCRGenericValue MUST_IFDEF_OUT_GenericValue
+#define VCRGenericString MUST_IFDEF_OUT_GenericString
+#define VCRGenericValueVerify MUST_IFDEF_OUT_GenericValueVerify
+#define VCRGetPercentCompleted() (0.0f)
+#define VCRHook_Sys_FloatTime Sys_FloatTime
+#define VCRHook_PeekMessage PeekMessage
+#define VCRHook_RecordGameMsg RecordGameMsg
+#define VCRHook_RecordEndGameMsg RecordEndGameMsg
+#define VCRHook_PlaybackGameMsg PlaybackGameMsg
+#define VCRHook_recvfrom recvfrom
+#define VCRHook_GetCursorPos GetCursorPos
+#define VCRHook_ScreenToClient ScreenToClient
+#define VCRHook_Cmd_Exec( a ) ((void)(0))
+#define VCRHook_GetCommandLine GetCommandLine
+#define VCRHook_RegOpenKeyEx RegOpenKeyEx
+#define VCRHook_RegSetValueEx RegSetValueEx
+#define VCRHook_RegQueryValueEx RegQueryValueEx
+#define VCRHook_RegCreateKeyEx RegCreateKeyEx
+#define VCRHook_RegCloseKey RegCloseKey
+#define VCRHook_GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents
+#define VCRHook_ReadConsoleInput ReadConsoleInput
+#define VCRHook_LocalTime( a ) memset(a, 0, sizeof(*a));
+#define VCRHook_GetKeyState GetKeyState
+#define VCRHook_recv recv
+#define VCRHook_send send
+#if defined( _X360 )
+#define VCRHook_CreateThread CreateThread
+#else
+#define VCRHook_CreateThread (void*)_beginthreadex
+#endif
+#define VCRHook_WaitForSingleObject WaitForSingleObject
+#define VCRHook_EnterCriticalSection EnterCriticalSection
+#define VCRHook_WaitForMultipleObjects( a, b, c, d) WaitForMultipleObjects( a, (const HANDLE *)b, c, d)
+#define VCRHook_Time Time
+#endif
+
+#endif // VCRMODE_H
diff --git a/sp/src/public/tier0/vprof.h b/sp/src/public/tier0/vprof.h
index 5267495f..2e60e17f 100644
--- a/sp/src/public/tier0/vprof.h
+++ b/sp/src/public/tier0/vprof.h
@@ -1,1438 +1,1438 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Real-Time Hierarchical Profiling
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef VPROF_H
-#define VPROF_H
-
-#include "tier0/dbg.h"
-#include "tier0/fasttimer.h"
-#include "tier0/l2cache.h"
-#include "tier0/threadtools.h"
-#include "tier0/vprof_telemetry.h"
-
-// VProf is enabled by default in all configurations -except- X360 Retail.
-#if !( defined( _X360 ) && defined( _CERT ) )
-#define VPROF_ENABLED
-#endif
-
-#if defined(_X360) && defined(VPROF_ENABLED)
-#include "tier0/pmc360.h"
-#ifndef USE_PIX
-#define VPROF_UNDO_PIX
-#undef _PIX_H_
-#undef PIXBeginNamedEvent
-#undef PIXEndNamedEvent
-#undef PIXSetMarker
-#undef PIXNameThread
-#define USE_PIX
-#include <pix.h>
-#undef USE_PIX
-#else
-#include <pix.h>
-#endif
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4251)
-#endif
-
-// enable this to get detailed nodes beneath budget
-// #define VPROF_LEVEL 1
-
-// enable this to use pix (360 only)
-// #define VPROF_PIX 1
-
-#if defined(VPROF_PIX)
-#pragma comment( lib, "Xapilibi" )
-#endif
-
-//-----------------------------------------------------------------------------
-//
-// Profiling instrumentation macros
-//
-
-#define MAXCOUNTERS 256
-
-
-#ifdef VPROF_ENABLED
-
-#define VPROF_VTUNE_GROUP
-
-#define VPROF( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0)
-#define VPROF_ASSERT_ACCOUNTED( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, true, 0)
-#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) VPROF_##detail(name,group, bAssertAccounted, budgetFlags)
-
-#define VPROF_BUDGET( name, group ) VPROF_BUDGET_FLAGS(name, group, BUDGETFLAG_OTHER)
-#define VPROF_BUDGET_FLAGS( name, group, flags ) VPROF_(name, 0, group, false, flags)
-
-#define VPROF_SCOPE_BEGIN( tag ) do { VPROF( tag )
-#define VPROF_SCOPE_END() } while (0)
-
-#define VPROF_ONLY( expression ) expression
-
-#define VPROF_ENTER_SCOPE( name ) g_VProfCurrentProfile.EnterScope( name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0 )
-#define VPROF_EXIT_SCOPE() g_VProfCurrentProfile.ExitScope()
-
-#define VPROF_BUDGET_GROUP_ID_UNACCOUNTED 0
-
-
-// Budgetgroup flags. These are used with VPROF_BUDGET_FLAGS.
-// These control which budget panels the groups show up in.
-// If a budget group uses VPROF_BUDGET, it gets the default
-// which is BUDGETFLAG_OTHER.
-#define BUDGETFLAG_CLIENT (1<<0) // Shows up in the client panel.
-#define BUDGETFLAG_SERVER (1<<1) // Shows up in the server panel.
-#define BUDGETFLAG_OTHER (1<<2) // Unclassified (the client shows these but the dedicated server doesn't).
-#define BUDGETFLAG_HIDDEN (1<<15)
-#define BUDGETFLAG_ALL 0xFFFF
-
-
-// NOTE: You can use strings instead of these defines. . they are defined here and added
-// in vprof.cpp so that they are always in the same order.
-#define VPROF_BUDGETGROUP_OTHER_UNACCOUNTED _T("Unaccounted")
-#define VPROF_BUDGETGROUP_WORLD_RENDERING _T("World Rendering")
-#define VPROF_BUDGETGROUP_DISPLACEMENT_RENDERING _T("Displacement_Rendering")
-#define VPROF_BUDGETGROUP_GAME _T("Game")
-#define VPROF_BUDGETGROUP_NPCS _T("NPCs")
-#define VPROF_BUDGETGROUP_SERVER_ANIM _T("Server Animation")
-#define VPROF_BUDGETGROUP_PHYSICS _T("Physics")
-#define VPROF_BUDGETGROUP_STATICPROP_RENDERING _T("Static_Prop_Rendering")
-#define VPROF_BUDGETGROUP_MODEL_RENDERING _T("Other_Model_Rendering")
-#define VPROF_BUDGETGROUP_MODEL_FAST_PATH_RENDERING _T("Fast Path Model Rendering")
-#define VPROF_BUDGETGROUP_BRUSHMODEL_RENDERING _T("Brush_Model_Rendering")
-#define VPROF_BUDGETGROUP_SHADOW_RENDERING _T("Shadow_Rendering")
-#define VPROF_BUDGETGROUP_DETAILPROP_RENDERING _T("Detail_Prop_Rendering")
-#define VPROF_BUDGETGROUP_PARTICLE_RENDERING _T("Particle/Effect_Rendering")
-#define VPROF_BUDGETGROUP_ROPES _T("Ropes")
-#define VPROF_BUDGETGROUP_DLIGHT_RENDERING _T("Dynamic_Light_Rendering")
-#define VPROF_BUDGETGROUP_OTHER_NETWORKING _T("Networking")
-#define VPROF_BUDGETGROUP_CLIENT_ANIMATION _T("Client_Animation")
-#define VPROF_BUDGETGROUP_OTHER_SOUND _T("Sound")
-#define VPROF_BUDGETGROUP_OTHER_VGUI _T("VGUI")
-#define VPROF_BUDGETGROUP_OTHER_FILESYSTEM _T("FileSystem")
-#define VPROF_BUDGETGROUP_PREDICTION _T("Prediction")
-#define VPROF_BUDGETGROUP_INTERPOLATION _T("Interpolation")
-#define VPROF_BUDGETGROUP_SWAP_BUFFERS _T("Swap_Buffers")
-#define VPROF_BUDGETGROUP_PLAYER _T("Player")
-#define VPROF_BUDGETGROUP_OCCLUSION _T("Occlusion")
-#define VPROF_BUDGETGROUP_OVERLAYS _T("Overlays")
-#define VPROF_BUDGETGROUP_TOOLS _T("Tools")
-#define VPROF_BUDGETGROUP_LIGHTCACHE _T("Light_Cache")
-#define VPROF_BUDGETGROUP_DISP_HULLTRACES _T("Displacement_Hull_Traces")
-#define VPROF_BUDGETGROUP_TEXTURE_CACHE _T("Texture_Cache")
-#define VPROF_BUDGETGROUP_REPLAY _T("Replay")
-#define VPROF_BUDGETGROUP_PARTICLE_SIMULATION _T("Particle Simulation")
-#define VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING _T("Flashlight Shadows")
-#define VPROF_BUDGETGROUP_CLIENT_SIM _T("Client Simulation") // think functions, tempents, etc.
-#define VPROF_BUDGETGROUP_STEAM _T("Steam")
-#define VPROF_BUDGETGROUP_CVAR_FIND _T("Cvar_Find")
-#define VPROF_BUDGETGROUP_CLIENTLEAFSYSTEM _T("ClientLeafSystem")
-#define VPROF_BUDGETGROUP_JOBS_COROUTINES _T("Jobs/Coroutines")
-#define VPROF_BUDGETGROUP_SLEEPING _T("Sleeping")
-#define VPROF_BUDGETGROUP_THREADINGMAIN _T("ThreadingMain")
-#define VPROF_BUDGETGROUP_CHROMEHTML _T("Chromehtml")
-#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_CHROMEHTML
-#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_CHROMEHTML
-#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_CHROMEHTML
-#define VPROF_BUDGETGROUP_ATTRIBUTES _T("Attributes")
-
-#ifdef _X360
-// update flags
-#define VPROF_UPDATE_BUDGET 0x01 // send budget data every frame
-#define VPROF_UPDATE_TEXTURE_GLOBAL 0x02 // send global texture data every frame
-#define VPROF_UPDATE_TEXTURE_PERFRAME 0x04 // send perframe texture data every frame
-#endif
-
-//-------------------------------------
-
-#ifndef VPROF_LEVEL
-#define VPROF_LEVEL 0
-#endif
-
-//these macros exist to create VProf_<line number> variables. This is important because it avoids /analyze warnings about variable aliasing when VPROF's are nested within each other, and allows
-//for multiple VPROF's to exist within the same scope. Three macros must be used to force the __LINE__ to be resolved prior to the token concatenation, but just ignore the _INTERNAL macros and use
-//the VPROF_VAR_NAME
-#define VPROF_VAR_NAME_INTERNAL_CAT(a, b) a##b
-#define VPROF_VAR_NAME_INTERNAL( a, b ) VPROF_VAR_NAME_INTERNAL_CAT( a, b )
-#define VPROF_VAR_NAME( a ) VPROF_VAR_NAME_INTERNAL( a, __LINE__ )
-
-#define VPROF_0(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags);
-
-#if VPROF_LEVEL > 0
-#define VPROF_1(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags);
-#else
-#define VPROF_1(name,group,assertAccounted,budgetFlags) ((void)0)
-#endif
-
-#if VPROF_LEVEL > 1
-#define VPROF_2(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL4, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags);
-#else
-#define VPROF_2(name,group,assertAccounted,budgetFlags) ((void)0)
-#endif
-
-#if VPROF_LEVEL > 2
-#define VPROF_3(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL5, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags);
-#else
-#define VPROF_3(name,group,assertAccounted,budgetFlags) ((void)0)
-#endif
-
-#if VPROF_LEVEL > 3
-#define VPROF_4(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL6, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags);
-#else
-#define VPROF_4(name,group,assertAccounted,budgetFlags) ((void)0)
-#endif
-
-//-------------------------------------
-
-#ifdef _MSC_VER
-#define VProfCode( code ) \
- if ( 0 ) \
- ; \
- else \
- { \
- VPROF( __FUNCTION__ ": " #code ); \
- code; \
- }
-#else
-#define VProfCode( code ) \
- if ( 0 ) \
- ; \
- else \
- { \
- VPROF( #code ); \
- code; \
- }
-#endif
-
-
-//-------------------------------------
-
-#define VPROF_INCREMENT_COUNTER(name,amount) do { static CVProfCounter _counter( name ); _counter.Increment( amount ); } while( 0 )
-#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) do { static CVProfCounter _counter( name, group ); _counter.Increment( amount ); } while( 0 )
-
-#else
-
-#define VPROF( name ) ((void)0)
-#define VPROF_ASSERT_ACCOUNTED( name ) ((void)0)
-#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) ((void)0)
-#define VPROF_BUDGET( name, group ) ((void)0)
-#define VPROF_BUDGET_FLAGS( name, group, flags ) ((void)0)
-
-#define VPROF_SCOPE_BEGIN( tag ) do {
-#define VPROF_SCOPE_END() } while (0)
-
-#define VPROF_ONLY( expression ) ((void)0)
-
-#define VPROF_ENTER_SCOPE( name )
-#define VPROF_EXIT_SCOPE()
-
-#define VPROF_INCREMENT_COUNTER(name,amount) ((void)0)
-#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) ((void)0)
-
-#define VPROF_TEST_SPIKE( msec ) ((void)0)
-
-#define VProfCode( code ) code
-
-#endif
-
-//-----------------------------------------------------------------------------
-
-#ifdef VPROF_ENABLED
-
-//-----------------------------------------------------------------------------
-//
-// A node in the call graph hierarchy
-//
-
-class DBG_CLASS CVProfNode
-{
-friend class CVProfRecorder;
-friend class CVProfile;
-
-public:
- CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags );
- ~CVProfNode();
-
- CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, int budgetFlags );
- CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName );
- CVProfNode *GetParent();
- CVProfNode *GetSibling();
- CVProfNode *GetPrevSibling();
- CVProfNode *GetChild();
-
- void MarkFrame();
- void ResetPeak();
-
- void Pause();
- void Resume();
- void Reset();
-
- void EnterScope();
- bool ExitScope();
-
- const tchar *GetName();
-
- int GetBudgetGroupID()
- {
- return m_BudgetGroupID;
- }
-
- // Only used by the record/playback stuff.
- void SetBudgetGroupID( int id )
- {
- m_BudgetGroupID = id;
- }
-
- int GetCurCalls();
- double GetCurTime();
- int GetPrevCalls();
- double GetPrevTime();
- int GetTotalCalls();
- double GetTotalTime();
- double GetPeakTime();
-
- double GetCurTimeLessChildren();
- double GetPrevTimeLessChildren();
- double GetTotalTimeLessChildren();
-
- int GetPrevL2CacheMissLessChildren();
- int GetPrevLoadHitStoreLessChildren();
-
- void ClearPrevTime();
-
- int GetL2CacheMisses();
-
- // Not used in the common case...
- void SetCurFrameTime( unsigned long milliseconds );
-
- void SetClientData( int iClientData ) { m_iClientData = iClientData; }
- int GetClientData() const { return m_iClientData; }
-
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-#endif // DBGFLAG_VALIDATE
-
-
-// Used by vprof record/playback.
-private:
-
- void SetUniqueNodeID( int id )
- {
- m_iUniqueNodeID = id;
- }
-
- int GetUniqueNodeID() const
- {
- return m_iUniqueNodeID;
- }
-
- static int s_iCurrentUniqueNodeID;
-
-
-private:
- const tchar *m_pszName;
- CFastTimer m_Timer;
-
- // L2 Cache data.
- int m_iPrevL2CacheMiss;
- int m_iCurL2CacheMiss;
- int m_iTotalL2CacheMiss;
-
-#ifndef _X360
- // L2 Cache data.
- CL2Cache m_L2Cache;
-#else // 360:
-
- unsigned int m_iBitFlags; // see enum below for settings
- CPMCData m_PMCData;
- int m_iPrevLoadHitStores;
- int m_iCurLoadHitStores;
- int m_iTotalLoadHitStores;
-
- public:
- enum FlagBits
- {
- kRecordL2 = 0x01,
- kCPUTrace = 0x02, ///< cause a PIX trace inside this node.
- };
- // call w/ true to enable L2 and LHS recording; false to turn it off
- inline void EnableL2andLHS(bool enable)
- {
- if (enable)
- m_iBitFlags |= kRecordL2;
- else
- m_iBitFlags &= (~kRecordL2);
- }
-
- inline bool IsL2andLHSEnabled( void )
- {
- return (m_iBitFlags & kRecordL2) != 0;
- }
-
- int GetLoadHitStores();
-
- private:
-
-#endif
-
- int m_nRecursions;
-
- unsigned m_nCurFrameCalls;
- CCycleCount m_CurFrameTime;
-
- unsigned m_nPrevFrameCalls;
- CCycleCount m_PrevFrameTime;
-
- unsigned m_nTotalCalls;
- CCycleCount m_TotalTime;
-
- CCycleCount m_PeakTime;
-
- CVProfNode *m_pParent;
- CVProfNode *m_pChild;
- CVProfNode *m_pSibling;
-
- int m_BudgetGroupID;
-
- int m_iClientData;
- int m_iUniqueNodeID;
-};
-
-//-----------------------------------------------------------------------------
-//
-// Coordinator and root node of the profile hierarchy tree
-//
-
-enum VProfReportType_t
-{
- VPRT_SUMMARY = ( 1 << 0 ),
- VPRT_HIERARCHY = ( 1 << 1 ),
- VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY = ( 1 << 2 ),
- VPRT_LIST_BY_TIME = ( 1 << 3 ),
- VPRT_LIST_BY_TIME_LESS_CHILDREN = ( 1 << 4 ),
- VPRT_LIST_BY_AVG_TIME = ( 1 << 5 ),
- VPRT_LIST_BY_AVG_TIME_LESS_CHILDREN = ( 1 << 6 ),
- VPRT_LIST_BY_PEAK_TIME = ( 1 << 7 ),
- VPRT_LIST_BY_PEAK_OVER_AVERAGE = ( 1 << 8 ),
- VPRT_LIST_TOP_ITEMS_ONLY = ( 1 << 9 ),
-
- VPRT_FULL = (0xffffffff & ~(VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY|VPRT_LIST_TOP_ITEMS_ONLY)),
-};
-
-enum CounterGroup_t
-{
- COUNTER_GROUP_DEFAULT=0,
- COUNTER_GROUP_NO_RESET, // The engine doesn't reset these counters. Usually, they are used
- // like global variables that can be accessed across modules.
- COUNTER_GROUP_TEXTURE_GLOBAL, // Global texture usage counters (totals for what is currently in memory).
- COUNTER_GROUP_TEXTURE_PER_FRAME, // Per-frame texture usage counters.
-
- COUNTER_GROUP_TELEMETRY,
-};
-
-class DBG_CLASS CVProfile
-{
-public:
- CVProfile();
- ~CVProfile();
-
- void Term();
-
- //
- // Runtime operations
- //
-
- void Start();
- void Stop();
-
- void SetTargetThreadId( unsigned id ) { m_TargetThreadId = id; }
- unsigned GetTargetThreadId() { return m_TargetThreadId; }
- bool InTargetThread() { return ( m_TargetThreadId == ThreadGetCurrentId() ); }
-
-#ifdef _X360
- enum VXConsoleReportMode_t
- {
- VXCONSOLE_REPORT_TIME = 0,
- VXCONSOLE_REPORT_L2CACHE_MISSES,
- VXCONSOLE_REPORT_LOAD_HIT_STORE,
- VXCONSOLE_REPORT_COUNT,
- };
-
- void VXProfileStart();
- void VXProfileUpdate();
- void VXEnableUpdateMode( int event, bool bEnable );
- void VXSendNodes( void );
-
- void PMCDisableAllNodes(CVProfNode *pStartNode = NULL); ///< turn off l2 and lhs recording for everywhere
- bool PMCEnableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node
- bool PMCDisableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node
-
- void DumpEnabledPMCNodes( void );
-
- void VXConsoleReportMode( VXConsoleReportMode_t mode );
- void VXConsoleReportScale( VXConsoleReportMode_t mode, float flScale );
-
- // the CPU trace mode is actually a small state machine; it can be off, primed for
- // single capture, primed for everything-in-a-frame capture, or currently in everything-in-a-frame
- // capture.
- enum CPUTraceState
- {
- kDisabled,
- kFirstHitNode, // record from the first time we hit the node until that node ends
- kAllNodesInFrame_WaitingForMark, // we're going to record all the times a node is hit in a frame, but are waiting for the frame to start
- kAllNodesInFrame_Recording, // we're recording all hits on a node this frame.
-
- // Same as above, but going to record for > 1 frame
- kAllNodesInFrame_WaitingForMarkMultiFrame, // we're going to record all the times a node is hit in a frame, but are waiting for the frame to start
- kAllNodesInFrame_RecordingMultiFrame,
- };
-
- // Global switch to turn CPU tracing on or off at all. The idea is you set up a node first,
- // then trigger tracing by throwing this to true. It'll reset back to false after the trace
- // happens.
- inline CPUTraceState GetCPUTraceMode();
- inline void SetCPUTraceEnabled( CPUTraceState enabled, bool bTraceCompleteEvent = false, int nNumFrames = -1 );
- inline void IncrementMultiTraceIndex(); // tick up the counter that gets appended to the multi-per-frame traces
- inline unsigned int GetMultiTraceIndex(); // return the counter
- void CPUTraceDisableAllNodes( CVProfNode *pStartNode = NULL ); // disable the cpu trace flag wherever it may be
- CVProfNode *CPUTraceEnableForNode( const tchar *pszNodeName ); // enable cpu trace on this node only, disabling it wherever else it may be on.
- CVProfNode *CPUTraceGetEnabledNode( CVProfNode *pStartNode = NULL ); // return the node enabled for CPU tracing, or NULL.
- const char *GetCPUTraceFilename(); // get the filename the trace should write into.
- const char *SetCPUTraceFilename( const char *filename ); // set the filename the trace should write into. (don't specify the extension; I'll do that.)
- inline bool TraceCompleteEvent( void );
-
-#ifdef _X360
- void LatchMultiFrame( int64 cycles );
- void SpewWorstMultiFrame();
-#endif
-
-#endif
-
- void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted );
- void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags );
- void ExitScope();
-
- void MarkFrame();
- void ResetPeaks();
-
- void Pause();
- void Resume();
- void Reset();
-
- bool IsEnabled() const;
- int GetDetailLevel() const;
-
- bool AtRoot() const;
-
- //
- // Queries
- //
-
-#ifdef VPROF_VTUNE_GROUP
-# define MAX_GROUP_STACK_DEPTH 1024
-
- void EnableVTuneGroup( const tchar *pGroupName )
- {
- m_nVTuneGroupID = BudgetGroupNameToBudgetGroupID( pGroupName );
- m_bVTuneGroupEnabled = true;
- }
- void DisableVTuneGroup( void )
- {
- m_bVTuneGroupEnabled = false;
- }
-
- inline void PushGroup( int nGroupID );
- inline void PopGroup( void );
-#endif
-
- int NumFramesSampled() { return m_nFrames; }
- double GetPeakFrameTime();
- double GetTotalTimeSampled();
- double GetTimeLastFrame();
-
- CVProfNode *GetRoot();
- CVProfNode *FindNode( CVProfNode *pStartNode, const tchar *pszNode );
- CVProfNode *GetCurrentNode();
-
- typedef void ( __cdecl *StreamOut_t )( const char* pszFormat, ... );
- // Set the output function used for all vprof reports. Call this with NULL
- // to set it to the default output function.
- void SetOutputStream( StreamOut_t outputStream );
- void OutputReport( int type = VPRT_FULL, const tchar *pszStartNode = NULL, int budgetGroupID = -1 );
-
- const tchar *GetBudgetGroupName( int budgetGroupID );
- int GetBudgetGroupFlags( int budgetGroupID ) const; // Returns a combination of BUDGETFLAG_ defines.
- int GetNumBudgetGroups( void );
- void GetBudgetGroupColor( int budgetGroupID, int &r, int &g, int &b, int &a );
- int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName );
- int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName, int budgetFlagsToORIn );
- void RegisterNumBudgetGroupsChangedCallBack( void (*pCallBack)(void) );
-
- int BudgetGroupNameToBudgetGroupIDNoCreate( const tchar *pBudgetGroupName ) { return FindBudgetGroupName( pBudgetGroupName ); }
-
- void HideBudgetGroup( int budgetGroupID, bool bHide = true );
- void HideBudgetGroup( const char *pszName, bool bHide = true ) { HideBudgetGroup( BudgetGroupNameToBudgetGroupID( pszName), bHide ); }
-
- int *FindOrCreateCounter( const tchar *pName, CounterGroup_t eCounterGroup=COUNTER_GROUP_DEFAULT );
- void ResetCounters( CounterGroup_t eCounterGroup );
-
- int GetNumCounters( void ) const;
-
- const tchar *GetCounterName( int index ) const;
- int GetCounterValue( int index ) const;
- const tchar *GetCounterNameAndValue( int index, int &val ) const;
- CounterGroup_t GetCounterGroup( int index ) const;
-
- // Performance monitoring events.
- void PMEInitialized( bool bInit ) { m_bPMEInit = bInit; }
- void PMEEnable( bool bEnable ) { m_bPMEEnabled = bEnable; }
-
-#ifndef _X360
- bool UsePME( void ) { return ( m_bPMEInit && m_bPMEEnabled ); }
-#else
- bool UsePME( void ) { return ( CPMCData::IsInitialized() && m_bPMEEnabled ); }
-#endif
-
-#ifdef DBGFLAG_VALIDATE
- void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
-#endif // DBGFLAG_VALIDATE
-
-protected:
-
- void FreeNodes_R( CVProfNode *pNode );
-
-#ifdef VPROF_VTUNE_GROUP
- bool VTuneGroupEnabled()
- {
- return m_bVTuneGroupEnabled;
- }
- int VTuneGroupID()
- {
- return m_nVTuneGroupID;
- }
-#endif
-
- void SumTimes( const tchar *pszStartNode, int budgetGroupID );
- void SumTimes( CVProfNode *pNode, int budgetGroupID );
- void DumpNodes( CVProfNode *pNode, int indent, bool bAverageAndCountOnly );
- int FindBudgetGroupName( const tchar *pBudgetGroupName );
- int AddBudgetGroupName( const tchar *pBudgetGroupName, int budgetFlags );
-
-#ifdef VPROF_VTUNE_GROUP
- bool m_bVTuneGroupEnabled;
- int m_nVTuneGroupID;
- int m_GroupIDStack[MAX_GROUP_STACK_DEPTH];
- int m_GroupIDStackDepth;
-#endif
- int m_enabled;
- bool m_fAtRoot; // tracked for efficiency of the "not profiling" case
- CVProfNode *m_pCurNode;
- CVProfNode m_Root;
- int m_nFrames;
- int m_ProfileDetailLevel;
- int m_pausedEnabledDepth;
-
- class CBudgetGroup
- {
- public:
- tchar *m_pName;
- int m_BudgetFlags;
- };
-
- CBudgetGroup *m_pBudgetGroups;
- int m_nBudgetGroupNamesAllocated;
- int m_nBudgetGroupNames;
- void (*m_pNumBudgetGroupsChangedCallBack)(void);
-
- // Performance monitoring events.
- bool m_bPMEInit;
- bool m_bPMEEnabled;
-
- int m_Counters[MAXCOUNTERS];
- char m_CounterGroups[MAXCOUNTERS]; // (These are CounterGroup_t's).
- tchar *m_CounterNames[MAXCOUNTERS];
- int m_NumCounters;
-
-#ifdef _X360
- int m_UpdateMode;
- CPUTraceState m_iCPUTraceEnabled;
- int m_nFramesRemaining;
- int m_nFrameCount;
- int64 m_WorstCycles;
- char m_WorstTraceFilename[128];
- char m_CPUTraceFilename[128];
- unsigned int m_iSuccessiveTraceIndex;
- VXConsoleReportMode_t m_ReportMode;
- float m_pReportScale[VXCONSOLE_REPORT_COUNT];
- bool m_bTraceCompleteEvent;
-#endif
-
- unsigned m_TargetThreadId;
-
- StreamOut_t m_pOutputStream;
-};
-
-//-------------------------------------
-
-DBG_INTERFACE CVProfile g_VProfCurrentProfile;
-
-
-//-----------------------------------------------------------------------------
-
-DBG_INTERFACE bool g_VProfSignalSpike;
-
-class CVProfSpikeDetector
-{
-public:
- CVProfSpikeDetector( float spike ) :
- m_timeLast( GetTimeLast() )
- {
- m_spike = spike;
- m_Timer.Start();
- }
-
- ~CVProfSpikeDetector()
- {
- m_Timer.End();
- if ( Plat_FloatTime() - m_timeLast > 2.0 )
- {
- m_timeLast = Plat_FloatTime();
- if ( m_Timer.GetDuration().GetMillisecondsF() > m_spike )
- {
- g_VProfSignalSpike = true;
- }
- }
- }
-
-private:
- static float &GetTimeLast() { static float timeLast = 0; return timeLast; }
- CFastTimer m_Timer;
- float m_spike;
- float &m_timeLast;
-};
-
-
-// Macro to signal a local spike. Meant as temporary instrumentation, do not leave in code
-#define VPROF_TEST_SPIKE( msec ) CVProfSpikeDetector UNIQUE_ID( msec )
-
-//-----------------------------------------------------------------------------
-
-#ifdef VPROF_VTUNE_GROUP
-inline void CVProfile::PushGroup( int nGroupID )
-{
- // There is always at least one item on the stack since we force
- // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED.
- Assert( m_GroupIDStackDepth > 0 );
- Assert( m_GroupIDStackDepth < MAX_GROUP_STACK_DEPTH );
- m_GroupIDStack[m_GroupIDStackDepth] = nGroupID;
- m_GroupIDStackDepth++;
- if( m_GroupIDStack[m_GroupIDStackDepth-2] != nGroupID &&
- VTuneGroupEnabled() &&
- nGroupID == VTuneGroupID() )
- {
- vtune( true );
- }
-}
-#endif // VPROF_VTUNE_GROUP
-
-#ifdef VPROF_VTUNE_GROUP
-inline void CVProfile::PopGroup( void )
-{
- m_GroupIDStackDepth--;
- // There is always at least one item on the stack since we force
- // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED.
- Assert( m_GroupIDStackDepth > 0 );
- if( m_GroupIDStack[m_GroupIDStackDepth] != m_GroupIDStack[m_GroupIDStackDepth+1] &&
- VTuneGroupEnabled() &&
- m_GroupIDStack[m_GroupIDStackDepth+1] == VTuneGroupID() )
- {
- vtune( false );
- }
-}
-#endif // VPROF_VTUNE_GROUP
-
-//-----------------------------------------------------------------------------
-
-class CVProfScope
-{
-public:
- CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags );
- ~CVProfScope();
-
-private:
- bool m_bEnabled;
-};
-
-//-----------------------------------------------------------------------------
-//
-// CVProfNode, inline methods
-//
-
-inline CVProfNode::CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags )
- : m_pszName( pszName ),
- m_nCurFrameCalls( 0 ),
- m_nPrevFrameCalls( 0 ),
- m_nRecursions( 0 ),
- m_pParent( pParent ),
- m_pChild( NULL ),
- m_pSibling( NULL ),
- m_iClientData( -1 )
-#ifdef _X360
- , m_iBitFlags( 0 )
-#endif
-{
- m_iUniqueNodeID = s_iCurrentUniqueNodeID++;
-
- if ( m_iUniqueNodeID > 0 )
- {
- m_BudgetGroupID = g_VProfCurrentProfile.BudgetGroupNameToBudgetGroupID( pBudgetGroupName, budgetFlags );
- }
- else
- {
- m_BudgetGroupID = 0; // "m_Root" can't call BudgetGroupNameToBudgetGroupID because g_VProfCurrentProfile not yet initialized
- }
-
- Reset();
-
- if( m_pParent && ( m_BudgetGroupID == VPROF_BUDGET_GROUP_ID_UNACCOUNTED ) )
- {
- m_BudgetGroupID = m_pParent->GetBudgetGroupID();
- }
-}
-
-
-//-------------------------------------
-
-inline CVProfNode *CVProfNode::GetParent()
-{
- Assert( m_pParent );
- return m_pParent;
-}
-
-//-------------------------------------
-
-inline CVProfNode *CVProfNode::GetSibling()
-{
- return m_pSibling;
-}
-
-//-------------------------------------
-// Hacky way to the previous sibling, only used from vprof panel at the moment,
-// so it didn't seem like it was worth the memory waste to add the reverse
-// link per node.
-
-inline CVProfNode *CVProfNode::GetPrevSibling()
-{
- CVProfNode* p = GetParent();
-
- if(!p)
- return NULL;
-
- CVProfNode* s;
- for( s = p->GetChild();
- s && ( s->GetSibling() != this );
- s = s->GetSibling() )
- ;
-
- return s;
-}
-
-//-------------------------------------
-
-inline CVProfNode *CVProfNode::GetChild()
-{
- return m_pChild;
-}
-
-//-------------------------------------
-
-inline const tchar *CVProfNode::GetName()
-{
- Assert( m_pszName );
- return m_pszName;
-}
-
-//-------------------------------------
-
-inline int CVProfNode::GetTotalCalls()
-{
- return m_nTotalCalls;
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetTotalTime()
-{
- return m_TotalTime.GetMillisecondsF();
-}
-
-//-------------------------------------
-
-inline int CVProfNode::GetCurCalls()
-{
- return m_nCurFrameCalls;
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetCurTime()
-{
- return m_CurFrameTime.GetMillisecondsF();
-}
-
-//-------------------------------------
-
-inline int CVProfNode::GetPrevCalls()
-{
- return m_nPrevFrameCalls;
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetPrevTime()
-{
- return m_PrevFrameTime.GetMillisecondsF();
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetPeakTime()
-{
- return m_PeakTime.GetMillisecondsF();
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetTotalTimeLessChildren()
-{
- double result = GetTotalTime();
- CVProfNode *pChild = GetChild();
- while ( pChild )
- {
- result -= pChild->GetTotalTime();
- pChild = pChild->GetSibling();
- }
- return result;
-}
-
-//-------------------------------------
-
-inline double CVProfNode::GetCurTimeLessChildren()
-{
- double result = GetCurTime();
- CVProfNode *pChild = GetChild();
- while ( pChild )
- {
- result -= pChild->GetCurTime();
- pChild = pChild->GetSibling();
- }
- return result;
-}
-
-inline double CVProfNode::GetPrevTimeLessChildren()
-{
- double result = GetPrevTime();
- CVProfNode *pChild = GetChild();
- while ( pChild )
- {
- result -= pChild->GetPrevTime();
- pChild = pChild->GetSibling();
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-inline int CVProfNode::GetPrevL2CacheMissLessChildren()
-{
- int result = m_iPrevL2CacheMiss;
- CVProfNode *pChild = GetChild();
- while ( pChild )
- {
- result -= pChild->m_iPrevL2CacheMiss;
- pChild = pChild->GetSibling();
- }
- return result;
-}
-
-//-----------------------------------------------------------------------------
-inline int CVProfNode::GetPrevLoadHitStoreLessChildren()
-{
-#ifndef _X360
- return 0;
-#else
- int result = m_iPrevLoadHitStores;
- CVProfNode *pChild = GetChild();
- while ( pChild )
- {
- result -= pChild->m_iPrevLoadHitStores;
- pChild = pChild->GetSibling();
- }
- return result;
-#endif
-}
-
-
-//-----------------------------------------------------------------------------
-inline void CVProfNode::ClearPrevTime()
-{
- m_PrevFrameTime.Init();
-}
-
-//-----------------------------------------------------------------------------
-inline int CVProfNode::GetL2CacheMisses( void )
-{
-#ifndef _X360
- return m_L2Cache.GetL2CacheMisses();
-#else
- return m_iTotalL2CacheMiss;
-#endif
-}
-
-#ifdef _X360
-inline int CVProfNode::GetLoadHitStores( void )
-{
- return m_iTotalLoadHitStores;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-//
-// CVProfile, inline methods
-//
-
-//-------------------------------------
-
-inline bool CVProfile::IsEnabled() const
-{
- return ( m_enabled != 0 );
-}
-
-//-------------------------------------
-
-inline int CVProfile::GetDetailLevel() const
-{
- return m_ProfileDetailLevel;
-}
-
-
-//-------------------------------------
-
-inline bool CVProfile::AtRoot() const
-{
- return m_fAtRoot;
-}
-
-//-------------------------------------
-
-inline void CVProfile::Start()
-{
- if ( ++m_enabled == 1 )
- {
- m_Root.EnterScope();
-#ifdef _X360
- VXProfileStart();
- CPMCData::InitializeOnceProgramWide();
-#endif
- }
-}
-
-//-------------------------------------
-
-inline void CVProfile::Stop()
-{
- if ( --m_enabled == 0 )
- m_Root.ExitScope();
-}
-
-//-------------------------------------
-
-inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags )
-{
- if ( ( m_enabled != 0 || !m_fAtRoot ) && InTargetThread() ) // if became disabled, need to unwind back to root before stopping
- {
- // Only account for vprof stuff on the primary thread.
- //if( !Plat_IsPrimaryThread() )
- // return;
-
- if ( pszName != m_pCurNode->GetName() )
- {
- m_pCurNode = m_pCurNode->GetSubNode( pszName, detailLevel, pBudgetGroupName, budgetFlags );
- }
- m_pBudgetGroups[m_pCurNode->GetBudgetGroupID()].m_BudgetFlags |= budgetFlags;
-
-#if defined( _DEBUG ) && !defined( _X360 )
- // 360 doesn't want this to allow tier0 debug/release .def files to match
- if ( bAssertAccounted )
- {
- // FIXME
- AssertOnce( m_pCurNode->GetBudgetGroupID() != 0 );
- }
-#endif
- m_pCurNode->EnterScope();
- m_fAtRoot = false;
- }
-#if defined(_X360) && defined(VPROF_PIX)
- if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED )
- PIXBeginNamedEvent( 0, pszName );
-#endif
-}
-
-inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted )
-{
- EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, BUDGETFLAG_OTHER );
-}
-
-//-------------------------------------
-
-inline void CVProfile::ExitScope()
-{
-#if defined(_X360) && defined(VPROF_PIX)
-#ifdef PIXBeginNamedEvent
-#error
-#endif
- if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED )
- PIXEndNamedEvent();
-#endif
- if ( ( !m_fAtRoot || m_enabled != 0 ) && InTargetThread() )
- {
- // Only account for vprof stuff on the primary thread.
- //if( !Plat_IsPrimaryThread() )
- // return;
-
- // ExitScope will indicate whether we should back up to our parent (we may
- // be profiling a recursive function)
- if (m_pCurNode->ExitScope())
- {
- m_pCurNode = m_pCurNode->GetParent();
- }
- m_fAtRoot = ( m_pCurNode == &m_Root );
- }
-}
-
-//-------------------------------------
-
-inline void CVProfile::Pause()
-{
- m_pausedEnabledDepth = m_enabled;
- m_enabled = 0;
- if ( !AtRoot() )
- m_Root.Pause();
-}
-
-//-------------------------------------
-
-inline void CVProfile::Resume()
-{
- m_enabled = m_pausedEnabledDepth;
- if ( !AtRoot() )
- m_Root.Resume();
-}
-
-//-------------------------------------
-
-inline void CVProfile::Reset()
-{
- m_Root.Reset();
- m_nFrames = 0;
-}
-
-//-------------------------------------
-
-inline void CVProfile::ResetPeaks()
-{
- m_Root.ResetPeak();
-}
-
-//-------------------------------------
-
-inline void CVProfile::MarkFrame()
-{
- if ( m_enabled )
- {
- ++m_nFrames;
- m_Root.ExitScope();
- m_Root.MarkFrame();
- m_Root.EnterScope();
-
-#ifdef _X360
- // update the CPU trace state machine if enabled
- switch ( GetCPUTraceMode() )
- {
- case kAllNodesInFrame_WaitingForMark:
- // mark! Start recording a zillion traces.
- m_iCPUTraceEnabled = kAllNodesInFrame_Recording;
- break;
- case kAllNodesInFrame_WaitingForMarkMultiFrame:
- m_iCPUTraceEnabled = kAllNodesInFrame_RecordingMultiFrame;
- break;
- case kAllNodesInFrame_Recording:
- // end of frame. stop recording if no more frames needed
- m_iCPUTraceEnabled = kDisabled;
- Msg("Frame ended. Recording no more CPU traces\n");
-
- break;
- case kAllNodesInFrame_RecordingMultiFrame:
- // end of frame. stop recording if no more frames needed
- if ( --m_nFramesRemaining == 0 )
- {
- m_iCPUTraceEnabled = kDisabled;
- Msg("Frames ended. Recording no more CPU traces\n");
-
- SpewWorstMultiFrame();
- }
-
- ++m_nFrameCount;
-
- break;
- default:
- // no default
- break;
- }
-#endif
- }
-}
-
-//-------------------------------------
-
-inline double CVProfile::GetTotalTimeSampled()
-{
- return m_Root.GetTotalTime();
-}
-
-//-------------------------------------
-
-inline double CVProfile::GetPeakFrameTime()
-{
- return m_Root.GetPeakTime();
-}
-
-//-------------------------------------
-
-inline double CVProfile::GetTimeLastFrame()
-{
- return m_Root.GetCurTime();
-}
-
-//-------------------------------------
-
-inline CVProfNode *CVProfile::GetRoot()
-{
- return &m_Root;
-}
-
-//-------------------------------------
-
-inline CVProfNode *CVProfile::GetCurrentNode()
-{
- return m_pCurNode;
-}
-
-
-inline const tchar *CVProfile::GetBudgetGroupName( int budgetGroupID )
-{
- Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames );
- return m_pBudgetGroups[budgetGroupID].m_pName;
-}
-
-inline int CVProfile::GetBudgetGroupFlags( int budgetGroupID ) const
-{
- Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames );
- return m_pBudgetGroups[budgetGroupID].m_BudgetFlags;
-}
-
-#ifdef _X360
-
-inline CVProfile::CPUTraceState CVProfile::GetCPUTraceMode()
-{
- return m_iCPUTraceEnabled;
-}
-
-inline void CVProfile::SetCPUTraceEnabled( CPUTraceState enabled, bool bTraceCompleteEvent /*=true*/, int nNumFrames /*= -1*/ )
-{
- m_iCPUTraceEnabled = enabled;
- m_bTraceCompleteEvent = bTraceCompleteEvent;
- if ( nNumFrames != -1 )
- {
- m_nFramesRemaining = nNumFrames;
- m_nFrameCount = 0;
- m_WorstCycles = 0;
- m_WorstTraceFilename[ 0 ] = 0;
- }
-}
-
-inline void CVProfile::IncrementMultiTraceIndex()
-{
- ++m_iSuccessiveTraceIndex;
-}
-
-inline unsigned int CVProfile::GetMultiTraceIndex()
-{
- return m_iSuccessiveTraceIndex;
-}
-
-#endif
-
-
-//-----------------------------------------------------------------------------
-
-inline CVProfScope::CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags )
- : m_bEnabled( g_VProfCurrentProfile.IsEnabled() )
-{
- if ( m_bEnabled )
- {
- g_VProfCurrentProfile.EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, budgetFlags );
- }
-}
-
-//-------------------------------------
-
-inline CVProfScope::~CVProfScope()
-{
- if ( m_bEnabled )
- {
- g_VProfCurrentProfile.ExitScope();
- }
-}
-
-class CVProfCounter
-{
-public:
- CVProfCounter( const tchar *pName, CounterGroup_t group=COUNTER_GROUP_DEFAULT )
- {
- m_pCounter = g_VProfCurrentProfile.FindOrCreateCounter( pName, group );
- Assert( m_pCounter );
- }
- ~CVProfCounter()
- {
- }
- void Increment( int val )
- {
- Assert( m_pCounter );
- *m_pCounter += val;
- }
-private:
- int *m_pCounter;
-};
-
-#endif
-
-#ifdef _X360
-
-#include "xbox/xbox_console.h"
-#include "tracerecording.h"
-#include "tier1/fmtstr.h"
-#pragma comment( lib, "tracerecording.lib" )
-#pragma comment( lib, "xbdm.lib" )
-
-class CPIXRecorder
-{
-public:
- CPIXRecorder() : m_bActive( false ) {}
- ~CPIXRecorder() { Stop(); }
-
- void Start( const char *pszFilename = "capture" )
- {
- if ( !m_bActive )
- {
- if ( !XTraceStartRecording( CFmtStr( "e:\\%s.pix2", pszFilename ) ) )
- {
- Msg( "XTraceStartRecording failed, error code %d\n", GetLastError() );
- }
- else
- {
- m_bActive = true;
- }
- }
- }
-
- void Stop()
- {
- if ( m_bActive )
- {
- m_bActive = false;
- if ( XTraceStopRecording() )
- {
- Msg( "CPU trace finished.\n" );
- // signal VXConsole that trace is completed
- XBX_rTraceComplete();
- }
- }
- }
-
-private:
- bool m_bActive;
-};
-
-#define VPROF_BEGIN_PIX_BLOCK( convar ) \
- { \
- bool bRunPix = 0; \
- static CFastTimer PIXTimer; \
- extern ConVar convar; \
- ConVar &PIXConvar = convar; \
- CPIXRecorder PIXRecorder; \
- { \
- PIXLabel: \
- if ( bRunPix ) \
- { \
- PIXRecorder.Start(); \
- } \
- else \
- { \
- if ( PIXConvar.GetBool() ) \
- { \
- PIXTimer.Start(); \
- } \
- } \
- {
-
-
-#define VPROF_END_PIX_BLOCK() \
- } \
- \
- if ( !bRunPix ) \
- { \
- if ( PIXConvar.GetBool() ) \
- { \
- PIXTimer.End(); \
- if ( PIXTimer.GetDuration().GetMillisecondsF() > PIXConvar.GetFloat() ) \
- { \
- PIXConvar.SetValue( 0 ); \
- bRunPix = true; \
- goto PIXLabel; \
- } \
- } \
- } \
- else \
- { \
- PIXRecorder.Stop(); \
- } \
- } \
- }
-#else
-#define VPROF_BEGIN_PIX_BLOCK( PIXConvar ) {
-#define VPROF_END_PIX_BLOCK() }
-#endif
-
-
-#ifdef VPROF_UNDO_PIX
-#undef USE_PIX
-#undef _PIX_H_
-#undef PIXBeginNamedEvent
-#undef PIXEndNamedEvent
-#undef PIXSetMarker
-#undef PIXNameThread
-#include <pix.h>
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
-#endif
-
-//=============================================================================
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Real-Time Hierarchical Profiling
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VPROF_H
+#define VPROF_H
+
+#include "tier0/dbg.h"
+#include "tier0/fasttimer.h"
+#include "tier0/l2cache.h"
+#include "tier0/threadtools.h"
+#include "tier0/vprof_telemetry.h"
+
+// VProf is enabled by default in all configurations -except- X360 Retail.
+#if !( defined( _X360 ) && defined( _CERT ) )
+#define VPROF_ENABLED
+#endif
+
+#if defined(_X360) && defined(VPROF_ENABLED)
+#include "tier0/pmc360.h"
+#ifndef USE_PIX
+#define VPROF_UNDO_PIX
+#undef _PIX_H_
+#undef PIXBeginNamedEvent
+#undef PIXEndNamedEvent
+#undef PIXSetMarker
+#undef PIXNameThread
+#define USE_PIX
+#include <pix.h>
+#undef USE_PIX
+#else
+#include <pix.h>
+#endif
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4251)
+#endif
+
+// enable this to get detailed nodes beneath budget
+// #define VPROF_LEVEL 1
+
+// enable this to use pix (360 only)
+// #define VPROF_PIX 1
+
+#if defined(VPROF_PIX)
+#pragma comment( lib, "Xapilibi" )
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// Profiling instrumentation macros
+//
+
+#define MAXCOUNTERS 256
+
+
+#ifdef VPROF_ENABLED
+
+#define VPROF_VTUNE_GROUP
+
+#define VPROF( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0)
+#define VPROF_ASSERT_ACCOUNTED( name ) VPROF_(name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, true, 0)
+#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) VPROF_##detail(name,group, bAssertAccounted, budgetFlags)
+
+#define VPROF_BUDGET( name, group ) VPROF_BUDGET_FLAGS(name, group, BUDGETFLAG_OTHER)
+#define VPROF_BUDGET_FLAGS( name, group, flags ) VPROF_(name, 0, group, false, flags)
+
+#define VPROF_SCOPE_BEGIN( tag ) do { VPROF( tag )
+#define VPROF_SCOPE_END() } while (0)
+
+#define VPROF_ONLY( expression ) expression
+
+#define VPROF_ENTER_SCOPE( name ) g_VProfCurrentProfile.EnterScope( name, 1, VPROF_BUDGETGROUP_OTHER_UNACCOUNTED, false, 0 )
+#define VPROF_EXIT_SCOPE() g_VProfCurrentProfile.ExitScope()
+
+#define VPROF_BUDGET_GROUP_ID_UNACCOUNTED 0
+
+
+// Budgetgroup flags. These are used with VPROF_BUDGET_FLAGS.
+// These control which budget panels the groups show up in.
+// If a budget group uses VPROF_BUDGET, it gets the default
+// which is BUDGETFLAG_OTHER.
+#define BUDGETFLAG_CLIENT (1<<0) // Shows up in the client panel.
+#define BUDGETFLAG_SERVER (1<<1) // Shows up in the server panel.
+#define BUDGETFLAG_OTHER (1<<2) // Unclassified (the client shows these but the dedicated server doesn't).
+#define BUDGETFLAG_HIDDEN (1<<15)
+#define BUDGETFLAG_ALL 0xFFFF
+
+
+// NOTE: You can use strings instead of these defines. . they are defined here and added
+// in vprof.cpp so that they are always in the same order.
+#define VPROF_BUDGETGROUP_OTHER_UNACCOUNTED _T("Unaccounted")
+#define VPROF_BUDGETGROUP_WORLD_RENDERING _T("World Rendering")
+#define VPROF_BUDGETGROUP_DISPLACEMENT_RENDERING _T("Displacement_Rendering")
+#define VPROF_BUDGETGROUP_GAME _T("Game")
+#define VPROF_BUDGETGROUP_NPCS _T("NPCs")
+#define VPROF_BUDGETGROUP_SERVER_ANIM _T("Server Animation")
+#define VPROF_BUDGETGROUP_PHYSICS _T("Physics")
+#define VPROF_BUDGETGROUP_STATICPROP_RENDERING _T("Static_Prop_Rendering")
+#define VPROF_BUDGETGROUP_MODEL_RENDERING _T("Other_Model_Rendering")
+#define VPROF_BUDGETGROUP_MODEL_FAST_PATH_RENDERING _T("Fast Path Model Rendering")
+#define VPROF_BUDGETGROUP_BRUSHMODEL_RENDERING _T("Brush_Model_Rendering")
+#define VPROF_BUDGETGROUP_SHADOW_RENDERING _T("Shadow_Rendering")
+#define VPROF_BUDGETGROUP_DETAILPROP_RENDERING _T("Detail_Prop_Rendering")
+#define VPROF_BUDGETGROUP_PARTICLE_RENDERING _T("Particle/Effect_Rendering")
+#define VPROF_BUDGETGROUP_ROPES _T("Ropes")
+#define VPROF_BUDGETGROUP_DLIGHT_RENDERING _T("Dynamic_Light_Rendering")
+#define VPROF_BUDGETGROUP_OTHER_NETWORKING _T("Networking")
+#define VPROF_BUDGETGROUP_CLIENT_ANIMATION _T("Client_Animation")
+#define VPROF_BUDGETGROUP_OTHER_SOUND _T("Sound")
+#define VPROF_BUDGETGROUP_OTHER_VGUI _T("VGUI")
+#define VPROF_BUDGETGROUP_OTHER_FILESYSTEM _T("FileSystem")
+#define VPROF_BUDGETGROUP_PREDICTION _T("Prediction")
+#define VPROF_BUDGETGROUP_INTERPOLATION _T("Interpolation")
+#define VPROF_BUDGETGROUP_SWAP_BUFFERS _T("Swap_Buffers")
+#define VPROF_BUDGETGROUP_PLAYER _T("Player")
+#define VPROF_BUDGETGROUP_OCCLUSION _T("Occlusion")
+#define VPROF_BUDGETGROUP_OVERLAYS _T("Overlays")
+#define VPROF_BUDGETGROUP_TOOLS _T("Tools")
+#define VPROF_BUDGETGROUP_LIGHTCACHE _T("Light_Cache")
+#define VPROF_BUDGETGROUP_DISP_HULLTRACES _T("Displacement_Hull_Traces")
+#define VPROF_BUDGETGROUP_TEXTURE_CACHE _T("Texture_Cache")
+#define VPROF_BUDGETGROUP_REPLAY _T("Replay")
+#define VPROF_BUDGETGROUP_PARTICLE_SIMULATION _T("Particle Simulation")
+#define VPROF_BUDGETGROUP_SHADOW_DEPTH_TEXTURING _T("Flashlight Shadows")
+#define VPROF_BUDGETGROUP_CLIENT_SIM _T("Client Simulation") // think functions, tempents, etc.
+#define VPROF_BUDGETGROUP_STEAM _T("Steam")
+#define VPROF_BUDGETGROUP_CVAR_FIND _T("Cvar_Find")
+#define VPROF_BUDGETGROUP_CLIENTLEAFSYSTEM _T("ClientLeafSystem")
+#define VPROF_BUDGETGROUP_JOBS_COROUTINES _T("Jobs/Coroutines")
+#define VPROF_BUDGETGROUP_SLEEPING _T("Sleeping")
+#define VPROF_BUDGETGROUP_THREADINGMAIN _T("ThreadingMain")
+#define VPROF_BUDGETGROUP_CHROMEHTML _T("Chromehtml")
+#define VPROF_BUDGETGROUP_VGUI VPROF_BUDGETGROUP_CHROMEHTML
+#define VPROF_BUDGETGROUP_TENFOOT VPROF_BUDGETGROUP_CHROMEHTML
+#define VPROF_BUDGETGROUP_STEAMUI VPROF_BUDGETGROUP_CHROMEHTML
+#define VPROF_BUDGETGROUP_ATTRIBUTES _T("Attributes")
+
+#ifdef _X360
+// update flags
+#define VPROF_UPDATE_BUDGET 0x01 // send budget data every frame
+#define VPROF_UPDATE_TEXTURE_GLOBAL 0x02 // send global texture data every frame
+#define VPROF_UPDATE_TEXTURE_PERFRAME 0x04 // send perframe texture data every frame
+#endif
+
+//-------------------------------------
+
+#ifndef VPROF_LEVEL
+#define VPROF_LEVEL 0
+#endif
+
+//these macros exist to create VProf_<line number> variables. This is important because it avoids /analyze warnings about variable aliasing when VPROF's are nested within each other, and allows
+//for multiple VPROF's to exist within the same scope. Three macros must be used to force the __LINE__ to be resolved prior to the token concatenation, but just ignore the _INTERNAL macros and use
+//the VPROF_VAR_NAME
+#define VPROF_VAR_NAME_INTERNAL_CAT(a, b) a##b
+#define VPROF_VAR_NAME_INTERNAL( a, b ) VPROF_VAR_NAME_INTERNAL_CAT( a, b )
+#define VPROF_VAR_NAME( a ) VPROF_VAR_NAME_INTERNAL( a, __LINE__ )
+
+#define VPROF_0(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL2, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 0, group, assertAccounted, budgetFlags);
+
+#if VPROF_LEVEL > 0
+#define VPROF_1(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL3, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 1, group, assertAccounted, budgetFlags);
+#else
+#define VPROF_1(name,group,assertAccounted,budgetFlags) ((void)0)
+#endif
+
+#if VPROF_LEVEL > 1
+#define VPROF_2(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL4, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 2, group, assertAccounted, budgetFlags);
+#else
+#define VPROF_2(name,group,assertAccounted,budgetFlags) ((void)0)
+#endif
+
+#if VPROF_LEVEL > 2
+#define VPROF_3(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL5, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 3, group, assertAccounted, budgetFlags);
+#else
+#define VPROF_3(name,group,assertAccounted,budgetFlags) ((void)0)
+#endif
+
+#if VPROF_LEVEL > 3
+#define VPROF_4(name,group,assertAccounted,budgetFlags) TM_ZONE( TELEMETRY_LEVEL6, TMZF_NONE, "(%s)%s", group, name ); CVProfScope VPROF_VAR_NAME( VProf_ )(name, 4, group, assertAccounted, budgetFlags);
+#else
+#define VPROF_4(name,group,assertAccounted,budgetFlags) ((void)0)
+#endif
+
+//-------------------------------------
+
+#ifdef _MSC_VER
+#define VProfCode( code ) \
+ if ( 0 ) \
+ ; \
+ else \
+ { \
+ VPROF( __FUNCTION__ ": " #code ); \
+ code; \
+ }
+#else
+#define VProfCode( code ) \
+ if ( 0 ) \
+ ; \
+ else \
+ { \
+ VPROF( #code ); \
+ code; \
+ }
+#endif
+
+
+//-------------------------------------
+
+#define VPROF_INCREMENT_COUNTER(name,amount) do { static CVProfCounter _counter( name ); _counter.Increment( amount ); } while( 0 )
+#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) do { static CVProfCounter _counter( name, group ); _counter.Increment( amount ); } while( 0 )
+
+#else
+
+#define VPROF( name ) ((void)0)
+#define VPROF_ASSERT_ACCOUNTED( name ) ((void)0)
+#define VPROF_( name, detail, group, bAssertAccounted, budgetFlags ) ((void)0)
+#define VPROF_BUDGET( name, group ) ((void)0)
+#define VPROF_BUDGET_FLAGS( name, group, flags ) ((void)0)
+
+#define VPROF_SCOPE_BEGIN( tag ) do {
+#define VPROF_SCOPE_END() } while (0)
+
+#define VPROF_ONLY( expression ) ((void)0)
+
+#define VPROF_ENTER_SCOPE( name )
+#define VPROF_EXIT_SCOPE()
+
+#define VPROF_INCREMENT_COUNTER(name,amount) ((void)0)
+#define VPROF_INCREMENT_GROUP_COUNTER(name,group,amount) ((void)0)
+
+#define VPROF_TEST_SPIKE( msec ) ((void)0)
+
+#define VProfCode( code ) code
+
+#endif
+
+//-----------------------------------------------------------------------------
+
+#ifdef VPROF_ENABLED
+
+//-----------------------------------------------------------------------------
+//
+// A node in the call graph hierarchy
+//
+
+class DBG_CLASS CVProfNode
+{
+friend class CVProfRecorder;
+friend class CVProfile;
+
+public:
+ CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags );
+ ~CVProfNode();
+
+ CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, int budgetFlags );
+ CVProfNode *GetSubNode( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName );
+ CVProfNode *GetParent();
+ CVProfNode *GetSibling();
+ CVProfNode *GetPrevSibling();
+ CVProfNode *GetChild();
+
+ void MarkFrame();
+ void ResetPeak();
+
+ void Pause();
+ void Resume();
+ void Reset();
+
+ void EnterScope();
+ bool ExitScope();
+
+ const tchar *GetName();
+
+ int GetBudgetGroupID()
+ {
+ return m_BudgetGroupID;
+ }
+
+ // Only used by the record/playback stuff.
+ void SetBudgetGroupID( int id )
+ {
+ m_BudgetGroupID = id;
+ }
+
+ int GetCurCalls();
+ double GetCurTime();
+ int GetPrevCalls();
+ double GetPrevTime();
+ int GetTotalCalls();
+ double GetTotalTime();
+ double GetPeakTime();
+
+ double GetCurTimeLessChildren();
+ double GetPrevTimeLessChildren();
+ double GetTotalTimeLessChildren();
+
+ int GetPrevL2CacheMissLessChildren();
+ int GetPrevLoadHitStoreLessChildren();
+
+ void ClearPrevTime();
+
+ int GetL2CacheMisses();
+
+ // Not used in the common case...
+ void SetCurFrameTime( unsigned long milliseconds );
+
+ void SetClientData( int iClientData ) { m_iClientData = iClientData; }
+ int GetClientData() const { return m_iClientData; }
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+#endif // DBGFLAG_VALIDATE
+
+
+// Used by vprof record/playback.
+private:
+
+ void SetUniqueNodeID( int id )
+ {
+ m_iUniqueNodeID = id;
+ }
+
+ int GetUniqueNodeID() const
+ {
+ return m_iUniqueNodeID;
+ }
+
+ static int s_iCurrentUniqueNodeID;
+
+
+private:
+ const tchar *m_pszName;
+ CFastTimer m_Timer;
+
+ // L2 Cache data.
+ int m_iPrevL2CacheMiss;
+ int m_iCurL2CacheMiss;
+ int m_iTotalL2CacheMiss;
+
+#ifndef _X360
+ // L2 Cache data.
+ CL2Cache m_L2Cache;
+#else // 360:
+
+ unsigned int m_iBitFlags; // see enum below for settings
+ CPMCData m_PMCData;
+ int m_iPrevLoadHitStores;
+ int m_iCurLoadHitStores;
+ int m_iTotalLoadHitStores;
+
+ public:
+ enum FlagBits
+ {
+ kRecordL2 = 0x01,
+ kCPUTrace = 0x02, ///< cause a PIX trace inside this node.
+ };
+ // call w/ true to enable L2 and LHS recording; false to turn it off
+ inline void EnableL2andLHS(bool enable)
+ {
+ if (enable)
+ m_iBitFlags |= kRecordL2;
+ else
+ m_iBitFlags &= (~kRecordL2);
+ }
+
+ inline bool IsL2andLHSEnabled( void )
+ {
+ return (m_iBitFlags & kRecordL2) != 0;
+ }
+
+ int GetLoadHitStores();
+
+ private:
+
+#endif
+
+ int m_nRecursions;
+
+ unsigned m_nCurFrameCalls;
+ CCycleCount m_CurFrameTime;
+
+ unsigned m_nPrevFrameCalls;
+ CCycleCount m_PrevFrameTime;
+
+ unsigned m_nTotalCalls;
+ CCycleCount m_TotalTime;
+
+ CCycleCount m_PeakTime;
+
+ CVProfNode *m_pParent;
+ CVProfNode *m_pChild;
+ CVProfNode *m_pSibling;
+
+ int m_BudgetGroupID;
+
+ int m_iClientData;
+ int m_iUniqueNodeID;
+};
+
+//-----------------------------------------------------------------------------
+//
+// Coordinator and root node of the profile hierarchy tree
+//
+
+enum VProfReportType_t
+{
+ VPRT_SUMMARY = ( 1 << 0 ),
+ VPRT_HIERARCHY = ( 1 << 1 ),
+ VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY = ( 1 << 2 ),
+ VPRT_LIST_BY_TIME = ( 1 << 3 ),
+ VPRT_LIST_BY_TIME_LESS_CHILDREN = ( 1 << 4 ),
+ VPRT_LIST_BY_AVG_TIME = ( 1 << 5 ),
+ VPRT_LIST_BY_AVG_TIME_LESS_CHILDREN = ( 1 << 6 ),
+ VPRT_LIST_BY_PEAK_TIME = ( 1 << 7 ),
+ VPRT_LIST_BY_PEAK_OVER_AVERAGE = ( 1 << 8 ),
+ VPRT_LIST_TOP_ITEMS_ONLY = ( 1 << 9 ),
+
+ VPRT_FULL = (0xffffffff & ~(VPRT_HIERARCHY_TIME_PER_FRAME_AND_COUNT_ONLY|VPRT_LIST_TOP_ITEMS_ONLY)),
+};
+
+enum CounterGroup_t
+{
+ COUNTER_GROUP_DEFAULT=0,
+ COUNTER_GROUP_NO_RESET, // The engine doesn't reset these counters. Usually, they are used
+ // like global variables that can be accessed across modules.
+ COUNTER_GROUP_TEXTURE_GLOBAL, // Global texture usage counters (totals for what is currently in memory).
+ COUNTER_GROUP_TEXTURE_PER_FRAME, // Per-frame texture usage counters.
+
+ COUNTER_GROUP_TELEMETRY,
+};
+
+class DBG_CLASS CVProfile
+{
+public:
+ CVProfile();
+ ~CVProfile();
+
+ void Term();
+
+ //
+ // Runtime operations
+ //
+
+ void Start();
+ void Stop();
+
+ void SetTargetThreadId( unsigned id ) { m_TargetThreadId = id; }
+ unsigned GetTargetThreadId() { return m_TargetThreadId; }
+ bool InTargetThread() { return ( m_TargetThreadId == ThreadGetCurrentId() ); }
+
+#ifdef _X360
+ enum VXConsoleReportMode_t
+ {
+ VXCONSOLE_REPORT_TIME = 0,
+ VXCONSOLE_REPORT_L2CACHE_MISSES,
+ VXCONSOLE_REPORT_LOAD_HIT_STORE,
+ VXCONSOLE_REPORT_COUNT,
+ };
+
+ void VXProfileStart();
+ void VXProfileUpdate();
+ void VXEnableUpdateMode( int event, bool bEnable );
+ void VXSendNodes( void );
+
+ void PMCDisableAllNodes(CVProfNode *pStartNode = NULL); ///< turn off l2 and lhs recording for everywhere
+ bool PMCEnableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node
+ bool PMCDisableL2Upon(const tchar *pszNodeName, bool bRecursive = false); ///< enable l2 and lhs recording for one given node
+
+ void DumpEnabledPMCNodes( void );
+
+ void VXConsoleReportMode( VXConsoleReportMode_t mode );
+ void VXConsoleReportScale( VXConsoleReportMode_t mode, float flScale );
+
+ // the CPU trace mode is actually a small state machine; it can be off, primed for
+ // single capture, primed for everything-in-a-frame capture, or currently in everything-in-a-frame
+ // capture.
+ enum CPUTraceState
+ {
+ kDisabled,
+ kFirstHitNode, // record from the first time we hit the node until that node ends
+ kAllNodesInFrame_WaitingForMark, // we're going to record all the times a node is hit in a frame, but are waiting for the frame to start
+ kAllNodesInFrame_Recording, // we're recording all hits on a node this frame.
+
+ // Same as above, but going to record for > 1 frame
+ kAllNodesInFrame_WaitingForMarkMultiFrame, // we're going to record all the times a node is hit in a frame, but are waiting for the frame to start
+ kAllNodesInFrame_RecordingMultiFrame,
+ };
+
+ // Global switch to turn CPU tracing on or off at all. The idea is you set up a node first,
+ // then trigger tracing by throwing this to true. It'll reset back to false after the trace
+ // happens.
+ inline CPUTraceState GetCPUTraceMode();
+ inline void SetCPUTraceEnabled( CPUTraceState enabled, bool bTraceCompleteEvent = false, int nNumFrames = -1 );
+ inline void IncrementMultiTraceIndex(); // tick up the counter that gets appended to the multi-per-frame traces
+ inline unsigned int GetMultiTraceIndex(); // return the counter
+ void CPUTraceDisableAllNodes( CVProfNode *pStartNode = NULL ); // disable the cpu trace flag wherever it may be
+ CVProfNode *CPUTraceEnableForNode( const tchar *pszNodeName ); // enable cpu trace on this node only, disabling it wherever else it may be on.
+ CVProfNode *CPUTraceGetEnabledNode( CVProfNode *pStartNode = NULL ); // return the node enabled for CPU tracing, or NULL.
+ const char *GetCPUTraceFilename(); // get the filename the trace should write into.
+ const char *SetCPUTraceFilename( const char *filename ); // set the filename the trace should write into. (don't specify the extension; I'll do that.)
+ inline bool TraceCompleteEvent( void );
+
+#ifdef _X360
+ void LatchMultiFrame( int64 cycles );
+ void SpewWorstMultiFrame();
+#endif
+
+#endif
+
+ void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted );
+ void EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags );
+ void ExitScope();
+
+ void MarkFrame();
+ void ResetPeaks();
+
+ void Pause();
+ void Resume();
+ void Reset();
+
+ bool IsEnabled() const;
+ int GetDetailLevel() const;
+
+ bool AtRoot() const;
+
+ //
+ // Queries
+ //
+
+#ifdef VPROF_VTUNE_GROUP
+# define MAX_GROUP_STACK_DEPTH 1024
+
+ void EnableVTuneGroup( const tchar *pGroupName )
+ {
+ m_nVTuneGroupID = BudgetGroupNameToBudgetGroupID( pGroupName );
+ m_bVTuneGroupEnabled = true;
+ }
+ void DisableVTuneGroup( void )
+ {
+ m_bVTuneGroupEnabled = false;
+ }
+
+ inline void PushGroup( int nGroupID );
+ inline void PopGroup( void );
+#endif
+
+ int NumFramesSampled() { return m_nFrames; }
+ double GetPeakFrameTime();
+ double GetTotalTimeSampled();
+ double GetTimeLastFrame();
+
+ CVProfNode *GetRoot();
+ CVProfNode *FindNode( CVProfNode *pStartNode, const tchar *pszNode );
+ CVProfNode *GetCurrentNode();
+
+ typedef void ( __cdecl *StreamOut_t )( const char* pszFormat, ... );
+ // Set the output function used for all vprof reports. Call this with NULL
+ // to set it to the default output function.
+ void SetOutputStream( StreamOut_t outputStream );
+ void OutputReport( int type = VPRT_FULL, const tchar *pszStartNode = NULL, int budgetGroupID = -1 );
+
+ const tchar *GetBudgetGroupName( int budgetGroupID );
+ int GetBudgetGroupFlags( int budgetGroupID ) const; // Returns a combination of BUDGETFLAG_ defines.
+ int GetNumBudgetGroups( void );
+ void GetBudgetGroupColor( int budgetGroupID, int &r, int &g, int &b, int &a );
+ int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName );
+ int BudgetGroupNameToBudgetGroupID( const tchar *pBudgetGroupName, int budgetFlagsToORIn );
+ void RegisterNumBudgetGroupsChangedCallBack( void (*pCallBack)(void) );
+
+ int BudgetGroupNameToBudgetGroupIDNoCreate( const tchar *pBudgetGroupName ) { return FindBudgetGroupName( pBudgetGroupName ); }
+
+ void HideBudgetGroup( int budgetGroupID, bool bHide = true );
+ void HideBudgetGroup( const char *pszName, bool bHide = true ) { HideBudgetGroup( BudgetGroupNameToBudgetGroupID( pszName), bHide ); }
+
+ int *FindOrCreateCounter( const tchar *pName, CounterGroup_t eCounterGroup=COUNTER_GROUP_DEFAULT );
+ void ResetCounters( CounterGroup_t eCounterGroup );
+
+ int GetNumCounters( void ) const;
+
+ const tchar *GetCounterName( int index ) const;
+ int GetCounterValue( int index ) const;
+ const tchar *GetCounterNameAndValue( int index, int &val ) const;
+ CounterGroup_t GetCounterGroup( int index ) const;
+
+ // Performance monitoring events.
+ void PMEInitialized( bool bInit ) { m_bPMEInit = bInit; }
+ void PMEEnable( bool bEnable ) { m_bPMEEnabled = bEnable; }
+
+#ifndef _X360
+ bool UsePME( void ) { return ( m_bPMEInit && m_bPMEEnabled ); }
+#else
+ bool UsePME( void ) { return ( CPMCData::IsInitialized() && m_bPMEEnabled ); }
+#endif
+
+#ifdef DBGFLAG_VALIDATE
+ void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
+#endif // DBGFLAG_VALIDATE
+
+protected:
+
+ void FreeNodes_R( CVProfNode *pNode );
+
+#ifdef VPROF_VTUNE_GROUP
+ bool VTuneGroupEnabled()
+ {
+ return m_bVTuneGroupEnabled;
+ }
+ int VTuneGroupID()
+ {
+ return m_nVTuneGroupID;
+ }
+#endif
+
+ void SumTimes( const tchar *pszStartNode, int budgetGroupID );
+ void SumTimes( CVProfNode *pNode, int budgetGroupID );
+ void DumpNodes( CVProfNode *pNode, int indent, bool bAverageAndCountOnly );
+ int FindBudgetGroupName( const tchar *pBudgetGroupName );
+ int AddBudgetGroupName( const tchar *pBudgetGroupName, int budgetFlags );
+
+#ifdef VPROF_VTUNE_GROUP
+ bool m_bVTuneGroupEnabled;
+ int m_nVTuneGroupID;
+ int m_GroupIDStack[MAX_GROUP_STACK_DEPTH];
+ int m_GroupIDStackDepth;
+#endif
+ int m_enabled;
+ bool m_fAtRoot; // tracked for efficiency of the "not profiling" case
+ CVProfNode *m_pCurNode;
+ CVProfNode m_Root;
+ int m_nFrames;
+ int m_ProfileDetailLevel;
+ int m_pausedEnabledDepth;
+
+ class CBudgetGroup
+ {
+ public:
+ tchar *m_pName;
+ int m_BudgetFlags;
+ };
+
+ CBudgetGroup *m_pBudgetGroups;
+ int m_nBudgetGroupNamesAllocated;
+ int m_nBudgetGroupNames;
+ void (*m_pNumBudgetGroupsChangedCallBack)(void);
+
+ // Performance monitoring events.
+ bool m_bPMEInit;
+ bool m_bPMEEnabled;
+
+ int m_Counters[MAXCOUNTERS];
+ char m_CounterGroups[MAXCOUNTERS]; // (These are CounterGroup_t's).
+ tchar *m_CounterNames[MAXCOUNTERS];
+ int m_NumCounters;
+
+#ifdef _X360
+ int m_UpdateMode;
+ CPUTraceState m_iCPUTraceEnabled;
+ int m_nFramesRemaining;
+ int m_nFrameCount;
+ int64 m_WorstCycles;
+ char m_WorstTraceFilename[128];
+ char m_CPUTraceFilename[128];
+ unsigned int m_iSuccessiveTraceIndex;
+ VXConsoleReportMode_t m_ReportMode;
+ float m_pReportScale[VXCONSOLE_REPORT_COUNT];
+ bool m_bTraceCompleteEvent;
+#endif
+
+ unsigned m_TargetThreadId;
+
+ StreamOut_t m_pOutputStream;
+};
+
+//-------------------------------------
+
+DBG_INTERFACE CVProfile g_VProfCurrentProfile;
+
+
+//-----------------------------------------------------------------------------
+
+DBG_INTERFACE bool g_VProfSignalSpike;
+
+class CVProfSpikeDetector
+{
+public:
+ CVProfSpikeDetector( float spike ) :
+ m_timeLast( GetTimeLast() )
+ {
+ m_spike = spike;
+ m_Timer.Start();
+ }
+
+ ~CVProfSpikeDetector()
+ {
+ m_Timer.End();
+ if ( Plat_FloatTime() - m_timeLast > 2.0 )
+ {
+ m_timeLast = Plat_FloatTime();
+ if ( m_Timer.GetDuration().GetMillisecondsF() > m_spike )
+ {
+ g_VProfSignalSpike = true;
+ }
+ }
+ }
+
+private:
+ static float &GetTimeLast() { static float timeLast = 0; return timeLast; }
+ CFastTimer m_Timer;
+ float m_spike;
+ float &m_timeLast;
+};
+
+
+// Macro to signal a local spike. Meant as temporary instrumentation, do not leave in code
+#define VPROF_TEST_SPIKE( msec ) CVProfSpikeDetector UNIQUE_ID( msec )
+
+//-----------------------------------------------------------------------------
+
+#ifdef VPROF_VTUNE_GROUP
+inline void CVProfile::PushGroup( int nGroupID )
+{
+ // There is always at least one item on the stack since we force
+ // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED.
+ Assert( m_GroupIDStackDepth > 0 );
+ Assert( m_GroupIDStackDepth < MAX_GROUP_STACK_DEPTH );
+ m_GroupIDStack[m_GroupIDStackDepth] = nGroupID;
+ m_GroupIDStackDepth++;
+ if( m_GroupIDStack[m_GroupIDStackDepth-2] != nGroupID &&
+ VTuneGroupEnabled() &&
+ nGroupID == VTuneGroupID() )
+ {
+ vtune( true );
+ }
+}
+#endif // VPROF_VTUNE_GROUP
+
+#ifdef VPROF_VTUNE_GROUP
+inline void CVProfile::PopGroup( void )
+{
+ m_GroupIDStackDepth--;
+ // There is always at least one item on the stack since we force
+ // the first element to be VPROF_BUDGETGROUP_OTHER_UNACCOUNTED.
+ Assert( m_GroupIDStackDepth > 0 );
+ if( m_GroupIDStack[m_GroupIDStackDepth] != m_GroupIDStack[m_GroupIDStackDepth+1] &&
+ VTuneGroupEnabled() &&
+ m_GroupIDStack[m_GroupIDStackDepth+1] == VTuneGroupID() )
+ {
+ vtune( false );
+ }
+}
+#endif // VPROF_VTUNE_GROUP
+
+//-----------------------------------------------------------------------------
+
+class CVProfScope
+{
+public:
+ CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags );
+ ~CVProfScope();
+
+private:
+ bool m_bEnabled;
+};
+
+//-----------------------------------------------------------------------------
+//
+// CVProfNode, inline methods
+//
+
+inline CVProfNode::CVProfNode( const tchar * pszName, int detailLevel, CVProfNode *pParent, const tchar *pBudgetGroupName, int budgetFlags )
+ : m_pszName( pszName ),
+ m_nCurFrameCalls( 0 ),
+ m_nPrevFrameCalls( 0 ),
+ m_nRecursions( 0 ),
+ m_pParent( pParent ),
+ m_pChild( NULL ),
+ m_pSibling( NULL ),
+ m_iClientData( -1 )
+#ifdef _X360
+ , m_iBitFlags( 0 )
+#endif
+{
+ m_iUniqueNodeID = s_iCurrentUniqueNodeID++;
+
+ if ( m_iUniqueNodeID > 0 )
+ {
+ m_BudgetGroupID = g_VProfCurrentProfile.BudgetGroupNameToBudgetGroupID( pBudgetGroupName, budgetFlags );
+ }
+ else
+ {
+ m_BudgetGroupID = 0; // "m_Root" can't call BudgetGroupNameToBudgetGroupID because g_VProfCurrentProfile not yet initialized
+ }
+
+ Reset();
+
+ if( m_pParent && ( m_BudgetGroupID == VPROF_BUDGET_GROUP_ID_UNACCOUNTED ) )
+ {
+ m_BudgetGroupID = m_pParent->GetBudgetGroupID();
+ }
+}
+
+
+//-------------------------------------
+
+inline CVProfNode *CVProfNode::GetParent()
+{
+ Assert( m_pParent );
+ return m_pParent;
+}
+
+//-------------------------------------
+
+inline CVProfNode *CVProfNode::GetSibling()
+{
+ return m_pSibling;
+}
+
+//-------------------------------------
+// Hacky way to the previous sibling, only used from vprof panel at the moment,
+// so it didn't seem like it was worth the memory waste to add the reverse
+// link per node.
+
+inline CVProfNode *CVProfNode::GetPrevSibling()
+{
+ CVProfNode* p = GetParent();
+
+ if(!p)
+ return NULL;
+
+ CVProfNode* s;
+ for( s = p->GetChild();
+ s && ( s->GetSibling() != this );
+ s = s->GetSibling() )
+ ;
+
+ return s;
+}
+
+//-------------------------------------
+
+inline CVProfNode *CVProfNode::GetChild()
+{
+ return m_pChild;
+}
+
+//-------------------------------------
+
+inline const tchar *CVProfNode::GetName()
+{
+ Assert( m_pszName );
+ return m_pszName;
+}
+
+//-------------------------------------
+
+inline int CVProfNode::GetTotalCalls()
+{
+ return m_nTotalCalls;
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetTotalTime()
+{
+ return m_TotalTime.GetMillisecondsF();
+}
+
+//-------------------------------------
+
+inline int CVProfNode::GetCurCalls()
+{
+ return m_nCurFrameCalls;
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetCurTime()
+{
+ return m_CurFrameTime.GetMillisecondsF();
+}
+
+//-------------------------------------
+
+inline int CVProfNode::GetPrevCalls()
+{
+ return m_nPrevFrameCalls;
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetPrevTime()
+{
+ return m_PrevFrameTime.GetMillisecondsF();
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetPeakTime()
+{
+ return m_PeakTime.GetMillisecondsF();
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetTotalTimeLessChildren()
+{
+ double result = GetTotalTime();
+ CVProfNode *pChild = GetChild();
+ while ( pChild )
+ {
+ result -= pChild->GetTotalTime();
+ pChild = pChild->GetSibling();
+ }
+ return result;
+}
+
+//-------------------------------------
+
+inline double CVProfNode::GetCurTimeLessChildren()
+{
+ double result = GetCurTime();
+ CVProfNode *pChild = GetChild();
+ while ( pChild )
+ {
+ result -= pChild->GetCurTime();
+ pChild = pChild->GetSibling();
+ }
+ return result;
+}
+
+inline double CVProfNode::GetPrevTimeLessChildren()
+{
+ double result = GetPrevTime();
+ CVProfNode *pChild = GetChild();
+ while ( pChild )
+ {
+ result -= pChild->GetPrevTime();
+ pChild = pChild->GetSibling();
+ }
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+inline int CVProfNode::GetPrevL2CacheMissLessChildren()
+{
+ int result = m_iPrevL2CacheMiss;
+ CVProfNode *pChild = GetChild();
+ while ( pChild )
+ {
+ result -= pChild->m_iPrevL2CacheMiss;
+ pChild = pChild->GetSibling();
+ }
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+inline int CVProfNode::GetPrevLoadHitStoreLessChildren()
+{
+#ifndef _X360
+ return 0;
+#else
+ int result = m_iPrevLoadHitStores;
+ CVProfNode *pChild = GetChild();
+ while ( pChild )
+ {
+ result -= pChild->m_iPrevLoadHitStores;
+ pChild = pChild->GetSibling();
+ }
+ return result;
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+inline void CVProfNode::ClearPrevTime()
+{
+ m_PrevFrameTime.Init();
+}
+
+//-----------------------------------------------------------------------------
+inline int CVProfNode::GetL2CacheMisses( void )
+{
+#ifndef _X360
+ return m_L2Cache.GetL2CacheMisses();
+#else
+ return m_iTotalL2CacheMiss;
+#endif
+}
+
+#ifdef _X360
+inline int CVProfNode::GetLoadHitStores( void )
+{
+ return m_iTotalLoadHitStores;
+}
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// CVProfile, inline methods
+//
+
+//-------------------------------------
+
+inline bool CVProfile::IsEnabled() const
+{
+ return ( m_enabled != 0 );
+}
+
+//-------------------------------------
+
+inline int CVProfile::GetDetailLevel() const
+{
+ return m_ProfileDetailLevel;
+}
+
+
+//-------------------------------------
+
+inline bool CVProfile::AtRoot() const
+{
+ return m_fAtRoot;
+}
+
+//-------------------------------------
+
+inline void CVProfile::Start()
+{
+ if ( ++m_enabled == 1 )
+ {
+ m_Root.EnterScope();
+#ifdef _X360
+ VXProfileStart();
+ CPMCData::InitializeOnceProgramWide();
+#endif
+ }
+}
+
+//-------------------------------------
+
+inline void CVProfile::Stop()
+{
+ if ( --m_enabled == 0 )
+ m_Root.ExitScope();
+}
+
+//-------------------------------------
+
+inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags )
+{
+ if ( ( m_enabled != 0 || !m_fAtRoot ) && InTargetThread() ) // if became disabled, need to unwind back to root before stopping
+ {
+ // Only account for vprof stuff on the primary thread.
+ //if( !Plat_IsPrimaryThread() )
+ // return;
+
+ if ( pszName != m_pCurNode->GetName() )
+ {
+ m_pCurNode = m_pCurNode->GetSubNode( pszName, detailLevel, pBudgetGroupName, budgetFlags );
+ }
+ m_pBudgetGroups[m_pCurNode->GetBudgetGroupID()].m_BudgetFlags |= budgetFlags;
+
+#if defined( _DEBUG ) && !defined( _X360 )
+ // 360 doesn't want this to allow tier0 debug/release .def files to match
+ if ( bAssertAccounted )
+ {
+ // FIXME
+ AssertOnce( m_pCurNode->GetBudgetGroupID() != 0 );
+ }
+#endif
+ m_pCurNode->EnterScope();
+ m_fAtRoot = false;
+ }
+#if defined(_X360) && defined(VPROF_PIX)
+ if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED )
+ PIXBeginNamedEvent( 0, pszName );
+#endif
+}
+
+inline void CVProfile::EnterScope( const tchar *pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted )
+{
+ EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, BUDGETFLAG_OTHER );
+}
+
+//-------------------------------------
+
+inline void CVProfile::ExitScope()
+{
+#if defined(_X360) && defined(VPROF_PIX)
+#ifdef PIXBeginNamedEvent
+#error
+#endif
+ if ( m_pCurNode->GetBudgetGroupID() != VPROF_BUDGET_GROUP_ID_UNACCOUNTED )
+ PIXEndNamedEvent();
+#endif
+ if ( ( !m_fAtRoot || m_enabled != 0 ) && InTargetThread() )
+ {
+ // Only account for vprof stuff on the primary thread.
+ //if( !Plat_IsPrimaryThread() )
+ // return;
+
+ // ExitScope will indicate whether we should back up to our parent (we may
+ // be profiling a recursive function)
+ if (m_pCurNode->ExitScope())
+ {
+ m_pCurNode = m_pCurNode->GetParent();
+ }
+ m_fAtRoot = ( m_pCurNode == &m_Root );
+ }
+}
+
+//-------------------------------------
+
+inline void CVProfile::Pause()
+{
+ m_pausedEnabledDepth = m_enabled;
+ m_enabled = 0;
+ if ( !AtRoot() )
+ m_Root.Pause();
+}
+
+//-------------------------------------
+
+inline void CVProfile::Resume()
+{
+ m_enabled = m_pausedEnabledDepth;
+ if ( !AtRoot() )
+ m_Root.Resume();
+}
+
+//-------------------------------------
+
+inline void CVProfile::Reset()
+{
+ m_Root.Reset();
+ m_nFrames = 0;
+}
+
+//-------------------------------------
+
+inline void CVProfile::ResetPeaks()
+{
+ m_Root.ResetPeak();
+}
+
+//-------------------------------------
+
+inline void CVProfile::MarkFrame()
+{
+ if ( m_enabled )
+ {
+ ++m_nFrames;
+ m_Root.ExitScope();
+ m_Root.MarkFrame();
+ m_Root.EnterScope();
+
+#ifdef _X360
+ // update the CPU trace state machine if enabled
+ switch ( GetCPUTraceMode() )
+ {
+ case kAllNodesInFrame_WaitingForMark:
+ // mark! Start recording a zillion traces.
+ m_iCPUTraceEnabled = kAllNodesInFrame_Recording;
+ break;
+ case kAllNodesInFrame_WaitingForMarkMultiFrame:
+ m_iCPUTraceEnabled = kAllNodesInFrame_RecordingMultiFrame;
+ break;
+ case kAllNodesInFrame_Recording:
+ // end of frame. stop recording if no more frames needed
+ m_iCPUTraceEnabled = kDisabled;
+ Msg("Frame ended. Recording no more CPU traces\n");
+
+ break;
+ case kAllNodesInFrame_RecordingMultiFrame:
+ // end of frame. stop recording if no more frames needed
+ if ( --m_nFramesRemaining == 0 )
+ {
+ m_iCPUTraceEnabled = kDisabled;
+ Msg("Frames ended. Recording no more CPU traces\n");
+
+ SpewWorstMultiFrame();
+ }
+
+ ++m_nFrameCount;
+
+ break;
+ default:
+ // no default
+ break;
+ }
+#endif
+ }
+}
+
+//-------------------------------------
+
+inline double CVProfile::GetTotalTimeSampled()
+{
+ return m_Root.GetTotalTime();
+}
+
+//-------------------------------------
+
+inline double CVProfile::GetPeakFrameTime()
+{
+ return m_Root.GetPeakTime();
+}
+
+//-------------------------------------
+
+inline double CVProfile::GetTimeLastFrame()
+{
+ return m_Root.GetCurTime();
+}
+
+//-------------------------------------
+
+inline CVProfNode *CVProfile::GetRoot()
+{
+ return &m_Root;
+}
+
+//-------------------------------------
+
+inline CVProfNode *CVProfile::GetCurrentNode()
+{
+ return m_pCurNode;
+}
+
+
+inline const tchar *CVProfile::GetBudgetGroupName( int budgetGroupID )
+{
+ Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames );
+ return m_pBudgetGroups[budgetGroupID].m_pName;
+}
+
+inline int CVProfile::GetBudgetGroupFlags( int budgetGroupID ) const
+{
+ Assert( budgetGroupID >= 0 && budgetGroupID < m_nBudgetGroupNames );
+ return m_pBudgetGroups[budgetGroupID].m_BudgetFlags;
+}
+
+#ifdef _X360
+
+inline CVProfile::CPUTraceState CVProfile::GetCPUTraceMode()
+{
+ return m_iCPUTraceEnabled;
+}
+
+inline void CVProfile::SetCPUTraceEnabled( CPUTraceState enabled, bool bTraceCompleteEvent /*=true*/, int nNumFrames /*= -1*/ )
+{
+ m_iCPUTraceEnabled = enabled;
+ m_bTraceCompleteEvent = bTraceCompleteEvent;
+ if ( nNumFrames != -1 )
+ {
+ m_nFramesRemaining = nNumFrames;
+ m_nFrameCount = 0;
+ m_WorstCycles = 0;
+ m_WorstTraceFilename[ 0 ] = 0;
+ }
+}
+
+inline void CVProfile::IncrementMultiTraceIndex()
+{
+ ++m_iSuccessiveTraceIndex;
+}
+
+inline unsigned int CVProfile::GetMultiTraceIndex()
+{
+ return m_iSuccessiveTraceIndex;
+}
+
+#endif
+
+
+//-----------------------------------------------------------------------------
+
+inline CVProfScope::CVProfScope( const tchar * pszName, int detailLevel, const tchar *pBudgetGroupName, bool bAssertAccounted, int budgetFlags )
+ : m_bEnabled( g_VProfCurrentProfile.IsEnabled() )
+{
+ if ( m_bEnabled )
+ {
+ g_VProfCurrentProfile.EnterScope( pszName, detailLevel, pBudgetGroupName, bAssertAccounted, budgetFlags );
+ }
+}
+
+//-------------------------------------
+
+inline CVProfScope::~CVProfScope()
+{
+ if ( m_bEnabled )
+ {
+ g_VProfCurrentProfile.ExitScope();
+ }
+}
+
+class CVProfCounter
+{
+public:
+ CVProfCounter( const tchar *pName, CounterGroup_t group=COUNTER_GROUP_DEFAULT )
+ {
+ m_pCounter = g_VProfCurrentProfile.FindOrCreateCounter( pName, group );
+ Assert( m_pCounter );
+ }
+ ~CVProfCounter()
+ {
+ }
+ void Increment( int val )
+ {
+ Assert( m_pCounter );
+ *m_pCounter += val;
+ }
+private:
+ int *m_pCounter;
+};
+
+#endif
+
+#ifdef _X360
+
+#include "xbox/xbox_console.h"
+#include "tracerecording.h"
+#include "tier1/fmtstr.h"
+#pragma comment( lib, "tracerecording.lib" )
+#pragma comment( lib, "xbdm.lib" )
+
+class CPIXRecorder
+{
+public:
+ CPIXRecorder() : m_bActive( false ) {}
+ ~CPIXRecorder() { Stop(); }
+
+ void Start( const char *pszFilename = "capture" )
+ {
+ if ( !m_bActive )
+ {
+ if ( !XTraceStartRecording( CFmtStr( "e:\\%s.pix2", pszFilename ) ) )
+ {
+ Msg( "XTraceStartRecording failed, error code %d\n", GetLastError() );
+ }
+ else
+ {
+ m_bActive = true;
+ }
+ }
+ }
+
+ void Stop()
+ {
+ if ( m_bActive )
+ {
+ m_bActive = false;
+ if ( XTraceStopRecording() )
+ {
+ Msg( "CPU trace finished.\n" );
+ // signal VXConsole that trace is completed
+ XBX_rTraceComplete();
+ }
+ }
+ }
+
+private:
+ bool m_bActive;
+};
+
+#define VPROF_BEGIN_PIX_BLOCK( convar ) \
+ { \
+ bool bRunPix = 0; \
+ static CFastTimer PIXTimer; \
+ extern ConVar convar; \
+ ConVar &PIXConvar = convar; \
+ CPIXRecorder PIXRecorder; \
+ { \
+ PIXLabel: \
+ if ( bRunPix ) \
+ { \
+ PIXRecorder.Start(); \
+ } \
+ else \
+ { \
+ if ( PIXConvar.GetBool() ) \
+ { \
+ PIXTimer.Start(); \
+ } \
+ } \
+ {
+
+
+#define VPROF_END_PIX_BLOCK() \
+ } \
+ \
+ if ( !bRunPix ) \
+ { \
+ if ( PIXConvar.GetBool() ) \
+ { \
+ PIXTimer.End(); \
+ if ( PIXTimer.GetDuration().GetMillisecondsF() > PIXConvar.GetFloat() ) \
+ { \
+ PIXConvar.SetValue( 0 ); \
+ bRunPix = true; \
+ goto PIXLabel; \
+ } \
+ } \
+ } \
+ else \
+ { \
+ PIXRecorder.Stop(); \
+ } \
+ } \
+ }
+#else
+#define VPROF_BEGIN_PIX_BLOCK( PIXConvar ) {
+#define VPROF_END_PIX_BLOCK() }
+#endif
+
+
+#ifdef VPROF_UNDO_PIX
+#undef USE_PIX
+#undef _PIX_H_
+#undef PIXBeginNamedEvent
+#undef PIXEndNamedEvent
+#undef PIXSetMarker
+#undef PIXNameThread
+#include <pix.h>
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
+
+//=============================================================================
diff --git a/sp/src/public/tier0/vprof_telemetry.h b/sp/src/public/tier0/vprof_telemetry.h
index 2b9c323a..f3df4f4b 100644
--- a/sp/src/public/tier0/vprof_telemetry.h
+++ b/sp/src/public/tier0/vprof_telemetry.h
@@ -1,1051 +1,1051 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Real-Time Hierarchical Telemetry Profiling
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef VPROF_TELEMETRY_H
-#define VPROF_TELEMETRY_H
-
-#if !defined( MAKE_VPC )
-
-#if !defined( RAD_TELEMETRY_DISABLED ) && ( defined( IS_WINDOWS_PC ) || defined( _LINUX ) )
-// Rad Telemetry profiling is enabled on Win32 and Win64.
-#define RAD_TELEMETRY_ENABLED
-#endif
-
-#endif // !defined( MAKE_VPC )
-
-
-#if !defined( RAD_TELEMETRY_ENABLED )
-
-//
-// If Telemetry isn't enabled, then kill all the tmZone() macros, etc.
-//
-#define NTELEMETRY 1
-// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here.
-#undef RADCOPYRIGHT
-
-#include "tmapi_dummy.h"
-
-inline void TelemetryTick() {}
-inline void TelemetrySetLevel( unsigned int Level ) {}
-
-#define TELEMETRY_REQUIRED( tmRequiredCode ) //a basic wrapper to only enable code if telemetry is present
-#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) replacementCode //in case you need to replace the code with something specific if telemetry isn't present
-
-//#define TMZF_NONE
-
-#else
-
-//
-// Telemetry is enabled. Include the telemetry header.
-//
-#include "../../thirdparty/telemetry/include/telemetry.h"
-// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here.
-#undef RADCOPYRIGHT
-
-PLATFORM_INTERFACE void TelemetryTick();
-PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level );
-
-struct TelemetryData
-{
- HTELEMETRY tmContext[32];
- float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to milliseconds.
- uint32 FrameCount; // Count of frames to capture before turning off.
- char ServerAddress[128]; // Server name to connect to.
- uint32 ZoneFilterVal; // tmZoneFiltered default filtered value (in MicroSeconds)
- int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo).
- float dotatime; // CDOTAGamerules::GetDOTATime()
- uint32 DemoTickStart; // Start telemetry on demo tick #
- uint32 DemoTickEnd; // End telemetry on demo tick #
- uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify)
-};
-PLATFORM_INTERFACE TelemetryData g_Telemetry;
-
-#define TELEMETRY_REQUIRED( tmRequiredCode ) tmRequiredCode //a basic wrapper to only enable code if telemetry is present
-#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) tmRequiredCode //in case you need to replace the code with something specific if telemetry isn't present
-
-#endif // RAD_TELEMETRY_ENABLED
-
-
-
-
-
-
-
-
-
-
-#define TELEMETRY_ERROR_BUILD_DISABLED TELEMETRY_REQUIRED_REPLACE( TMERR_DISABLED, 0x0001 )
-#define TELEMETRY_ERROR_DISCONNECTED TELEMETRY_REQUIRED_REPLACE( TMCS_DISCONNECTED, 0 )
-
-
-#define TELEMETRY_LEVEL0 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[0], 0 ) // high level tmZone()
-#define TELEMETRY_LEVEL1 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[1], 0 ) // lower level tmZone(), tmZoneFiltered()
-#define TELEMETRY_LEVEL2 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[2], 0 ) // VPROF_0
-#define TELEMETRY_LEVEL3 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[3], 0 ) // VPROF_1
-#define TELEMETRY_LEVEL4 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[4], 0 ) // VPROF_2
-#define TELEMETRY_LEVEL5 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[5], 0 ) // VPROF_3
-#define TELEMETRY_LEVEL6 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[6], 0 ) // VPROF_4
-
-//__rdtsc()
-#define TM_FAST_TIME() TELEMETRY_REQUIRED_REPLACE( tmFastTime(), 0 )
-
-
-//int RADEXPLINK tmLoadTelemetry( int const kUseCheckedDLL );
-//
-//Description
-// On dynamic library platforms, this function loads the Telemetry DLL (or shared library) and then hooks up all of the dynamic function pointers.
-//Parameters
-// kUseCheckedDLL [in] set to 0 if you want to use the release mode DLL or 1 if you want to use the checked DLL. The checked DLL is compiled with optimizations but does extra run time checks and reporting.
-#define TM_LOAD_TELEMETRY(kUseCheckedDll) TELEMETRY_REQUIRED_REPLACE( tmLoadTelemetry(kUseCheckedDll), 0 )
-
-
-//TmErrorCode tmStartup( );
-//
-//Description
-// Starts up all of Telemetry.
-#define TM_STARTUP() TELEMETRY_REQUIRED_REPLACE( tmStartup(), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmShutdown( );
-//
-//Description
-// Shuts down all of Telemetry.
-#define TM_SHUTDOWN() TELEMETRY_REQUIRED( tmShutdown() )
-
-
-//TmErrorCode tmInitializeContext( HTELEMETRY * pcx,void * pArena,TmU32 const kArenaSize );
-//
-//Description
-// Initializes a context.
-//
-//Parameters
-// pcx [out] pointer to a TmHandle in which to store a handle to the initialized context
-// pArena [in] pointer to a memory buffer for use by Telemetry to create the context. Applications should never free or modify this memory unless tmShutdownContext has been called!
-// kArenaSize [in] size of the memory buffer pointed to by pArena. You want this large enough so that Telemetry never stalls trying to send over the network, but not so large that it takes up too much memory from your app. A good initial value is 1MB.
-#define TM_INITIALIZE_CONTEXT( pContext, pArena, kArenaSize ) TELEMETRY_REQUIRED_REPLACE( tmInitializeContext( pContext, pArena, kArenaSize ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmZoneFiltered( HTELEMETRY cx,TmU64 const kThreshold,TmU32 const kFlags,char const * kpFormat,... );
-//
-//Description
-// Identical to tmZone however also allows specification of threshold duration.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kThreshold [in] microseconds that the zone must span before being sent to server.
-// kFlags [in] flags for the zone (same as those passed to tmEnter.
-// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers.
-#define TM_ZONE_FILTERED( context, kThreshold, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZoneFiltered( context, kThreshold, kFlags, kpFormat, ##__VA_ARGS__ ) )
-
-
-//void tmZone( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormat,... );
-//
-//Description
-// Helper macro in C++ that creates an anonymous local object that automatically calls tmEnter and then tmLeave when exiting scope.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kFlags [in] flags for the zone (same as those passed to tmEnter
-// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers.
-#define TM_ZONE( context, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZone( context, kFlags, kpFormat, ##__VA_ARGS__ ) )
-
-//Standardized zones
-#define TM_ZONE_DEFAULT( context ) TM_ZONE( context, TMZF_NONE, __FUNCTION__ )
-#define TM_ZONE_IDLE( context ) TM_ZONE( context, TMZF_IDLE, __FUNCTION__ )
-#define TM_ZONE_STALL( context ) TM_ZONE( context, TMZF_STALL, __FUNCTION__ )
-
-
-//TmErrorCode tmCheckVersion( HTELEMETRY cx, TmU32 const major, TmU32 const minor, TmU32 const build, TmU32 const cust );
-//
-//could not find documentation
-#define TM_CHECK_VERSION( context, major, minor, build, cust ) TELEMETRY_REQUIRED_REPLACE( tmCheckVersion( context, major, minor, build, cust ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//TmErrorCode tmListenIPC( HTELEMETRY cx, char const *name );
-//
-//could not find documentation
-#define TM_LISTEN_IPC( context, name ) TELEMETRY_REQUIRED_REPLACE( tmListenIPC( context, name ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmUpdateSymbolData( HTELEMETRY cx );
-//
-//Description
-// Tells Telemetry to rescan loaded modules for symbol database information.
-//
-//Parameters
-// cx [in] a valid context
-#define TM_UPDATE_SYMBOL_DATA( context ) TELEMETRY_REQUIRED( tmUpdateSymbolData( context ) )
-
-
-//TmErrorCode tmGetSessionName( HTELEMETRY cx,char * dst,int const kDstSize );
-//
-//Description
-// Gets the name of the current session as determined by the server.
-//
-//Parameters
-// cx [in] a valid context
-// dst [in] pointer to buffer in which to copy the name
-// kDstSize [in] size of dst
-#define TM_GET_SESSION_NAME( context, dst, kDstSize ) TELEMETRY_REQUIRED_REPLACE( tmGetSessionName( context, dst, kDstSize ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmUnwindToDebugZoneLevel( HTELEMETRY cx,int const kLevel );
-//
-//Description
-// Unwinds the current thread's zone stack back to the given level.
-//
-//Parameters
-// cx [in] a valid context
-// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel
-#define TM_UNWIND_TO_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmUnwindToDebugZoneLevel( context, kLevel ) )
-
-
-//void tmSetDebugZoneLevel( HTELEMETRY cx,int const kLevel );
-//
-//Description
-// Set the Telemetry debug zone level.
-//
-//Parameters
-// cx [in] a valid context
-// kLevel [in] an arbitrary constant used to differentiate this zone level from another
-#define TM_SET_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmSetDebugZoneLevel( context, kLevel ) )
-
-
-//void tmCheckDebugZoneLevel( HTELEMETRY cx,int const kLevel );
-//
-//Description
-// Check the current Telemetry debug zone level.
-//
-//Parameters
-// cx [in] a valid context
-// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel
-#define TM_CHECK_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmCheckDebugZoneLevel( context, kLevel ) )
-
-
-//int tmGetCallStack( HTELEMETRY cx,TmCallStack * dst );
-//
-//Description
-// Retrieves the callstack for the current thread.
-//
-//Parameters
-// cx [in] a valid context
-// dst [in] TmCallStack structure in which to store the callstack information
-#define TM_GET_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmGetCallStack( context, TmCallStack_Ptr ), 0 )
-
-
-//int tmSendCallStack( HTELEMETRY cx,TmCallStack const * kpCallStack );
-//
-//Description
-// Sends the current callstack to the server so that later references with string format specifiers are up to date.
-//
-//Parameters
-// cx [in] a valid context
-// kpCallStack [in] pointer to a pre-existing callstack or 0 if it should use the current callstack
-#define TM_SEND_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmSendCallStack( context, TmCallStack_Ptr ), 0 )
-
-
-//TmErrorCode tmGetLastError( HTELEMETRY cx );
-//
-//Description
-// Returns and clears the current error condition for the given context.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-#define TM_GET_LAST_ERROR( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastError( context ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmShutdownContext( HTELEMETRY cx );
-//
-//Description
-// Shuts down the given context.
-//
-//Parameters
-// cx [in] handle to a valid context
-#define TM_SHUTDOWN_CONTEXT( context ) TELEMETRY_REQUIRED( tmShutdownContext( context ) )
-
-
-//TmU64 tmGetAccumulationStart( HTELEMETRY cx );
-//
-//Description
-// Gets the start time for a set of accumulation zones.
-//
-//Parameters
-// cx [in] handle to a telemetry context
-//
-//Return value
-// return [out] start time for use with tmEmitAccumulationZone.
-#define TM_GET_ACCUMULATION_START( context ) TELEMETRY_REQUIRED_REPLACE( tmGetAccumulationStart( context ), 0 )
-
-
-//TmU64 tmGetLastContextSwitchTime( HTELEMETRY cx );
-//
-//Description
-// Returns the time of the last received context switch event.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-//
-//Return value
-// return [out] the time of the last received context switch event, or 0 on failure (e.g. invalid context, context switches disabled, etc.)
-#define TM_GET_LAST_CONTEXT_SWITCH_TIME( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastContextSwitchTime( context ), 0 )
-
-
-//void tmEnterAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable );
-//
-//Description
-// Updates a zone variable passed to tmEmitAccumulationZone later.
-//
-//Parameters
-// cx [in] handle to a telemetry context
-// zone_variable [in] zone_variable to update
-#define TM_ENTER_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmEnterAccumulationZone( context, zone_variable ) )
-
-
-//void tmLeaveAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable );
-//
-//Description
-// Updates a zone variable passed to tmEmitAccumulationZone later.
-//
-//Parameters
-// cx [in] handle to a telemetry context
-// zone_variable [in] zone_variable to update
-#define TM_LEAVE_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmLeaveAccumulationZone( context, zone_variable ) )
-
-
-//void tmGetFormatCode( TmU32* pCode, char const * kpFmt );
-//
-//could not find documentation
-#define TM_GET_FORMAT_CODE( context, pCode, kpFmt ) TELEMETRY_REQUIRED( tmGetFormatCode( context, pCode, kpFmt ) )
-
-
-//char const * tmDynamicString( HTELEMETRY cx,char const * kpString );
-//
-//Description
-// Returns an opaque string identifier usable by Telemetry that is a copy of the kpString parameter.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpString [in] string to copy
-#define TM_DYNAMIC_STRING( context, kpString ) TELEMETRY_REQUIRED_REPLACE( tmDynamicString( context, kpString ), NULL )
-
-
-//void tmClearStaticString( HTELEMETRY cx,char const * kpString );
-//
-//Description
-// Marks the given string pointer as 'changed', forcing Telemetry to resend its contents.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpString [in] string to reset
-#define TM_CLEAR_STATIC_STRING( context, kpString ) TELEMETRY_REQUIRED( tmClearStaticString( context, kpString ) )
-
-
-//void tmEnable( HTELEMETRY cx,TmOption const kOption,int const kValue );
-//
-//Description
-// Enables or disables a specific Telemetry option.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kOption [in] the option to modify. One of the TmOption constants.
-// kValue [in] the new value for the option. Must be 0 (disable) or 1 (enable).
-#define TM_ENABLE( context, kOption, kValue ) TELEMETRY_REQUIRED( tmEnable( context, kOption, kValue ) )
-
-
-//int tmIsEnabled( HTELEMETRY cx,TmOption const kOption );
-//
-//Description
-// Inspects the state of a Telemetry option.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kOption [in] the option to inspect. Must be one of the TmOption constants.
-//
-//Return value
-// return [out] 1 if the option is enabled, 0 if not enabled. In case of error, 0 is enabled and last error is set.
-#define TM_IS_ENABLED( context, kOption ) TELEMETRY_REQUIRED_REPLACE( tmIsEnabled( context, kOption ), 0 )
-
-//void tmSetParameter( HTELEMETRY cx,TmParameter const kParameter,void const * kpValue );
-//
-//Description
-// Sets a Telemetry parameter.
-//
-//Parameters
-// cx [in] a valid context
-// kParameter [in] TmParameter constant
-// kpValue [in] pointer to value of the parameter. This varies depending on the value.
-#define TM_SET_PARAMETER( context, kParameter, kpValue ) TELEMETRY_REQUIRED( tmSetParameter( context, kParameter, kpValue ) )
-
-
-//TmErrorCode tmOpen( HTELEMETRY cx,char const * kpAppName,char const * kpBuildInfo,char const * kpServerAddress,TmConnectionType const kConnection,TmU16 const kServerPort,TmU32 const kFlags,int const kTimeoutMS );
-//
-//Description
-// Starts a Telemetry context and attempts to connect to a Telemetry server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpAppName [in] name of the application. NOTE: This MUST be alphanumeric only, e.g. "Game234", no spaces, special characters, etc. are allowed.
-// kpBuildInfo [in] information about the application. Used to annotate this Telemetry session. This information will show up when connecting to the server later to examine this particular run. Common uses include build numbers, compiled options, etc.
-// kpServerAddress [in] name or IP address of the Telemetry server to connect to
-// kConnection [in] type of connection to establish. Currently only TMCT_TCP is supported.
-// kServerPort [in] port to connect to. Specify 0 or TELEMETRY_DEFAULT_PORT for the default port.
-// kFlags [in] bitwise OR of TmOpenFlag flags
-// kTimeoutMS [in] duration, in milliseconds, to wait for a connection to the Telemetry server. Specify -1 to wait indefinitely.
-//
-//Return value
-// return [out] TM_OK on success, or on error one of the following: TMERR_INVALID_PARAM, TMERR_INVALID_CONTEXT, TMERR_UNKNOWN_NETWORK.
-#define TM_OPEN( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ) TELEMETRY_REQUIRED_REPLACE( tmOpen( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ), TELEMETRY_ERROR_BUILD_DISABLED )
-
-
-//void tmClose( HTELEMETRY cx );
-//
-//Description
-// Closes a context previously opened with tmOpen.
-//
-//Parameters
-// cx [in] handle to a valid and open Telemetry context
-#define TM_CLOSE( context ) TELEMETRY_REQUIRED( tmClose( context ) )
-
-
-//void tmTick( HTELEMETRY cx );
-//
-//Description
-// "Ticks" the Telemetry context, i.e. signifies the end of a frame of execution so that Telemetry can perform internal processing and send data to the Telemetry server.
-//
-//Parameters
-// cx [in] handle to a valid and open Telemetry context
-#define TM_TICK( context ) TELEMETRY_REQUIRED( tmTick( context ) )
-
-
-//void tmFlush( HTELEMETRY cx );
-//
-//cannot find documentation
-#define TM_FLUSH( context ) TELEMETRY_REQUIRED( tmFlush( context ) )
-
-
-//void tmPause( HTELEMETRY cx,int const kPause );
-//
-//Description
-// Pauses/unpauses Telemetry capture.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPause [in] 1 to pause, 0 to unpause
-#define TM_PAUSE( context, kPause ) TELEMETRY_REQUIRED( tmPause( context, kPause ) )
-
-
-//int tmIsPaused( HTELEMETRY cx );
-//
-//cannot find documentation. Presumably returns 1 if paused, 0 if not
-#define TM_IS_PAUSED( context ) TELEMETRY_REQUIRED_REPLACE( tmIsPaused( context ), 0 )
-
-
-//TmConnectionStatus tmGetConnectionStatus( HTELEMETRY cx );
-//
-//Description
-// Get the current connection status.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-//
-//Return value
-// return [out] a TmConnectionStatus constant. On error returns TMCS_DISCONNECTED and sets the context's last error.
-#define TM_GET_CONNECTION_STATUS( context ) TELEMETRY_REQUIRED_REPLACE( tmGetConnectionStatus( context ), TELEMETRY_ERROR_DISCONNECTED )
-
-
-//void tmFree( HTELEMETRY cx,void const * kpPtr );
-//
-//Description
-// Notify Telemetry that memory has been freed.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpPtr [in] address of the old memory block previously passed to a tmAlloc call
-#define TM_FREE( context, kpPtr ) TELEMETRY_REQUIRED( tmFree( context, kpPtr ) )
-
-
-//TmI32 tmGetStati( HTELEMETRY cx,TmStat const kStat );
-//
-//Description
-// Retrieves internal Telemetry statistics.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kStat [in] the TmStat to retrieve
-//
-//Return value
-// return [out] the value of the indicated internal statistic. On error returns 0 and sets last error.
-#define TM_GET_STAT_I( context, kStat ) TELEMETRY_REQUIRED_REPLACE( tmGetStati( context, kStat ), 0 )
-
-
-//void tmLeave( HTELEMETRY cx );
-//
-//Description
-// Notify Telemetry that a zone is being left.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-#define TM_LEAVE( context ) TELEMETRY_REQUIRED( tmLeave( context ) )
-
-
-//void tmLeaveEx( HTELEMETRY cx,TmU64 const kMatchId,TmU32 const kThreadId,char const * kpFilename,int const kLine );
-//
-//Description
-// Notify Telemetry that a zone is being left.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kMatchId [in] match id returned by tmEnterEx, used for Zones: Runtime Zone Filtering by Duration . Pass 0 if you're not filtering.
-// kThreadId [in] thread id for this zone. Pass 0 for 'current thread'.
-// kpFilename [in] name of the file
-// kLine [in] line number for the leave
-#define TM_LEAVE_EX( context, kMatchId, kThreadId, kpFilename, kLine ) TELEMETRY_REQUIRED( tmLeaveEx( context, kMatchId, kThreadId, kpFilename, kLine ) )
-
-
-//void tmTryLock( HTELEMETRY cx,void const * kPtr,char const * kpLockName,... );
-//
-//Description
-// Notify Telemetry that an attempt to grab a lock is beginning.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] pointer to the item being locked
-// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers.
-#define TM_TRY_LOCK( context, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLock( context, kPtr, kpLockName, ##__VA_ARGS__ ) )
-
-
-//void tmTryLockEx( HTELEMETRY cx,TmU64 * matcher,TmU64 const kThreshold,char const * kpFileName,int const kLine,void const * kPtr,char const * kpLockName,... );
-//
-//Description
-// Same as tmTryLock, but also specifying file and line information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// matcher [in] reference in which to store a match ID used for later filtering by duration
-// kpFileName [in] pointer to filename
-// kLine [in] line number
-// kPtr [in] pointer to the item being locked
-// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers.
-#define TM_TRY_LOCK_EX( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLockEx( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ##__VA_ARGS__ ) )
-
-
-//void tmEndTryLock( HTELEMETRY cx,void const * kPtr,TmLockResult const kResult );
-//
-//Description
-// Specify the result of a lock attempt previously started with tmTryLock.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] pointer for the object (mutex, etc.) being locked
-// kResult [in] the result of the lock attempt, one of TmLockResult.
-#define TM_END_TRY_LOCK( context, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLock( context, kPtr, kResult ) )
-
-
-//void tmEndTryLockEx( HTELEMETRY cx,TmU64 const kMatchId,char const * kpFileName,int const kLine,void const * kPtr,TmLockResult const kResult );
-//
-//Description
-// Specify the result of a lock attempt previously started with tmTryLock, but also with file and line information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kMatchId [in] match id returned from tmTryLockEx
-// kpFileName [in] pointer to filename
-// kLine [in] line number
-// kPtr [in] pointer for the object (mutex, etc.) being locked
-// kResult [in] the result of the lock attempt, one of TmLockResult.
-#define TM_END_TRY_LOCK_EX( context, kMatchId, kpFileName, kLine, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLockEx( context, kMatchId, kpFileName, kLine, kPtr, kResult ) )
-
-
-//void tmBeginTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... );
-//
-//Description
-// Start the beginning of a timespan.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kId [in] a user defined identifier for the timespan. Should be > 0.
-// kFlags [in] flags for the timespan. Reserved, must be 0.
-// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
-#define TM_BEGIN_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmEndTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... );
-//
-//Description
-// Mark the end a timespan.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan.
-// kFlags [in] flags for the timespan. Reserved, must be 0.
-// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
-#define TM_END_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmBeginTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... );
-//
-//Description
-// Start the beginning of a timespan but at an explicit time.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kId [in] a user defined identifier for the timespan. Should be > 0.
-// kFlags [in] flags for the timespan. Reserved, must be 0.
-// kTimeStamp [in] explicit timestamp (e.g. from tmFastTime)
-// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
-#define TM_BEGIN_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmEndTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... );
-//
-//Description
-// Mark the end a timespan, but with an explicit timestamp.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan.
-// kFlags [in] flags for the timespan. Reserved, must be 0.
-// kTimeStamp [in] a user specified timestamp (e.g. from tmFastTime.
-// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
-#define TM_END_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmSignalLockCount( HTELEMETRY cx,void const * kPtr,TmU32 const kCount,char const * kpDescription,... );
-//
-//Description
-// Signal that a semaphore's lock count has been incremented.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] pointer to the being whose count is being incremented (e.g. HANDLE)
-// kCount [in] count value
-// kpDescription [in] description of the event. This may contain printf-style format specifiers.
-#define TM_SIGNAL_LOCK_COUNT( context, kPtr, kCount, kpDescription, ... ) TELEMETRY_REQUIRED( tmSignalLockCount( context, kPtr, kCount, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmSetLockState( HTELEMETRY cx,void const * kPtr,TmLockState const kState,char const * kpDescription,... );
-//
-//Description
-// Sets the state of a lock (mutex, critical section, semaphore, etc.)
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] identifier for the lock, typically its address or HANDLE
-// kState [in] new state of the lock
-// kpDescription [in] description of the event. This may contain printf-style format specifiers.
-#define TM_SET_LOCK_STATE( context, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockState( context, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmSetLockStateEx( HTELEMETRY cx,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState );
-//
-//Description
-// Set the state of a lock but with explicit file and line information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpFilename [in] filename where the state change occurs
-// kLine [in] line number of the state change
-// kPtr [in] identifier for the lock, typically its address or HANDLE
-// kState [in] new state of the lock
-// kpDescription [in] description of the event. This may contain printf-style format specifiers.
-#define TM_SET_LOCK_STATE_EX( context, kpFileName, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateEx( context, kpFileName, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmSetLockStateMinTime( HTELEMETRY cx,void * buf,void const * kPtr,TmLockState const kState,char const * fmt,... );
-//
-//Description
-// Set the state of a lock but with a minimum time threshold.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size.
-// kPtr [in] identifier for the lock, typically its address or HANDLE
-// kState [in] new state of the lock
-// kpDescription [in] description of the event. This may contain printf-style format specifiers.
-#define TM_SET_LOCK_STATE_MIN_TIME( context, buf, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTime( context, buf, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmSetLockStateMinTimeEx( HTELEMETRY cx,void * buf,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState );
-//
-//Description
-// This is the 'Ex' version of tmSetLockStateMinTimeEx. Please refer to tmSetLockStateEx and tmSetLockStateMinTime for more information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size.
-// kpFilename [in] filename where the state change occurs
-// kLine [in] line number of the state change
-// kPtr [in] identifier for the lock, typically its address or HANDLE
-// kState [in] new state of the lock
-// kpDescription [in] description of the event. This may contain printf-style format specifiers.
-#define TM_SET_LOCK_STATE_MIN_TIME_EX( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTimeEx( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmThreadName( HTELEMETRY cx,TmU32 const kThreadID,char const * kpNameFormat,... );
-//
-//Description
-// Sets the name of the specified thread.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kThreadID [in] thread identifier of the thread to name. Use 0 to specify the current thread.
-// kpNameFormat [in] name of the thread. This may contain printf-style format specifiers.
-#define TM_THREAD_NAME( context, kThreadID, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmThreadName( context, kThreadID, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmLockName( HTELEMETRY cx,void const* kPtr,char const * kpNameFormat,... );
-//
-//Description
-// Sets the name of the specified locking object.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] identifier for the lock. Usually you can supply a pointer/HANDLE.
-// kpNameFormat [in] name of the lock. This may contain printf-style format specifiers.
-#define TM_LOCK_NAME( context, kPtr, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmLockName( context, kPtr, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmEmitAccumulationZone( HTELEMETRY cx,TmU32 const kZoneFlags,TmU64 * pStart,int const kCount,TmU64 const kTotal,char const * kpZoneFormat,... );
-//
-//Description
-// Emits an accumulation zone.
-//
-//Parameters
-// cx [in] handle to a valid telemetry context
-// kZoneFlags [in] reserved, must be 0
-// pStart [out] pointer to start time variable retrieved with a prior call to tmGetAccumulationStart. This value is modified.
-// kCount [in] number of times the accumulation zone was called
-// kTotal [in] total amount of time spent in the accumulation zone
-// kpZoneFormat [in] name of the accumulation zone. This may contain printf-style format specifiers.
-#define TM_EMIT_ACCUMULATION_ZONE( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ... ) TELEMETRY_REQUIRED( tmEmitAccumulationZone( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ##__VA_ARGS__ ) )
-
-
-//void tmSetVariable( HTELEMETRY cx,char const * kpKey,char const * kpValueFormat,... );
-//
-//Description
-// Binds a string to a key name and sends to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpKey [in] pointer to string identify the key being set
-// kpValueFormat [in] pointer to string to bind to the associated key. This may contain printf-style format specifiers.
-#define TM_SET_VARIABLE( context, kpKey, kpValueFormat, ... ) TELEMETRY_REQUIRED( tmSetVariable( context, kpKey, kpValueFormat, ##__VA_ARGS__ ) )
-
-
-//void tmSetTimelineSectionName( HTELEMETRY cx,char const * kpNameFormat,... );
-//
-//Description
-// Changes the name of the global state.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpNameFormat [in] name of the current state. This may contain printf-style format specifiers.
-#define TM_SET_TIMELINE_SECTION_NAME( context, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmSetTimelineSectionName( context, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmEnter( HTELEMETRY cx,TmU32 const kFlags,char const * kpZoneName,... );
-//
-//Description
-// Notify Telemetry that a zone is being entered.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kFlags [in] Bitwise OR of TmZoneFlag
-// kpZoneName [in] name of the zone. This may contain printf-style format specifiers.
-#define TM_ENTER( context, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnter( context, kFlags, kpZoneName, ##__VA_ARGS__ ) )
-
-
-//void tmEnterEx( HTELEMETRY cx,TmU64 * pMatchId,TmU32 const kThreadId,TmU64 const kThreshold,char const * kpFilename,int const kLine,TmU32 const kFlags,char const * kpZoneName,... );
-//
-//Description
-// Notify Telemetry that a zone is being entered, but with explicit file and line information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// pMatchId [in] pointer variable to assign a match ID, pass NULL if you are not Zones: Runtime Zone Filtering by Duration.
-// kThreadId [in] thread ID for this zone, pass 0 for current thread
-// kThreshold [in] microseconds that the zone must span before being sent to server.
-// kpFilename [in] filename
-// kLine [in] line number
-// kFlags [in] Bitwise OR of TmZoneFlag
-// kpZoneName [in] name of the zone. This may contain printf-style format specifiers.
-#define TM_ENTER_EX( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnterEx( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ##__VA_ARGS__ ) )
-
-
-//void tmAlloc( HTELEMETRY cx,void const * kPtr,TmU64 const kSize,char const * kpDescription,... );
-//
-//Description
-// Notify Telemetry that memory has been allocated.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kPtr [in] address of the memory that has been allocated
-// kSize [in] size of memory that has been allocated
-// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers.
-#define TM_ALLOC( context, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAlloc( context, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmAllocEx( HTELEMETRY cx,char const * kpFilename,int const kLineNumber,void const * kPtr,TmU64 const kSize,char const * kpDescription,... );
-//
-//Description
-// Notify Telemetry that memory has been allocated, but with explicit file and line information.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpFilename [in] name of the file
-// kLineNumber [in] line number of the allocation
-// kPtr [in] address of the memory that has been allocated
-// kSize [in] size of memory that has been allocated
-// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers.
-#define TM_ALLOC_EX( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAllocEx( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) )
-
-
-//void tmMessage( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormatString,... );
-//
-//Description
-// Send a message to the server for later viewing in the Visualizer.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kFlags [in] Bitwise OR of TmMessageFlag
-// kpFormatString [in] message string (not to exceed TM_MAX_STRING in length). This may contain printf-style format specifiers. Note that the message may have a Telemetry object path in it so that it can be hierarchically displayed with other messages.
-#define TM_MESSAGE( context, kFlags, kpFormatString, ... ) TELEMETRY_REQUIRED( tmMessage( context, kFlags, kpFormatString, ##__VA_ARGS__ ) )
-#define TM_LOG( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_LOG, kpFormatString, ##__VA_ARGS__ )
-#define TM_WARNING( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_WARNING, kpFormatString, ##__VA_ARGS__ )
-#define TM_ERROR( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_ERROR, kpFormatString, ##__VA_ARGS__ )
-
-
-
-//void tmPlot( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends a floating point plot value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlot( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//Identical to tmPlot()
-//void tmPlotF32( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends a floating point plot value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_F32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmPlotF64( HTELEMETRY cx,TmPlotType const kType,double const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends a double precision floating point plot value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_F64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmPlotI32( HTELEMETRY cx,TmPlotType const kType,TmI32 const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends an signed 32-bit value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_I32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmPlotU32( HTELEMETRY cx,TmPlotType const kType,TmU32 const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends an unsigned 32-bit value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_U32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmPlotI64( HTELEMETRY cx,TmPlotType const kType,TmI64 const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends an signed 64-bit value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_I64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmPlotU64( HTELEMETRY cx,TmPlotType const kType,TmU64 const kValue,char const * kpNameFormat,... );
-//
-//Description
-// Sends an unsigned 64-bit value to the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
-// kValue [in] the value of the plot at this moment in time
-// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
-#define TM_PLOT_U64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
-
-
-//void tmBlob( HTELEMETRY cx,void const * kpData,int const kDataSize,char const * kpPluginIdentifier,char const * kpBlobName,... );
-//
-//Description
-// Sends an arbitrary application specified blob of binary data for storage on the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kpData [in] the actual blob data
-// kDataSize [in] size of kpData in bytes
-// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier).
-// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers.
-#define TM_BLOB( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ...) TELEMETRY_REQUIRED( tmBlob( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) )
-
-
-//void tmDisjointBlob( HTELEMETRY cx,int const kNumPieces,void const ** kpData,int const * kDataSizes,char const* kpPluginIdentifier,char const * kpBlobName,... );
-//
-//Description
-// Sends an arbitrary application specified blob of binary data for storage on the server.
-//
-//Parameters
-// cx [in] handle to a valid Telemetry context
-// kNumPieces [in] number of elements in kpData and kDataSizes
-// kpData [in] array of actual data blobs
-// kDataSizes [in] array of data blob sizes in bytes
-// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier).
-// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers.
-#define TM_DISJOINT_BLOB( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ... ) TELEMETRY_REQUIRED( tmDisjointBlob( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) )
-
-
-
-
-
-
-
-
-
-
-
-
-#if !defined( RAD_TELEMETRY_ENABLED )
-
-//
-// Telemetry is disabled.
-//
-
-class CTelemetryLock
-{
-public:
- CTelemetryLock(void *plocation, const char *description) {}
- ~CTelemetryLock() {}
- void Locked() {}
- void Unlocked() {}
-};
-
-class CTelemetrySpikeDetector
-{
-public:
- CTelemetrySpikeDetector( const char *msg, uint32 threshold = 50 ) {}
- ~CTelemetrySpikeDetector() { }
-};
-
-#define TelemetrySetLockName( _ctx, _location, _description )
-
-#else
-
-//
-// Telemetry is enabled.
-//
-
-#define TelemetrySetLockName( _ctx, _location, _description ) \
- do \
- { \
- static bool s_bNameSet = false; \
- if( _ctx && !s_bNameSet ) \
- { \
- tmLockName( _ctx, _location, _description ); \
- s_bNameSet = true; \
- } \
- } while( 0 )
-
-class CTelemetryLock
-{
-public:
- CTelemetryLock(void *plocation, const char *description)
- {
- m_plocation = (const char *)plocation;
- m_description = description;
- TelemetrySetLockName( TELEMETRY_LEVEL1, m_plocation, m_description );
- TM_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, "%s", m_description );
- }
- ~CTelemetryLock()
- {
- Unlocked();
- }
- void Locked()
- {
- TM_END_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS );
- TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description );
- }
- void Unlocked()
- {
- if( m_plocation )
- {
- TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description );
- m_plocation = NULL;
- }
- }
-
-public:
- const char *m_plocation;
- const char *m_description;
-};
-
-class CTelemetrySpikeDetector
-{
-public:
- // Spews Telemetry message when threshold hit (in milliseconds.)
- CTelemetrySpikeDetector( const char *msg, float threshold = 5 ) :
- m_message( msg ), m_threshold( threshold ), time0( tmFastTime() ) {}
- ~CTelemetrySpikeDetector()
- {
- float time = ( tmFastTime() - time0 ) * g_Telemetry.flRDTSCToMilliSeconds;
- if( time >= m_threshold )
- {
- TM_MESSAGE( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(dota/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) );
- }
- }
-
-private:
- TmU64 time0;
- float m_threshold;
- const char *m_message;
-};
-
-#endif // RAD_TELEMETRY_ENABLED
-
-#endif // VPROF_TELEMETRY_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Real-Time Hierarchical Telemetry Profiling
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef VPROF_TELEMETRY_H
+#define VPROF_TELEMETRY_H
+
+#if !defined( MAKE_VPC )
+
+#if !defined( RAD_TELEMETRY_DISABLED ) && ( defined( IS_WINDOWS_PC ) || defined( _LINUX ) )
+// Rad Telemetry profiling is enabled on Win32 and Win64.
+#define RAD_TELEMETRY_ENABLED
+#endif
+
+#endif // !defined( MAKE_VPC )
+
+
+#if !defined( RAD_TELEMETRY_ENABLED )
+
+//
+// If Telemetry isn't enabled, then kill all the tmZone() macros, etc.
+//
+#define NTELEMETRY 1
+// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here.
+#undef RADCOPYRIGHT
+
+#include "tmapi_dummy.h"
+
+inline void TelemetryTick() {}
+inline void TelemetrySetLevel( unsigned int Level ) {}
+
+#define TELEMETRY_REQUIRED( tmRequiredCode ) //a basic wrapper to only enable code if telemetry is present
+#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) replacementCode //in case you need to replace the code with something specific if telemetry isn't present
+
+//#define TMZF_NONE
+
+#else
+
+//
+// Telemetry is enabled. Include the telemetry header.
+//
+#include "../../thirdparty/telemetry/include/telemetry.h"
+// Different versions of radbase.h define RADCOPYRIGHT to different values. So undef that here.
+#undef RADCOPYRIGHT
+
+PLATFORM_INTERFACE void TelemetryTick();
+PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level );
+
+struct TelemetryData
+{
+ HTELEMETRY tmContext[32];
+ float flRDTSCToMilliSeconds; // Conversion from tmFastTime() (rdtsc) to milliseconds.
+ uint32 FrameCount; // Count of frames to capture before turning off.
+ char ServerAddress[128]; // Server name to connect to.
+ uint32 ZoneFilterVal; // tmZoneFiltered default filtered value (in MicroSeconds)
+ int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo).
+ float dotatime; // CDOTAGamerules::GetDOTATime()
+ uint32 DemoTickStart; // Start telemetry on demo tick #
+ uint32 DemoTickEnd; // End telemetry on demo tick #
+ uint32 Level; // Current Telemetry level (Use TelemetrySetLevel to modify)
+};
+PLATFORM_INTERFACE TelemetryData g_Telemetry;
+
+#define TELEMETRY_REQUIRED( tmRequiredCode ) tmRequiredCode //a basic wrapper to only enable code if telemetry is present
+#define TELEMETRY_REQUIRED_REPLACE( tmRequiredCode, replacementCode ) tmRequiredCode //in case you need to replace the code with something specific if telemetry isn't present
+
+#endif // RAD_TELEMETRY_ENABLED
+
+
+
+
+
+
+
+
+
+
+#define TELEMETRY_ERROR_BUILD_DISABLED TELEMETRY_REQUIRED_REPLACE( TMERR_DISABLED, 0x0001 )
+#define TELEMETRY_ERROR_DISCONNECTED TELEMETRY_REQUIRED_REPLACE( TMCS_DISCONNECTED, 0 )
+
+
+#define TELEMETRY_LEVEL0 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[0], 0 ) // high level tmZone()
+#define TELEMETRY_LEVEL1 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[1], 0 ) // lower level tmZone(), tmZoneFiltered()
+#define TELEMETRY_LEVEL2 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[2], 0 ) // VPROF_0
+#define TELEMETRY_LEVEL3 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[3], 0 ) // VPROF_1
+#define TELEMETRY_LEVEL4 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[4], 0 ) // VPROF_2
+#define TELEMETRY_LEVEL5 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[5], 0 ) // VPROF_3
+#define TELEMETRY_LEVEL6 TELEMETRY_REQUIRED_REPLACE( g_Telemetry.tmContext[6], 0 ) // VPROF_4
+
+//__rdtsc()
+#define TM_FAST_TIME() TELEMETRY_REQUIRED_REPLACE( tmFastTime(), 0 )
+
+
+//int RADEXPLINK tmLoadTelemetry( int const kUseCheckedDLL );
+//
+//Description
+// On dynamic library platforms, this function loads the Telemetry DLL (or shared library) and then hooks up all of the dynamic function pointers.
+//Parameters
+// kUseCheckedDLL [in] set to 0 if you want to use the release mode DLL or 1 if you want to use the checked DLL. The checked DLL is compiled with optimizations but does extra run time checks and reporting.
+#define TM_LOAD_TELEMETRY(kUseCheckedDll) TELEMETRY_REQUIRED_REPLACE( tmLoadTelemetry(kUseCheckedDll), 0 )
+
+
+//TmErrorCode tmStartup( );
+//
+//Description
+// Starts up all of Telemetry.
+#define TM_STARTUP() TELEMETRY_REQUIRED_REPLACE( tmStartup(), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmShutdown( );
+//
+//Description
+// Shuts down all of Telemetry.
+#define TM_SHUTDOWN() TELEMETRY_REQUIRED( tmShutdown() )
+
+
+//TmErrorCode tmInitializeContext( HTELEMETRY * pcx,void * pArena,TmU32 const kArenaSize );
+//
+//Description
+// Initializes a context.
+//
+//Parameters
+// pcx [out] pointer to a TmHandle in which to store a handle to the initialized context
+// pArena [in] pointer to a memory buffer for use by Telemetry to create the context. Applications should never free or modify this memory unless tmShutdownContext has been called!
+// kArenaSize [in] size of the memory buffer pointed to by pArena. You want this large enough so that Telemetry never stalls trying to send over the network, but not so large that it takes up too much memory from your app. A good initial value is 1MB.
+#define TM_INITIALIZE_CONTEXT( pContext, pArena, kArenaSize ) TELEMETRY_REQUIRED_REPLACE( tmInitializeContext( pContext, pArena, kArenaSize ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmZoneFiltered( HTELEMETRY cx,TmU64 const kThreshold,TmU32 const kFlags,char const * kpFormat,... );
+//
+//Description
+// Identical to tmZone however also allows specification of threshold duration.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kThreshold [in] microseconds that the zone must span before being sent to server.
+// kFlags [in] flags for the zone (same as those passed to tmEnter.
+// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers.
+#define TM_ZONE_FILTERED( context, kThreshold, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZoneFiltered( context, kThreshold, kFlags, kpFormat, ##__VA_ARGS__ ) )
+
+
+//void tmZone( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormat,... );
+//
+//Description
+// Helper macro in C++ that creates an anonymous local object that automatically calls tmEnter and then tmLeave when exiting scope.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kFlags [in] flags for the zone (same as those passed to tmEnter
+// kpFormat [in] name of the zone (same as those passed to tmEnter. This may contain printf-style format specifiers.
+#define TM_ZONE( context, kFlags, kpFormat, ... ) TELEMETRY_REQUIRED( tmZone( context, kFlags, kpFormat, ##__VA_ARGS__ ) )
+
+//Standardized zones
+#define TM_ZONE_DEFAULT( context ) TM_ZONE( context, TMZF_NONE, __FUNCTION__ )
+#define TM_ZONE_IDLE( context ) TM_ZONE( context, TMZF_IDLE, __FUNCTION__ )
+#define TM_ZONE_STALL( context ) TM_ZONE( context, TMZF_STALL, __FUNCTION__ )
+
+
+//TmErrorCode tmCheckVersion( HTELEMETRY cx, TmU32 const major, TmU32 const minor, TmU32 const build, TmU32 const cust );
+//
+//could not find documentation
+#define TM_CHECK_VERSION( context, major, minor, build, cust ) TELEMETRY_REQUIRED_REPLACE( tmCheckVersion( context, major, minor, build, cust ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//TmErrorCode tmListenIPC( HTELEMETRY cx, char const *name );
+//
+//could not find documentation
+#define TM_LISTEN_IPC( context, name ) TELEMETRY_REQUIRED_REPLACE( tmListenIPC( context, name ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmUpdateSymbolData( HTELEMETRY cx );
+//
+//Description
+// Tells Telemetry to rescan loaded modules for symbol database information.
+//
+//Parameters
+// cx [in] a valid context
+#define TM_UPDATE_SYMBOL_DATA( context ) TELEMETRY_REQUIRED( tmUpdateSymbolData( context ) )
+
+
+//TmErrorCode tmGetSessionName( HTELEMETRY cx,char * dst,int const kDstSize );
+//
+//Description
+// Gets the name of the current session as determined by the server.
+//
+//Parameters
+// cx [in] a valid context
+// dst [in] pointer to buffer in which to copy the name
+// kDstSize [in] size of dst
+#define TM_GET_SESSION_NAME( context, dst, kDstSize ) TELEMETRY_REQUIRED_REPLACE( tmGetSessionName( context, dst, kDstSize ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmUnwindToDebugZoneLevel( HTELEMETRY cx,int const kLevel );
+//
+//Description
+// Unwinds the current thread's zone stack back to the given level.
+//
+//Parameters
+// cx [in] a valid context
+// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel
+#define TM_UNWIND_TO_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmUnwindToDebugZoneLevel( context, kLevel ) )
+
+
+//void tmSetDebugZoneLevel( HTELEMETRY cx,int const kLevel );
+//
+//Description
+// Set the Telemetry debug zone level.
+//
+//Parameters
+// cx [in] a valid context
+// kLevel [in] an arbitrary constant used to differentiate this zone level from another
+#define TM_SET_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmSetDebugZoneLevel( context, kLevel ) )
+
+
+//void tmCheckDebugZoneLevel( HTELEMETRY cx,int const kLevel );
+//
+//Description
+// Check the current Telemetry debug zone level.
+//
+//Parameters
+// cx [in] a valid context
+// kLevel [in] an arbitrary constant that was previously set using tmSetDebugZoneLevel
+#define TM_CHECK_DEBUG_ZONE_LEVEL( context, kLevel ) TELEMETRY_REQUIRED( tmCheckDebugZoneLevel( context, kLevel ) )
+
+
+//int tmGetCallStack( HTELEMETRY cx,TmCallStack * dst );
+//
+//Description
+// Retrieves the callstack for the current thread.
+//
+//Parameters
+// cx [in] a valid context
+// dst [in] TmCallStack structure in which to store the callstack information
+#define TM_GET_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmGetCallStack( context, TmCallStack_Ptr ), 0 )
+
+
+//int tmSendCallStack( HTELEMETRY cx,TmCallStack const * kpCallStack );
+//
+//Description
+// Sends the current callstack to the server so that later references with string format specifiers are up to date.
+//
+//Parameters
+// cx [in] a valid context
+// kpCallStack [in] pointer to a pre-existing callstack or 0 if it should use the current callstack
+#define TM_SEND_CALL_STACK( context, TmCallStack_Ptr ) TELEMETRY_REQUIRED_REPLACE( tmSendCallStack( context, TmCallStack_Ptr ), 0 )
+
+
+//TmErrorCode tmGetLastError( HTELEMETRY cx );
+//
+//Description
+// Returns and clears the current error condition for the given context.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+#define TM_GET_LAST_ERROR( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastError( context ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmShutdownContext( HTELEMETRY cx );
+//
+//Description
+// Shuts down the given context.
+//
+//Parameters
+// cx [in] handle to a valid context
+#define TM_SHUTDOWN_CONTEXT( context ) TELEMETRY_REQUIRED( tmShutdownContext( context ) )
+
+
+//TmU64 tmGetAccumulationStart( HTELEMETRY cx );
+//
+//Description
+// Gets the start time for a set of accumulation zones.
+//
+//Parameters
+// cx [in] handle to a telemetry context
+//
+//Return value
+// return [out] start time for use with tmEmitAccumulationZone.
+#define TM_GET_ACCUMULATION_START( context ) TELEMETRY_REQUIRED_REPLACE( tmGetAccumulationStart( context ), 0 )
+
+
+//TmU64 tmGetLastContextSwitchTime( HTELEMETRY cx );
+//
+//Description
+// Returns the time of the last received context switch event.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+//
+//Return value
+// return [out] the time of the last received context switch event, or 0 on failure (e.g. invalid context, context switches disabled, etc.)
+#define TM_GET_LAST_CONTEXT_SWITCH_TIME( context ) TELEMETRY_REQUIRED_REPLACE( tmGetLastContextSwitchTime( context ), 0 )
+
+
+//void tmEnterAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable );
+//
+//Description
+// Updates a zone variable passed to tmEmitAccumulationZone later.
+//
+//Parameters
+// cx [in] handle to a telemetry context
+// zone_variable [in] zone_variable to update
+#define TM_ENTER_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmEnterAccumulationZone( context, zone_variable ) )
+
+
+//void tmLeaveAccumulationZone( HTELEMETRY cx,TmI64 * zone_variable );
+//
+//Description
+// Updates a zone variable passed to tmEmitAccumulationZone later.
+//
+//Parameters
+// cx [in] handle to a telemetry context
+// zone_variable [in] zone_variable to update
+#define TM_LEAVE_ACCUMULATION_ZONE( context, zone_variable ) TELEMETRY_REQUIRED( tmLeaveAccumulationZone( context, zone_variable ) )
+
+
+//void tmGetFormatCode( TmU32* pCode, char const * kpFmt );
+//
+//could not find documentation
+#define TM_GET_FORMAT_CODE( context, pCode, kpFmt ) TELEMETRY_REQUIRED( tmGetFormatCode( context, pCode, kpFmt ) )
+
+
+//char const * tmDynamicString( HTELEMETRY cx,char const * kpString );
+//
+//Description
+// Returns an opaque string identifier usable by Telemetry that is a copy of the kpString parameter.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpString [in] string to copy
+#define TM_DYNAMIC_STRING( context, kpString ) TELEMETRY_REQUIRED_REPLACE( tmDynamicString( context, kpString ), NULL )
+
+
+//void tmClearStaticString( HTELEMETRY cx,char const * kpString );
+//
+//Description
+// Marks the given string pointer as 'changed', forcing Telemetry to resend its contents.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpString [in] string to reset
+#define TM_CLEAR_STATIC_STRING( context, kpString ) TELEMETRY_REQUIRED( tmClearStaticString( context, kpString ) )
+
+
+//void tmEnable( HTELEMETRY cx,TmOption const kOption,int const kValue );
+//
+//Description
+// Enables or disables a specific Telemetry option.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kOption [in] the option to modify. One of the TmOption constants.
+// kValue [in] the new value for the option. Must be 0 (disable) or 1 (enable).
+#define TM_ENABLE( context, kOption, kValue ) TELEMETRY_REQUIRED( tmEnable( context, kOption, kValue ) )
+
+
+//int tmIsEnabled( HTELEMETRY cx,TmOption const kOption );
+//
+//Description
+// Inspects the state of a Telemetry option.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kOption [in] the option to inspect. Must be one of the TmOption constants.
+//
+//Return value
+// return [out] 1 if the option is enabled, 0 if not enabled. In case of error, 0 is enabled and last error is set.
+#define TM_IS_ENABLED( context, kOption ) TELEMETRY_REQUIRED_REPLACE( tmIsEnabled( context, kOption ), 0 )
+
+//void tmSetParameter( HTELEMETRY cx,TmParameter const kParameter,void const * kpValue );
+//
+//Description
+// Sets a Telemetry parameter.
+//
+//Parameters
+// cx [in] a valid context
+// kParameter [in] TmParameter constant
+// kpValue [in] pointer to value of the parameter. This varies depending on the value.
+#define TM_SET_PARAMETER( context, kParameter, kpValue ) TELEMETRY_REQUIRED( tmSetParameter( context, kParameter, kpValue ) )
+
+
+//TmErrorCode tmOpen( HTELEMETRY cx,char const * kpAppName,char const * kpBuildInfo,char const * kpServerAddress,TmConnectionType const kConnection,TmU16 const kServerPort,TmU32 const kFlags,int const kTimeoutMS );
+//
+//Description
+// Starts a Telemetry context and attempts to connect to a Telemetry server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpAppName [in] name of the application. NOTE: This MUST be alphanumeric only, e.g. "Game234", no spaces, special characters, etc. are allowed.
+// kpBuildInfo [in] information about the application. Used to annotate this Telemetry session. This information will show up when connecting to the server later to examine this particular run. Common uses include build numbers, compiled options, etc.
+// kpServerAddress [in] name or IP address of the Telemetry server to connect to
+// kConnection [in] type of connection to establish. Currently only TMCT_TCP is supported.
+// kServerPort [in] port to connect to. Specify 0 or TELEMETRY_DEFAULT_PORT for the default port.
+// kFlags [in] bitwise OR of TmOpenFlag flags
+// kTimeoutMS [in] duration, in milliseconds, to wait for a connection to the Telemetry server. Specify -1 to wait indefinitely.
+//
+//Return value
+// return [out] TM_OK on success, or on error one of the following: TMERR_INVALID_PARAM, TMERR_INVALID_CONTEXT, TMERR_UNKNOWN_NETWORK.
+#define TM_OPEN( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ) TELEMETRY_REQUIRED_REPLACE( tmOpen( context, kpAppName, kpBuildInfo, kpServerAddress, kConnection, kServerPort, kFlags, kTimeoutMS ), TELEMETRY_ERROR_BUILD_DISABLED )
+
+
+//void tmClose( HTELEMETRY cx );
+//
+//Description
+// Closes a context previously opened with tmOpen.
+//
+//Parameters
+// cx [in] handle to a valid and open Telemetry context
+#define TM_CLOSE( context ) TELEMETRY_REQUIRED( tmClose( context ) )
+
+
+//void tmTick( HTELEMETRY cx );
+//
+//Description
+// "Ticks" the Telemetry context, i.e. signifies the end of a frame of execution so that Telemetry can perform internal processing and send data to the Telemetry server.
+//
+//Parameters
+// cx [in] handle to a valid and open Telemetry context
+#define TM_TICK( context ) TELEMETRY_REQUIRED( tmTick( context ) )
+
+
+//void tmFlush( HTELEMETRY cx );
+//
+//cannot find documentation
+#define TM_FLUSH( context ) TELEMETRY_REQUIRED( tmFlush( context ) )
+
+
+//void tmPause( HTELEMETRY cx,int const kPause );
+//
+//Description
+// Pauses/unpauses Telemetry capture.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPause [in] 1 to pause, 0 to unpause
+#define TM_PAUSE( context, kPause ) TELEMETRY_REQUIRED( tmPause( context, kPause ) )
+
+
+//int tmIsPaused( HTELEMETRY cx );
+//
+//cannot find documentation. Presumably returns 1 if paused, 0 if not
+#define TM_IS_PAUSED( context ) TELEMETRY_REQUIRED_REPLACE( tmIsPaused( context ), 0 )
+
+
+//TmConnectionStatus tmGetConnectionStatus( HTELEMETRY cx );
+//
+//Description
+// Get the current connection status.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+//
+//Return value
+// return [out] a TmConnectionStatus constant. On error returns TMCS_DISCONNECTED and sets the context's last error.
+#define TM_GET_CONNECTION_STATUS( context ) TELEMETRY_REQUIRED_REPLACE( tmGetConnectionStatus( context ), TELEMETRY_ERROR_DISCONNECTED )
+
+
+//void tmFree( HTELEMETRY cx,void const * kpPtr );
+//
+//Description
+// Notify Telemetry that memory has been freed.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpPtr [in] address of the old memory block previously passed to a tmAlloc call
+#define TM_FREE( context, kpPtr ) TELEMETRY_REQUIRED( tmFree( context, kpPtr ) )
+
+
+//TmI32 tmGetStati( HTELEMETRY cx,TmStat const kStat );
+//
+//Description
+// Retrieves internal Telemetry statistics.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kStat [in] the TmStat to retrieve
+//
+//Return value
+// return [out] the value of the indicated internal statistic. On error returns 0 and sets last error.
+#define TM_GET_STAT_I( context, kStat ) TELEMETRY_REQUIRED_REPLACE( tmGetStati( context, kStat ), 0 )
+
+
+//void tmLeave( HTELEMETRY cx );
+//
+//Description
+// Notify Telemetry that a zone is being left.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+#define TM_LEAVE( context ) TELEMETRY_REQUIRED( tmLeave( context ) )
+
+
+//void tmLeaveEx( HTELEMETRY cx,TmU64 const kMatchId,TmU32 const kThreadId,char const * kpFilename,int const kLine );
+//
+//Description
+// Notify Telemetry that a zone is being left.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kMatchId [in] match id returned by tmEnterEx, used for Zones: Runtime Zone Filtering by Duration . Pass 0 if you're not filtering.
+// kThreadId [in] thread id for this zone. Pass 0 for 'current thread'.
+// kpFilename [in] name of the file
+// kLine [in] line number for the leave
+#define TM_LEAVE_EX( context, kMatchId, kThreadId, kpFilename, kLine ) TELEMETRY_REQUIRED( tmLeaveEx( context, kMatchId, kThreadId, kpFilename, kLine ) )
+
+
+//void tmTryLock( HTELEMETRY cx,void const * kPtr,char const * kpLockName,... );
+//
+//Description
+// Notify Telemetry that an attempt to grab a lock is beginning.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] pointer to the item being locked
+// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers.
+#define TM_TRY_LOCK( context, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLock( context, kPtr, kpLockName, ##__VA_ARGS__ ) )
+
+
+//void tmTryLockEx( HTELEMETRY cx,TmU64 * matcher,TmU64 const kThreshold,char const * kpFileName,int const kLine,void const * kPtr,char const * kpLockName,... );
+//
+//Description
+// Same as tmTryLock, but also specifying file and line information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// matcher [in] reference in which to store a match ID used for later filtering by duration
+// kpFileName [in] pointer to filename
+// kLine [in] line number
+// kPtr [in] pointer to the item being locked
+// kpLockName [in] description of this lock attempt. This may contain printf-style format specifiers.
+#define TM_TRY_LOCK_EX( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ... ) TELEMETRY_REQUIRED( tmTryLockEx( context, matcher, kThreshold, kpFileName, kLine, kPtr, kpLockName, ##__VA_ARGS__ ) )
+
+
+//void tmEndTryLock( HTELEMETRY cx,void const * kPtr,TmLockResult const kResult );
+//
+//Description
+// Specify the result of a lock attempt previously started with tmTryLock.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] pointer for the object (mutex, etc.) being locked
+// kResult [in] the result of the lock attempt, one of TmLockResult.
+#define TM_END_TRY_LOCK( context, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLock( context, kPtr, kResult ) )
+
+
+//void tmEndTryLockEx( HTELEMETRY cx,TmU64 const kMatchId,char const * kpFileName,int const kLine,void const * kPtr,TmLockResult const kResult );
+//
+//Description
+// Specify the result of a lock attempt previously started with tmTryLock, but also with file and line information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kMatchId [in] match id returned from tmTryLockEx
+// kpFileName [in] pointer to filename
+// kLine [in] line number
+// kPtr [in] pointer for the object (mutex, etc.) being locked
+// kResult [in] the result of the lock attempt, one of TmLockResult.
+#define TM_END_TRY_LOCK_EX( context, kMatchId, kpFileName, kLine, kPtr, kResult ) TELEMETRY_REQUIRED( tmEndTryLockEx( context, kMatchId, kpFileName, kLine, kPtr, kResult ) )
+
+
+//void tmBeginTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... );
+//
+//Description
+// Start the beginning of a timespan.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kId [in] a user defined identifier for the timespan. Should be > 0.
+// kFlags [in] flags for the timespan. Reserved, must be 0.
+// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
+#define TM_BEGIN_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmEndTimeSpan( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,char const * kpNameFormat,... );
+//
+//Description
+// Mark the end a timespan.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan.
+// kFlags [in] flags for the timespan. Reserved, must be 0.
+// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
+#define TM_END_TIME_SPAN( context, kId, kFlags, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpan( context, kId, kFlags, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmBeginTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... );
+//
+//Description
+// Start the beginning of a timespan but at an explicit time.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kId [in] a user defined identifier for the timespan. Should be > 0.
+// kFlags [in] flags for the timespan. Reserved, must be 0.
+// kTimeStamp [in] explicit timestamp (e.g. from tmFastTime)
+// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
+#define TM_BEGIN_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmBeginTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmEndTimeSpanAt( HTELEMETRY cx,TmU64 const kId,TmU32 const kFlags,TmU64 const kTimeStamp,char const * kpNameFormat,... );
+//
+//Description
+// Mark the end a timespan, but with an explicit timestamp.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kId [in] a user defined identifier for the timespan. Should be the same as the identifier passed to tmBeginTimeSpan.
+// kFlags [in] flags for the timespan. Reserved, must be 0.
+// kTimeStamp [in] a user specified timestamp (e.g. from tmFastTime.
+// kpNameFormat [in] information about this timespan. This may contain printf-style format specifiers.
+#define TM_END_TIME_SPAN_AT( context, kId, kFlags, kTimeStamp, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmEndTimeSpanAt( context, kId, kFlags, kTimeStamp, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmSignalLockCount( HTELEMETRY cx,void const * kPtr,TmU32 const kCount,char const * kpDescription,... );
+//
+//Description
+// Signal that a semaphore's lock count has been incremented.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] pointer to the being whose count is being incremented (e.g. HANDLE)
+// kCount [in] count value
+// kpDescription [in] description of the event. This may contain printf-style format specifiers.
+#define TM_SIGNAL_LOCK_COUNT( context, kPtr, kCount, kpDescription, ... ) TELEMETRY_REQUIRED( tmSignalLockCount( context, kPtr, kCount, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmSetLockState( HTELEMETRY cx,void const * kPtr,TmLockState const kState,char const * kpDescription,... );
+//
+//Description
+// Sets the state of a lock (mutex, critical section, semaphore, etc.)
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] identifier for the lock, typically its address or HANDLE
+// kState [in] new state of the lock
+// kpDescription [in] description of the event. This may contain printf-style format specifiers.
+#define TM_SET_LOCK_STATE( context, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockState( context, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmSetLockStateEx( HTELEMETRY cx,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState );
+//
+//Description
+// Set the state of a lock but with explicit file and line information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpFilename [in] filename where the state change occurs
+// kLine [in] line number of the state change
+// kPtr [in] identifier for the lock, typically its address or HANDLE
+// kState [in] new state of the lock
+// kpDescription [in] description of the event. This may contain printf-style format specifiers.
+#define TM_SET_LOCK_STATE_EX( context, kpFileName, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateEx( context, kpFileName, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmSetLockStateMinTime( HTELEMETRY cx,void * buf,void const * kPtr,TmLockState const kState,char const * fmt,... );
+//
+//Description
+// Set the state of a lock but with a minimum time threshold.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size.
+// kPtr [in] identifier for the lock, typically its address or HANDLE
+// kState [in] new state of the lock
+// kpDescription [in] description of the event. This may contain printf-style format specifiers.
+#define TM_SET_LOCK_STATE_MIN_TIME( context, buf, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTime( context, buf, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmSetLockStateMinTimeEx( HTELEMETRY cx,void * buf,char const * kpFilename,int const kLine,void const * kPtr,TmLockState const kState );
+//
+//Description
+// This is the 'Ex' version of tmSetLockStateMinTimeEx. Please refer to tmSetLockStateEx and tmSetLockStateMinTime for more information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// buf [in] a user buffer used to store the lock event. Must be at least TM_LOCK_MIN_TIME_BUFSIZE in size.
+// kpFilename [in] filename where the state change occurs
+// kLine [in] line number of the state change
+// kPtr [in] identifier for the lock, typically its address or HANDLE
+// kState [in] new state of the lock
+// kpDescription [in] description of the event. This may contain printf-style format specifiers.
+#define TM_SET_LOCK_STATE_MIN_TIME_EX( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ... ) TELEMETRY_REQUIRED( tmSetLockStateMinTimeEx( context, buf, kpFilename, kLine, kPtr, kState, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmThreadName( HTELEMETRY cx,TmU32 const kThreadID,char const * kpNameFormat,... );
+//
+//Description
+// Sets the name of the specified thread.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kThreadID [in] thread identifier of the thread to name. Use 0 to specify the current thread.
+// kpNameFormat [in] name of the thread. This may contain printf-style format specifiers.
+#define TM_THREAD_NAME( context, kThreadID, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmThreadName( context, kThreadID, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmLockName( HTELEMETRY cx,void const* kPtr,char const * kpNameFormat,... );
+//
+//Description
+// Sets the name of the specified locking object.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] identifier for the lock. Usually you can supply a pointer/HANDLE.
+// kpNameFormat [in] name of the lock. This may contain printf-style format specifiers.
+#define TM_LOCK_NAME( context, kPtr, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmLockName( context, kPtr, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmEmitAccumulationZone( HTELEMETRY cx,TmU32 const kZoneFlags,TmU64 * pStart,int const kCount,TmU64 const kTotal,char const * kpZoneFormat,... );
+//
+//Description
+// Emits an accumulation zone.
+//
+//Parameters
+// cx [in] handle to a valid telemetry context
+// kZoneFlags [in] reserved, must be 0
+// pStart [out] pointer to start time variable retrieved with a prior call to tmGetAccumulationStart. This value is modified.
+// kCount [in] number of times the accumulation zone was called
+// kTotal [in] total amount of time spent in the accumulation zone
+// kpZoneFormat [in] name of the accumulation zone. This may contain printf-style format specifiers.
+#define TM_EMIT_ACCUMULATION_ZONE( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ... ) TELEMETRY_REQUIRED( tmEmitAccumulationZone( context, kZoneFlags, pStart, kCount, kTotal, kpZoneFormat, ##__VA_ARGS__ ) )
+
+
+//void tmSetVariable( HTELEMETRY cx,char const * kpKey,char const * kpValueFormat,... );
+//
+//Description
+// Binds a string to a key name and sends to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpKey [in] pointer to string identify the key being set
+// kpValueFormat [in] pointer to string to bind to the associated key. This may contain printf-style format specifiers.
+#define TM_SET_VARIABLE( context, kpKey, kpValueFormat, ... ) TELEMETRY_REQUIRED( tmSetVariable( context, kpKey, kpValueFormat, ##__VA_ARGS__ ) )
+
+
+//void tmSetTimelineSectionName( HTELEMETRY cx,char const * kpNameFormat,... );
+//
+//Description
+// Changes the name of the global state.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpNameFormat [in] name of the current state. This may contain printf-style format specifiers.
+#define TM_SET_TIMELINE_SECTION_NAME( context, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmSetTimelineSectionName( context, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmEnter( HTELEMETRY cx,TmU32 const kFlags,char const * kpZoneName,... );
+//
+//Description
+// Notify Telemetry that a zone is being entered.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kFlags [in] Bitwise OR of TmZoneFlag
+// kpZoneName [in] name of the zone. This may contain printf-style format specifiers.
+#define TM_ENTER( context, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnter( context, kFlags, kpZoneName, ##__VA_ARGS__ ) )
+
+
+//void tmEnterEx( HTELEMETRY cx,TmU64 * pMatchId,TmU32 const kThreadId,TmU64 const kThreshold,char const * kpFilename,int const kLine,TmU32 const kFlags,char const * kpZoneName,... );
+//
+//Description
+// Notify Telemetry that a zone is being entered, but with explicit file and line information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// pMatchId [in] pointer variable to assign a match ID, pass NULL if you are not Zones: Runtime Zone Filtering by Duration.
+// kThreadId [in] thread ID for this zone, pass 0 for current thread
+// kThreshold [in] microseconds that the zone must span before being sent to server.
+// kpFilename [in] filename
+// kLine [in] line number
+// kFlags [in] Bitwise OR of TmZoneFlag
+// kpZoneName [in] name of the zone. This may contain printf-style format specifiers.
+#define TM_ENTER_EX( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ... ) TELEMETRY_REQUIRED( tmEnterEx( context, pMatchId, kThreadId, kThreshold, kpFilename, kLine, kFlags, kpZoneName, ##__VA_ARGS__ ) )
+
+
+//void tmAlloc( HTELEMETRY cx,void const * kPtr,TmU64 const kSize,char const * kpDescription,... );
+//
+//Description
+// Notify Telemetry that memory has been allocated.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kPtr [in] address of the memory that has been allocated
+// kSize [in] size of memory that has been allocated
+// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers.
+#define TM_ALLOC( context, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAlloc( context, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmAllocEx( HTELEMETRY cx,char const * kpFilename,int const kLineNumber,void const * kPtr,TmU64 const kSize,char const * kpDescription,... );
+//
+//Description
+// Notify Telemetry that memory has been allocated, but with explicit file and line information.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpFilename [in] name of the file
+// kLineNumber [in] line number of the allocation
+// kPtr [in] address of the memory that has been allocated
+// kSize [in] size of memory that has been allocated
+// kpDescription [in] textual description of the allocation, e.g. "vertex array" or "texture data". This may contain printf-style format specifiers.
+#define TM_ALLOC_EX( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ... ) TELEMETRY_REQUIRED( tmAllocEx( context, kpFilename, kLineNumber, kPtr, kSize, kpDescription, ##__VA_ARGS__ ) )
+
+
+//void tmMessage( HTELEMETRY cx,TmU32 const kFlags,char const * kpFormatString,... );
+//
+//Description
+// Send a message to the server for later viewing in the Visualizer.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kFlags [in] Bitwise OR of TmMessageFlag
+// kpFormatString [in] message string (not to exceed TM_MAX_STRING in length). This may contain printf-style format specifiers. Note that the message may have a Telemetry object path in it so that it can be hierarchically displayed with other messages.
+#define TM_MESSAGE( context, kFlags, kpFormatString, ... ) TELEMETRY_REQUIRED( tmMessage( context, kFlags, kpFormatString, ##__VA_ARGS__ ) )
+#define TM_LOG( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_LOG, kpFormatString, ##__VA_ARGS__ )
+#define TM_WARNING( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_WARNING, kpFormatString, ##__VA_ARGS__ )
+#define TM_ERROR( context, kpFormatString, ... ) TM_MESSAGE( context, TMMF_SEVERITY_ERROR, kpFormatString, ##__VA_ARGS__ )
+
+
+
+//void tmPlot( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends a floating point plot value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlot( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//Identical to tmPlot()
+//void tmPlotF32( HTELEMETRY cx,TmPlotType const kType,float const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends a floating point plot value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_F32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmPlotF64( HTELEMETRY cx,TmPlotType const kType,double const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends a double precision floating point plot value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_F64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotF64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmPlotI32( HTELEMETRY cx,TmPlotType const kType,TmI32 const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends an signed 32-bit value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_I32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmPlotU32( HTELEMETRY cx,TmPlotType const kType,TmU32 const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends an unsigned 32-bit value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_U32( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU32( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmPlotI64( HTELEMETRY cx,TmPlotType const kType,TmI64 const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends an signed 64-bit value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_I64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotI64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmPlotU64( HTELEMETRY cx,TmPlotType const kType,TmU64 const kValue,char const * kpNameFormat,... );
+//
+//Description
+// Sends an unsigned 64-bit value to the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kType [in] type of the plot (used to specify how the Visualizer will format the plot's value).
+// kValue [in] the value of the plot at this moment in time
+// kpNameFormat [in] name of the plot. You can use Telemetry object paths to create plot hierarchies on the Visualizer's plot filter tree. You can also specify plot scaling groups by appending group names in parenthesis to your plot's name, e.g. "renderer/memory/meshes(rendermem)" and "renderer/memory/textures(rendermem)" would be scaled using the same min/max values. This may contain printf-style format specifiers.
+#define TM_PLOT_U64( context, kType, kFlags, kValue, kpNameFormat, ... ) TELEMETRY_REQUIRED( tmPlotU64( context, kType, kFlags, kValue, kpNameFormat, ##__VA_ARGS__ ) )
+
+
+//void tmBlob( HTELEMETRY cx,void const * kpData,int const kDataSize,char const * kpPluginIdentifier,char const * kpBlobName,... );
+//
+//Description
+// Sends an arbitrary application specified blob of binary data for storage on the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kpData [in] the actual blob data
+// kDataSize [in] size of kpData in bytes
+// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier).
+// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers.
+#define TM_BLOB( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ...) TELEMETRY_REQUIRED( tmBlob( context, kpData, kDataSize, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) )
+
+
+//void tmDisjointBlob( HTELEMETRY cx,int const kNumPieces,void const ** kpData,int const * kDataSizes,char const* kpPluginIdentifier,char const * kpBlobName,... );
+//
+//Description
+// Sends an arbitrary application specified blob of binary data for storage on the server.
+//
+//Parameters
+// cx [in] handle to a valid Telemetry context
+// kNumPieces [in] number of elements in kpData and kDataSizes
+// kpData [in] array of actual data blobs
+// kDataSizes [in] array of data blob sizes in bytes
+// kpPluginIdentifier [in] identifier of the plugin used to visualize this data (must match the plugin's internal identifier).
+// kpBlobName [in] the name of the blob. This may contain printf-style format specifiers.
+#define TM_DISJOINT_BLOB( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ... ) TELEMETRY_REQUIRED( tmDisjointBlob( context, kNumPieces, kpData, kDataSizes, kpPluginIdentifier, kpBlobName, ##__VA_ARGS__ ) )
+
+
+
+
+
+
+
+
+
+
+
+
+#if !defined( RAD_TELEMETRY_ENABLED )
+
+//
+// Telemetry is disabled.
+//
+
+class CTelemetryLock
+{
+public:
+ CTelemetryLock(void *plocation, const char *description) {}
+ ~CTelemetryLock() {}
+ void Locked() {}
+ void Unlocked() {}
+};
+
+class CTelemetrySpikeDetector
+{
+public:
+ CTelemetrySpikeDetector( const char *msg, uint32 threshold = 50 ) {}
+ ~CTelemetrySpikeDetector() { }
+};
+
+#define TelemetrySetLockName( _ctx, _location, _description )
+
+#else
+
+//
+// Telemetry is enabled.
+//
+
+#define TelemetrySetLockName( _ctx, _location, _description ) \
+ do \
+ { \
+ static bool s_bNameSet = false; \
+ if( _ctx && !s_bNameSet ) \
+ { \
+ tmLockName( _ctx, _location, _description ); \
+ s_bNameSet = true; \
+ } \
+ } while( 0 )
+
+class CTelemetryLock
+{
+public:
+ CTelemetryLock(void *plocation, const char *description)
+ {
+ m_plocation = (const char *)plocation;
+ m_description = description;
+ TelemetrySetLockName( TELEMETRY_LEVEL1, m_plocation, m_description );
+ TM_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, "%s", m_description );
+ }
+ ~CTelemetryLock()
+ {
+ Unlocked();
+ }
+ void Locked()
+ {
+ TM_END_TRY_LOCK( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS );
+ TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description );
+ }
+ void Unlocked()
+ {
+ if( m_plocation )
+ {
+ TM_SET_LOCK_STATE( TELEMETRY_LEVEL1, m_plocation, TMLS_RELEASED, "%s Released", m_description );
+ m_plocation = NULL;
+ }
+ }
+
+public:
+ const char *m_plocation;
+ const char *m_description;
+};
+
+class CTelemetrySpikeDetector
+{
+public:
+ // Spews Telemetry message when threshold hit (in milliseconds.)
+ CTelemetrySpikeDetector( const char *msg, float threshold = 5 ) :
+ m_message( msg ), m_threshold( threshold ), time0( tmFastTime() ) {}
+ ~CTelemetrySpikeDetector()
+ {
+ float time = ( tmFastTime() - time0 ) * g_Telemetry.flRDTSCToMilliSeconds;
+ if( time >= m_threshold )
+ {
+ TM_MESSAGE( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(dota/spike)%s %.2fms %t", m_message, time, tmSendCallStack( TELEMETRY_LEVEL0, 0 ) );
+ }
+ }
+
+private:
+ TmU64 time0;
+ float m_threshold;
+ const char *m_message;
+};
+
+#endif // RAD_TELEMETRY_ENABLED
+
+#endif // VPROF_TELEMETRY_H
diff --git a/sp/src/public/tier0/wchartypes.h b/sp/src/public/tier0/wchartypes.h
index a0a954e3..9803870c 100644
--- a/sp/src/public/tier0/wchartypes.h
+++ b/sp/src/public/tier0/wchartypes.h
@@ -1,101 +1,101 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: All of our code is completely Unicode. Instead of char, you should
-// use wchar, uint8, or char8, as explained below.
-//
-// $NoKeywords: $
-//=============================================================================//
-
-
-#ifndef WCHARTYPES_H
-#define WCHARTYPES_H
-#ifdef _WIN32
-#pragma once
-#endif
-
-#ifdef _INC_TCHAR
-#error ("Must include tier0 type headers before tchar.h")
-#endif
-
-// Temporarily turn off Valve defines
-#include "tier0/valve_off.h"
-
-#if !defined(_WCHAR_T_DEFINED) && !defined(GNUC)
-typedef unsigned short wchar_t;
-#define _WCHAR_T_DEFINED
-#endif
-
-// char8
-// char8 is equivalent to char, and should be used when you really need a char
-// (for example, when calling an external function that's declared to take
-// chars).
-typedef char char8;
-
-// uint8
-// uint8 is equivalent to byte (but is preferred over byte for clarity). Use this
-// whenever you mean a byte (for example, one byte of a network packet).
-typedef unsigned char uint8;
-typedef unsigned char BYTE;
-typedef unsigned char byte;
-
-// wchar
-// wchar is a single character of text (currently 16 bits, as all of our text is
-// Unicode). Use this whenever you mean a piece of text (for example, in a string).
-typedef wchar_t wchar;
-//typedef char wchar;
-
-// __WFILE__
-// This is a Unicode version of __FILE__
-#define WIDEN2(x) L ## x
-#define WIDEN(x) WIDEN2(x)
-#define __WFILE__ WIDEN(__FILE__)
-
-#ifdef STEAM
-#ifndef _UNICODE
-#define FORCED_UNICODE
-#endif
-#define _UNICODE
-#endif
-
-#ifdef _WIN32
-#include <tchar.h>
-#else
-#define _tcsstr strstr
-#define _tcsicmp stricmp
-#define _tcscmp strcmp
-#define _tcscpy strcpy
-#define _tcsncpy strncpy
-#define _tcsrchr strrchr
-#define _tcslen strlen
-#define _tfopen fopen
-#define _stprintf sprintf
-#define _ftprintf fprintf
-#define _vsntprintf _vsnprintf
-#define _tprintf printf
-#define _sntprintf _snprintf
-#define _T(s) s
-#endif
-
-#if defined(_UNICODE)
-typedef wchar tchar;
-#define tstring wstring
-#define __TFILE__ __WFILE__
-#define TCHAR_IS_WCHAR
-#else
-typedef char tchar;
-#define tstring string
-#define __TFILE__ __FILE__
-#define TCHAR_IS_CHAR
-#endif
-
-#ifdef FORCED_UNICODE
-#undef _UNICODE
-#endif
-
-// Turn valve defines back on
-#include "tier0/valve_on.h"
-
-
-#endif // WCHARTYPES
-
-
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: All of our code is completely Unicode. Instead of char, you should
+// use wchar, uint8, or char8, as explained below.
+//
+// $NoKeywords: $
+//=============================================================================//
+
+
+#ifndef WCHARTYPES_H
+#define WCHARTYPES_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#ifdef _INC_TCHAR
+#error ("Must include tier0 type headers before tchar.h")
+#endif
+
+// Temporarily turn off Valve defines
+#include "tier0/valve_off.h"
+
+#if !defined(_WCHAR_T_DEFINED) && !defined(GNUC)
+typedef unsigned short wchar_t;
+#define _WCHAR_T_DEFINED
+#endif
+
+// char8
+// char8 is equivalent to char, and should be used when you really need a char
+// (for example, when calling an external function that's declared to take
+// chars).
+typedef char char8;
+
+// uint8
+// uint8 is equivalent to byte (but is preferred over byte for clarity). Use this
+// whenever you mean a byte (for example, one byte of a network packet).
+typedef unsigned char uint8;
+typedef unsigned char BYTE;
+typedef unsigned char byte;
+
+// wchar
+// wchar is a single character of text (currently 16 bits, as all of our text is
+// Unicode). Use this whenever you mean a piece of text (for example, in a string).
+typedef wchar_t wchar;
+//typedef char wchar;
+
+// __WFILE__
+// This is a Unicode version of __FILE__
+#define WIDEN2(x) L ## x
+#define WIDEN(x) WIDEN2(x)
+#define __WFILE__ WIDEN(__FILE__)
+
+#ifdef STEAM
+#ifndef _UNICODE
+#define FORCED_UNICODE
+#endif
+#define _UNICODE
+#endif
+
+#ifdef _WIN32
+#include <tchar.h>
+#else
+#define _tcsstr strstr
+#define _tcsicmp stricmp
+#define _tcscmp strcmp
+#define _tcscpy strcpy
+#define _tcsncpy strncpy
+#define _tcsrchr strrchr
+#define _tcslen strlen
+#define _tfopen fopen
+#define _stprintf sprintf
+#define _ftprintf fprintf
+#define _vsntprintf _vsnprintf
+#define _tprintf printf
+#define _sntprintf _snprintf
+#define _T(s) s
+#endif
+
+#if defined(_UNICODE)
+typedef wchar tchar;
+#define tstring wstring
+#define __TFILE__ __WFILE__
+#define TCHAR_IS_WCHAR
+#else
+typedef char tchar;
+#define tstring string
+#define __TFILE__ __FILE__
+#define TCHAR_IS_CHAR
+#endif
+
+#ifdef FORCED_UNICODE
+#undef _UNICODE
+#endif
+
+// Turn valve defines back on
+#include "tier0/valve_on.h"
+
+
+#endif // WCHARTYPES
+
+
diff --git a/sp/src/public/tier0/xbox_codeline_defines.h b/sp/src/public/tier0/xbox_codeline_defines.h
index ebdb3914..2e3b2c52 100644
--- a/sp/src/public/tier0/xbox_codeline_defines.h
+++ b/sp/src/public/tier0/xbox_codeline_defines.h
@@ -1,16 +1,16 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#ifndef XBOX_CODELINE_DEFINES_H
-#define XBOX_CODELINE_DEFINES_H
-
-
-// In the regular src_main codeline, we leave this out.
-//#define IN_XBOX_CODELINE
-
-
-#endif // XBOX_CODELINE_DEFINES_H
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef XBOX_CODELINE_DEFINES_H
+#define XBOX_CODELINE_DEFINES_H
+
+
+// In the regular src_main codeline, we leave this out.
+//#define IN_XBOX_CODELINE
+
+
+#endif // XBOX_CODELINE_DEFINES_H