This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
+480
View File
@@ -0,0 +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);
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +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
File diff suppressed because it is too large Load Diff
+322
View File
@@ -0,0 +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
+225
View File
@@ -0,0 +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
+192
View File
@@ -0,0 +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 )
#endif // PMELIB_H
+456
View File
@@ -0,0 +1,456 @@
//========= 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 _MSC_VER >= 1700
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
#if _MSC_VER >= 1700
void* __cdecl operator new[](size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
{
return ::operator new(nSize, nType, lpszFileName, nLine);
}
void __cdecl operator delete[](void* p, int nType, LPCSTR lpszFileName, int nLine)
{
::operator delete(p, nType, lpszFileName, nLine);
}
#endif // _MSC_VER >= 1210
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
+84
View File
@@ -0,0 +1,84 @@
//========= 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>
// 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
// Used for annotating functions to describe their return types.
#define MUST_CHECK_RETURN _Check_return_
// 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
#define MUST_CHECK_RETURN
#endif
#endif // ANALYSIS_ANNOTATIONS_H
+398
View File
@@ -0,0 +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
+174
View File
@@ -0,0 +1,174 @@
//========= 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)
#define V_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
+33
View File
@@ -0,0 +1,33 @@
#ifndef CPU_MONITORING_H
#define CPU_MONITORING_H
/*
This header defines functions and structures for controlling the measurement of CPU frequency
in order to detect thermal throttling. For details see the associated source file.
*/
struct CPUFrequencyResults
{
double m_timeStamp; // Time (from Plat_FloatTime) when the measurements were made.
float m_GHz;
float m_percentage;
float m_lowestPercentage;
};
// Call this to get results.
// When CPU monitoring is 'disabled' it may still be running at a low frequency,
// for OGS purposes or for proactively warning users of problems. If fGetDisabledResults
// is true then results will be returned when disabled (if available).
PLATFORM_INTERFACE CPUFrequencyResults GetCPUFrequencyResults( bool fGetDisabledResults = false );
// Call this to set the monitoring frequency. Intervals of 2-5 seconds (2,000 to 5,000 ms)
// are recommended. An interval of zero will disable CPU monitoring. Short delays (below
// about 300 ms) will be rounded up.
PLATFORM_INTERFACE void SetCPUMonitoringInterval( unsigned nDelayMilliseconds );
// Warn with increasing strident colors when CPU percentages go below these levels.
// They are const int instead of float because const float in C++ is stupid.
const int kCPUMonitoringWarning1 = 80;
const int kCPUMonitoringWarning2 = 50;
#endif
+820
View File
@@ -0,0 +1,820 @@
//========= 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 );
/* True if -hushasserts was passed on command line. */
DBG_INTERFACE bool HushAsserts();
#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 retAssert = _SpewMessage("%s", static_cast<const char*>( _msg )); \
CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \
_executeExp; \
if ( retAssert == 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, (const tchar *)CDbgFmtMsg( _msg, ##__VA_ARGS__ ), ((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, _msg, a1 )
#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, _msg, a1, a2 )
#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, _msg, a1, a2, a3 )
#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4 )
#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5 )
#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 )
#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )
#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )
#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, _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 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, (const tchar *)CDbgFmtMsg( _msg, ##__VA_ARGS__ ), ((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 VerifyMsg1( _exp, _msg, a1 ) AssertMsg1( _exp, _msg, a1 )
#define VerifyMsg2( _exp, _msg, a1, a2 ) AssertMsg2( _exp, _msg, a1, a2 )
#define VerifyMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg3( _exp, _msg, a1, a2, a3 )
#define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue )
#define DbgVerify( _exp ) Assert( _exp )
#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, _msg, a1 )
#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, _msg, a1, a2 )
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, _msg, a1, a2, a3 )
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, _msg, a1, a2, a3, a4 )
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5 )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6 )
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 )
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 )
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg( _exp, _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 VerifyMsg1( _exp, _msg, a1 ) (_exp)
#define VerifyMsg2( _exp, _msg, a1, a2 ) (_exp)
#define VerifyMsg3( _exp, _msg, a1, a2, a3 ) (_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 )
// Stringify a number
#define V_STRINGIFY_INTERNAL(x) #x
// Extra level of indirection needed when passing in a macro to avoid getting the macro name instead of value
#define V_STRINGIFY(x) V_STRINGIFY_INTERNAL(x)
// Macros to help decorate warnings or errors with the location in code
#define FILE_LINE_FUNCTION_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):" __FUNCTION__ ":"
#define FILE_LINE_STRING __FILE__ "(" V_STRINGIFY(__LINE__) "):"
#define FUNCTION_LINE_STRING __FUNCTION__ "(" V_STRINGIFY(__LINE__) "): "
// Handy define for inserting clickable messages into the build output.
// Use like this:
// #pragma MESSAGE("Some message")
#define MESSAGE(msg) message(__FILE__ "(" V_STRINGIFY(__LINE__) "): " msg)
#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 MsgV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist );
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 WarningV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist );
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 );
DBG_INTERFACE void LogV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist );
#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 );
DBG_INTERFACE void NORETURN ErrorV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist );
#endif
#else
inline void Msg( ... ) {}
inline void DMsg( ... ) {}
inline void MsgV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {}
inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {}
inline void WarningV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {}
inline void DWarning( ... ) {}
inline void Log( ... ) {}
inline void DLog( ... ) {}
inline void LogV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {}
inline void Error( ... ) {}
inline void ErrorV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) {}
#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
//-----------------------------------------------------------------------------
// This macro predates universal static_assert support in our toolchains
#define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
// 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 )
// NOTE: On GCC / Clang, assert_cast can sometimes fire even if the type is correct. We should just workaround these.
// The situation where this would occur is
// 1. You create an object of a low level type in a DLL, and it really gets created there.
// 2. You pass it across a DLL boundary
// 3. You use assert_cast to verify it in the second DLL boundary (where it also could've been created).
#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
//-----------------------------------------------------------------------------
// This is horrible, but we don't want to integrate CS:GO new logging system atm.
#define Log_Warning( ignore, ... ) ::Msg( __VA_ARGS__ ); ::Log( __VA_ARGS__ );
#define Log_Msg( ignore, ... ) ::Warning( __VA_ARGS__ ); ::Log( __VA_ARGS__ );
#define Log_Error( ignore, ... ) ::Error( __VA_ARGS__ );
#define DEFINE_LOGGING_CHANNEL_NO_TAGS( ... );
#define Plat_FatalError( ... ) do { Log_Error( LOG_GENERAL, __VA_ARGS__ ); Plat_ExitProcess( EXIT_FAILURE ); } while( 0 )
#endif /* DBG_H */
+65
View File
@@ -0,0 +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
+136
View File
@@ -0,0 +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
+157
View File
@@ -0,0 +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
+569
View File
@@ -0,0 +1,569 @@
//========= 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;
};
// -------------------------------------------------------------------------- //
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() const;
int CMicroSecOverage() const;
uint64 CMicroSecLeft() const;
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() const
{
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() const
{
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() const
{
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
+377
View File
@@ -0,0 +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
+61
View File
@@ -0,0 +1,61 @@
//========= 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;
// A bool return of whether param exists, useful for just checking if param that is just a flag is set
virtual bool HasParm( const char *psz ) 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;
virtual const char *ParmValueByIndex( int nIndex, const char *pDefaultVal = 0 ) const = 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
+46
View File
@@ -0,0 +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
+47
View File
@@ -0,0 +1,47 @@
//========= 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>
#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();
MEM_INTERFACE void MemAllocOOMError( size_t nSize );
#ifdef _LINUX
MEM_INTERFACE void ZeroMemory( void *mem, size_t length );
#endif
#endif /* TIER0_MEM_H */
+661
View File
@@ -0,0 +1,661 @@
//========= 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_JOIN_AGAIN( a, b ) a ## b
#define MEM_ALLOC_CREDIT_JOIN( a, b ) MEM_ALLOC_CREDIT_JOIN_AGAIN( a, b )
#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction MEM_ALLOC_CREDIT_JOIN( memAllocAttributeAlloction, __LINE__ )( 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_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 )
inline void MemAlloc_CheckAlloc( void *ptr, size_t nSize )
{
if ( !ptr )
MemAllocOOMError( nSize );
}
#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); MemAlloc_CheckAlloc( pTmp, size ); return pTmp;}
#endif
inline void *_aligned_malloc( size_t nSize, size_t align ) { void *ptr = memalign( align, nSize ); MemAlloc_CheckAlloc( ptr, nSize ); return ptr; }
inline void _aligned_free( void *ptr ) { free( ptr ); }
inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName = NULL, int nLine = 0 ) { void *ptr = malloc( nSize ); MemAlloc_CheckAlloc( ptr, nSize ); return ptr; }
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 ) { void *ptr = memalign( align, size ); MemAlloc_CheckAlloc( ptr, size ); return ptr; }
inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile = NULL, int nLine = 0 ) { void *ptr = memalign( align, size ); MemAlloc_CheckAlloc( ptr, size ); return ptr; }
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 );
}
MemAlloc_CheckAlloc( ptr_new_aligned, size );
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_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 */
+25
View File
@@ -0,0 +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
+318
View File
@@ -0,0 +1,318 @@
//========= 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 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
#ifdef OSX
void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ) throw (std::bad_alloc);
void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ) throw (std::bad_alloc);
#else
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
#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__ )
#ifdef _malloc_dbg
#undef _malloc_dbg
#endif
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
#if !defined( POSIX )
#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 )
#ifdef _malloc_dbg
#undef _malloc_dbg
#endif
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
#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"
#if !defined( VALVE_ALLOCS_DEFINED )
#define VALVE_ALLOCS_DEFINED
#include "tier0/mem.h"
inline void *valve_malloc_check_oom( size_t size )
{
void *ptr = malloc( size );
if ( !ptr )
MemAllocOOMError( size );
return ptr;
}
inline void *valve_realloc_check_oom( void *ptr, size_t size )
{
void *ret = realloc( ptr, size );
if ( !ret )
MemAllocOOMError( size );
return ret;
}
inline void *valve_calloc_check_oom( size_t num, size_t size )
{
void *ptr = calloc( num, size );
if (!ptr)
MemAllocOOMError( num * size );
return ptr;
}
inline void *valve_memalign_check_oom( size_t alignment, size_t size )
{
void *ptr = memalign( alignment, size );
if (!ptr)
MemAllocOOMError(size);
return ptr;
}
inline void *valve_aligned_malloc_check_oom( size_t size, size_t alignment )
{
void *ptr = _aligned_malloc( size, alignment );
if (!ptr)
MemAllocOOMError( size );
return ptr;
}
#endif // VALVE_ALLOCS_DEFINED
#define malloc valve_malloc_check_oom
#define realloc valve_realloc_check_oom
#define calloc valve_calloc_check_oom
#define memalign valve_memalign_check_oom
#define _aligned_malloc valve_aligned_malloc_check_oom
#endif // !STEAM && !NO_MALLOC_OVERRIDE
#if defined( NO_MALLOC_OVERRIDE )
#undef malloc
#undef realloc
#undef calloc
#undef memalign
#undef _aligned_malloc
#endif // NO_MALLOC_OVERRIDE
File diff suppressed because it is too large Load Diff
+104
View File
@@ -0,0 +1,104 @@
//========= 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 // defined(_WIN32) && !defined(_X360)
//
// Minidump User Stream Info Comments.
//
// There currently is a single header string, and an array of 64 comment strings.
// MinidumpUserStreamInfoSetHeader() will set the single header string.
// MinidumpUserStreamInfoAppend() will round robin through and array and set the comment strings, overwriting old.
PLATFORM_INTERFACE void MinidumpUserStreamInfoSetHeader( const char *pFormat, ... );
PLATFORM_INTERFACE void MinidumpUserStreamInfoAppend( const char *pFormat, ... );
// Retrieve the StreamInfo strings.
// Index 0: header string
// Index 1..: comment string
// Returns NULL when you've reached the end of the comment string array
// Empty strings ("\0") can be returned if comment hasn't been set
PLATFORM_INTERFACE const char *MinidumpUserStreamInfoGet( int Index );
#endif // MINIDUMP_H
File diff suppressed because it is too large Load Diff
+73
View File
@@ -0,0 +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
};
#endif // CPMCDATA_H
+17
View File
@@ -0,0 +1,17 @@
.model flat, C
.data
__imp__EncodePointer@4 dd dummy
__imp__DecodePointer@4 dd dummy
EXTERNDEF __imp__EncodePointer@4 : DWORD
EXTERNDEF __imp__DecodePointer@4 : DWORD
.code
dummy proc
mov eax, [esp+4]
ret 4
dummy endp
end
+23
View File
@@ -0,0 +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
+271
View File
@@ -0,0 +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
+153
View File
@@ -0,0 +1,153 @@
//========= Copyright 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose: Tools for grabbing/dumping the stack at runtime
//
// $NoKeywords: $
//=============================================================================//
#ifndef TIER0_STACKTOOLS_H
#define TIER0_STACKTOOLS_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#if (defined( PLATFORM_WINDOWS ) || defined( PLATFORM_X360 )) && !defined( STEAM ) && !defined( _CERT ) && defined( TCHAR_IS_CHAR ) //designed for windows/x360, not built/tested with wide characters, not intended for release builds (but probably wouldn't damage anything)
# define ENABLE_RUNTIME_STACK_TRANSLATION //uncomment to enable runtime stack translation tools. All of which use on-demand loading of necessary dll's and pdb's
#endif
#if defined( ENABLE_RUNTIME_STACK_TRANSLATION )
//#define ENABLE_THREAD_PARENT_STACK_TRACING 1 //uncomment to actually enable tracking stack traces from threads and jobs to their parent thread. Must also define THREAD_PARENT_STACK_TRACE_SUPPORTED in threadtools.h
# if defined( ENABLE_THREAD_PARENT_STACK_TRACING )
# define THREAD_PARENT_STACK_TRACE_LENGTH 32
# endif
#endif
PLATFORM_INTERFACE int GetCallStack( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
//ONLY WORKS IF THE CRAWLED PORTION OF THE STACK DISABLES FRAME POINTER OMISSION (/Oy-) "vpc /nofpo"
PLATFORM_INTERFACE int GetCallStack_Fast( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
typedef int (*FN_GetCallStack)( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
//where we'll find our PDB's for win32.
PLATFORM_INTERFACE void SetStackTranslationSymbolSearchPath( const char *szSemicolonSeparatedList = NULL );
PLATFORM_INTERFACE void StackToolsNotify_LoadedLibrary( const char *szLibName );
//maximum output sample "tier0.dll!TranslateStackInfo - u:\Dev\L4D\src\tier0\stacktools.cpp(162) + 4 bytes"
enum TranslateStackInfo_StyleFlags_t
{
TSISTYLEFLAG_NONE = 0,
TSISTYLEFLAG_MODULENAME = (1<<0), //start with module Sample: "tier0.dll!"
TSISTYLEFLAG_SYMBOLNAME = (1<<1), //include the symbol name Sample: "TranslateStackInfo"
TSISTYLEFLAG_FULLPATH = (1<<2), //include full path Sample: "u:\Dev\L4D\src\tier0\stacktools.cpp"
TSISTYLEFLAG_SHORTPATH = (1<<3), //only include 2 directories Sample: "\src\tier0\stacktools.cpp"
TSISTYLEFLAG_LINE = (1<<4), //file line number Sample: "(162)"
TSISTYLEFLAG_LINEANDOFFSET = (1<<5), //file line + offset Sample: "(162) + 4 bytes"
TSISTYLEFLAG_LAST = TSISTYLEFLAG_LINEANDOFFSET,
TSISTYLEFLAG_DEFAULT = (TSISTYLEFLAG_MODULENAME | TSISTYLEFLAG_SYMBOLNAME | TSISTYLEFLAG_FULLPATH | TSISTYLEFLAG_LINEANDOFFSET), //produces sample above
};
//Generates a formatted list of function information, returns number of translated entries
//On 360 this generates a string that can be decoded by VXConsole in print functions. Optimal path for translation because it's one way. Other paths require multiple transactions.
PLATFORM_INTERFACE int TranslateStackInfo( const void * const *pCallStack, int iCallStackCount, tchar *szOutput, int iOutBufferSize, const tchar *szEntrySeparator, TranslateStackInfo_StyleFlags_t style = TSISTYLEFLAG_DEFAULT );
PLATFORM_INTERFACE void PreloadStackInformation( void * const *pAddresses, int iAddressCount ); //caches data and reduces communication with VXConsole to speed up 360 decoding when using any of the Get***FromAddress() functions. Nop on PC.
PLATFORM_INTERFACE bool GetFileAndLineFromAddress( const void *pAddress, tchar *pFileNameOut, int iMaxFileNameLength, uint32 &iLineNumberOut, uint32 *pDisplacementOut = NULL );
PLATFORM_INTERFACE bool GetSymbolNameFromAddress( const void *pAddress, tchar *pSymbolNameOut, int iMaxSymbolNameLength, uint64 *pDisplacementOut = NULL );
PLATFORM_INTERFACE bool GetModuleNameFromAddress( const void *pAddress, tchar *pModuleNameOut, int iMaxModuleNameLength );
class PLATFORM_CLASS CCallStackStorage //a helper class to grab a stack trace as close to the leaf code surface as possible, then pass it on to deeper functions intact with less unpredictable inlining pollution
{
public:
CCallStackStorage( FN_GetCallStack GetStackFunction = GetCallStack, uint32 iSkipCalls = 0 );
CCallStackStorage( const CCallStackStorage &copyFrom )
{
iValidEntries = copyFrom.iValidEntries;
memcpy( pStack, copyFrom.pStack, sizeof( void * ) * copyFrom.iValidEntries );
}
void *pStack[128]; //probably too big, possibly too small for some applications. Don't want to spend the time figuring out how to generalize this without templatizing pollution or mallocs
uint32 iValidEntries;
};
//Hold onto one of these to denote the top of a functional stack trace. Also allows us to string together threads to their parents
class PLATFORM_CLASS CStackTop_Base
{
protected:
#if defined( ENABLE_RUNTIME_STACK_TRANSLATION )
CStackTop_Base *m_pPrevTop;
void *m_pStackBase;
void *m_pReplaceAddress;
void * const *m_pParentStackTrace;
int m_iParentStackTraceLength;
#endif
};
//makes a copy of the parent stack
class PLATFORM_CLASS CStackTop_CopyParentStack : public CStackTop_Base
{
public:
CStackTop_CopyParentStack( void * const * pParentStackTrace, int iParentStackTraceLength );
~CStackTop_CopyParentStack( void );
};
//just references the parent stack. Assuming that you'll keep that memory around as long as you're keeping this Stack Top marker.
class PLATFORM_CLASS CStackTop_ReferenceParentStack : public CStackTop_Base
{
public:
CStackTop_ReferenceParentStack( void * const * pParentStackTrace = NULL, int iParentStackTraceLength = 0 );
~CStackTop_ReferenceParentStack( void );
void ReleaseParentStackReferences( void ); //in case you need to delete the parent stack trace before this class goes out of scope
};
//Encodes data so that every byte's most significant bit is a 1. Ensuring no null terminators.
//This puts the encoded data in the 128-255 value range. Leaving all standard ascii characters for control.
//Returns string length (not including the written null terminator as is standard).
//Or if the buffer is too small. Returns negative of necessary buffer size (including room needed for null terminator)
PLATFORM_INTERFACE int EncodeBinaryToString( const void *pToEncode, int iDataLength, char *pEncodeOut, int iEncodeBufferSize );
//Decodes a string produced by EncodeBinaryToString(). Safe to decode in place if you don't mind trashing your string, binary byte count always less than string byte count.
//Returns:
// >= 0 is the decoded data size
// INT_MIN (most negative value possible) indicates an improperly formatted string (not our data)
// all other negative values are the negative of how much dest buffer size is necessary.
PLATFORM_INTERFACE int DecodeBinaryFromString( const char *pString, void *pDestBuffer, int iDestBufferSize, char **ppParseFinishOut = NULL );
// 360<->VXConsole specific communication definitions
#define XBX_CALLSTACKDECODEPREFIX ":CSDECODE["
enum StackTranslation_BinaryHandler_Command_t
{
ST_BHC_LOADEDLIBARY,
ST_BHC_GETTRANSLATIONINFO,
};
#pragma pack(push)
#pragma pack(1)
struct FullStackInfo_t
{
const void *pAddress;
char szModuleName[24];
char szFileName[MAX_PATH/2];
char szSymbol[64];
uint32 iLine;
uint32 iSymbolOffset;
};
#pragma pack(pop)
#endif //#ifndef TIER0_STACKTOOLS_H
+56
View File
@@ -0,0 +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
+60
View File
@@ -0,0 +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
File diff suppressed because it is too large Load Diff
+84
View File
@@ -0,0 +1,84 @@
//========= 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 tmLeave(...)
#define tmLeaveEx(...)
#define tmBeginTimeSpan(...)
#define tmEndTimeSpan(...)
#define tmBeginTimeSpanAt(...)
#define tmEndTimeSpanAt(...)
#define tmDynamicString(...) ""
#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;
File diff suppressed because it is too large Load Diff
+32
View File
@@ -0,0 +1,32 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: functionality that is provided in C++11 type_traits, which
// currently isn't supported by the OSX compiler. Sadness.
//
//=============================================================================
#pragma once
template <class T>
struct V_remove_const
{
typedef T type;
};
template <class T>
struct V_remove_const<const T>
{
typedef T type;
};
template <class T>
struct V_remove_const<const T[]>
{
typedef T type;
};
template <class T, unsigned int N>
struct V_remove_const<const T[N]>
{
typedef T type;
};
+73
View File
@@ -0,0 +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
+72
View File
@@ -0,0 +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
+7
View File
@@ -0,0 +1,7 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
+9
View File
@@ -0,0 +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
+30
View File
@@ -0,0 +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
+31
View File
@@ -0,0 +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
+54
View File
@@ -0,0 +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
+306
View File
@@ -0,0 +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
+1440
View File
File diff suppressed because it is too large Load Diff
+154
View File
@@ -0,0 +1,154 @@
//========= 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 // !MAKE_VPC
#if !defined( RAD_TELEMETRY_ENABLED )
//
// Kill all tmZone() macros, etc.
//
#include "tmapi_dummy.h"
inline void TelemetryTick() {}
inline void TelemetrySetLevel( unsigned int Level ) {}
#define TelemetrySetLockName( _ctx, _location, _description )
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 TM_ZONE_DEFAULT( context )
#define TM_ZONE_DEFAULT_PARAM( context, string_param )
#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
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.
int playbacktick; // GetPlaybackTick() value from demo file (or 0 if not playing a demo).
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;
PLATFORM_INTERFACE void TelemetryTick();
PLATFORM_INTERFACE void TelemetrySetLevel( unsigned int Level );
#define TELEMETRY_LEVEL0 g_Telemetry.tmContext[0] // high level tmZone()
#define TELEMETRY_LEVEL1 g_Telemetry.tmContext[1] // lower level tmZone(), tmZoneFiltered()
#define TELEMETRY_LEVEL2 g_Telemetry.tmContext[2] // VPROF_0
#define TELEMETRY_LEVEL3 g_Telemetry.tmContext[3] // VPROF_1
#define TELEMETRY_LEVEL4 g_Telemetry.tmContext[4] // VPROF_2
#define TELEMETRY_LEVEL5 g_Telemetry.tmContext[5] // VPROF_3
#define TELEMETRY_LEVEL6 g_Telemetry.tmContext[6] // VPROF_4
#define TM_ZONE_DEFAULT( context ) tmZone(context, TMZF_NONE, __FUNCTION__ )
#define TM_ZONE_DEFAULT_PARAM( context, string_param ) tmZone(context, TMZF_NONE, "%s( %s )", __FUNCTION__ , tmDynamicString( context, (string_param) ) )
#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 );
tmTryLock( TELEMETRY_LEVEL1, m_plocation, "%s", m_description );
}
~CTelemetryLock()
{
Unlocked();
}
void Locked()
{
tmEndTryLock( TELEMETRY_LEVEL1, m_plocation, TMLR_SUCCESS );
tmSetLockState( TELEMETRY_LEVEL1, m_plocation, TMLS_LOCKED, "%s Locked", m_description );
}
void Unlocked()
{
if( m_plocation )
{
tmSetLockState( 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 )
{
tmMessage( TELEMETRY_LEVEL0, TMMF_ICON_NOTE | TMMF_SEVERITY_WARNING, "(source/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
+109
View File
@@ -0,0 +1,109 @@
//========= 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
#if defined( _MSC_VER ) || defined( WIN32 )
typedef wchar_t uchar16;
typedef unsigned int uchar32;
#else
typedef unsigned short uchar16;
typedef wchar_t uchar32;
#endif
#ifdef FORCED_UNICODE
#undef _UNICODE
#endif
// Turn valve defines back on
#include "tier0/valve_on.h"
#endif // WCHARTYPES
+16
View File
@@ -0,0 +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