From b599d02bd73650536ae4ff27a95da8894bf185e2 Mon Sep 17 00:00:00 2001 From: valerie lirz Date: Sun, 25 May 2025 01:19:20 -0700 Subject: [PATCH] zig as a build system, get tier0.so and vstdlib.so to build --- .gitignore | 3 + build.zig | 117 +++++++ progress.md | 20 ++ project.zig | 454 ++++++++++++++++++++++++++ public/tier0/platform.h | 16 +- public/tier1/utlblockmemory.h | 28 +- tier0/InterlockedCompareExchange128.S | 46 +++ tier0/dbg.cpp | 44 +-- wscript | 6 +- 9 files changed, 696 insertions(+), 38 deletions(-) create mode 100644 build.zig create mode 100644 progress.md create mode 100644 project.zig create mode 100644 tier0/InterlockedCompareExchange128.S diff --git a/.gitignore b/.gitignore index 717bd12d..adde4331 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ waf3*/ .vscode/ .depproj/ source-engine.sln + +zig-out +.zig-cache \ No newline at end of file diff --git a/build.zig b/build.zig new file mode 100644 index 00000000..b3300e61 --- /dev/null +++ b/build.zig @@ -0,0 +1,117 @@ +const std = @import("std"); +const proj = @import("project.zig"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const tier0 = tier0: { + const cpp = [_]proj.PlatformSrc{ + proj.PlatformSrc{ .data = &[_][]const u8{ + "assert_dialog.cpp", + "commandline.cpp", + "cpu.cpp", + "cpumonitoring.cpp", + "cpu_usage.cpp", + "dbg.cpp", + "dynfunction.cpp", + "fasttimer.cpp", + "mem.cpp", + "mem_helpers.cpp", + "memdbg.cpp", + "memstd.cpp", + "memvalidate.cpp", + "minidump.cpp", + "pch_tier0.cpp", + "progressbar.cpp", + "security.cpp", + "systeminformation.cpp", + "stacktools.cpp", + "threadtools.cpp", + "tier0_strtools.cpp", + "tslist.cpp", + "vprof.cpp", + "../tier1/pathmatch.cpp", + } }, + proj.PlatformSrc{ + .data = &[_][]const u8{ + "PMELib.cpp", + "thread.cpp", + "cpu_posix.cpp", + "platform_posix.cpp", + "pme_posix.cpp", + "vcrmode_posix.cpp", + }, + .spec = .{ .os = .{ + .posix = null, + } }, + }, + proj.PlatformSrc{ + .data = &[_][]const u8{ + "PMELib.cpp", + "thread.cpp", + "assert_dialog.rc", + // "etwprof.cpp", + "platform.cpp", + "pme.cpp", + "vcrmode.cpp", + "win32consoleio.cpp", + }, + .spec = .{ + .os = .{ .windows = @as(void, undefined) }, + }, + }, + }; + + const asm_att = [_]proj.PlatformSrc{proj.PlatformSrc{ + .data = &[_][]const u8{"InterlockedCompareExchange128.S"}, + .spec = .{ + .arch = .{ .amd64 = @as(void, undefined) }, + }, + }}; + + const macros = [_]proj.PlatformMacros{proj.PlatformMacros{ + .data = &[_]proj.Macro{ + proj.Macro{ .name = "TIER0_DLL_EXPORT" }, + }, + }}; + + break :tier0 proj.make_module(b, target, optimize, "tier0", .{ .use_sdl = true, .use_gl = true, .use_togles = true }, .shared, b.path("tier0"), &cpp, null, &asm_att, null, ¯os, null, null); + }; + + const vstdlib = vstdlib: { + const cpp = [_]proj.PlatformSrc{ + proj.PlatformSrc{ .data = &[_][]const u8{ "coroutine.cpp", "cvar.cpp", "jobthread.cpp", "KeyValuesSystem.cpp", "random.cpp", "vcover.cpp", "../public/tier0/memoverride.cpp" } }, + proj.PlatformSrc{ + .data = &[_][]const u8{"processutils.cpp"}, + .spec = .{ + .os = .{ .windows = @as(void, undefined) }, + }, + }, + }; + + const asm_att = [_]proj.PlatformSrc{proj.PlatformSrc{ + // TODO: at&t syntax + .data = &[_][]const u8{ "coroutine_win64.masm", "GetStackPtr64.masm" }, + .spec = .{ + .os = .{ .windows = @as(void, undefined) }, + .arch = .{ .amd64 = @as(void, undefined) }, + }, + }}; + + const macros = [_]proj.PlatformMacros{proj.PlatformMacros{ + .data = &[_]proj.Macro{ + proj.Macro{ .name = "VSTDLIB_DLL_EXPORT" }, + }, + }}; + + const incpaths = [_]proj.PlatformIncludePaths{ + proj.PlatformIncludePaths{ .data = &[_]proj.Path{b.path("../public/vstdlib")} }, + }; + + break :vstdlib proj.make_module(b, target, optimize, "vstdlib", .{ .use_sdl = true, .use_gl = true, .use_togles = true }, .shared, b.path("vstdlib"), &cpp, null, &asm_att, null, ¯os, &incpaths, null); + }; + + b.installArtifact(vstdlib); + b.installArtifact(tier0); +} diff --git a/progress.md b/progress.md new file mode 100644 index 00000000..955a998d --- /dev/null +++ b/progress.md @@ -0,0 +1,20 @@ +### done +- build a `tier0.so` from zig +- make build code generic +- build a `vstdlib.so` from zig +- pass correct cflags/ldflags/defines into the build (mostly) + +- - - + +### todo! +- build `tier1.a` +- work our way up to `engine.so` + +- - - + +### goals +- build more engine libraries +- get a working `hl2_launcher` exe +- see what we can do about hammer editor and its dll + +- - - diff --git a/project.zig b/project.zig new file mode 100644 index 00000000..07c0af13 --- /dev/null +++ b/project.zig @@ -0,0 +1,454 @@ +const std = @import("std"); + +pub const Macro = struct { name: []const u8, val: []const u8 = "" }; +pub const Path = std.Build.LazyPath; + +pub const Os = union(enum) { + posix: ?union(enum) { + other: ?std.Target.Os.Tag, + linux: void, + android: void, + bsd: ?union(enum) { + other: ?std.Target.Os.Tag, + darwin: void, + }, + }, + windows: void, + + // TODO: android + pub fn from(f: std.Target.Os.Tag) Os { + return switch (f) { + .linux => Os{ .posix = .{ .linux = @as(void, undefined) } }, + .windows => Os{ .windows = @as(void, undefined) }, + .netbsd, .openbsd, .freebsd, .dragonfly => Os{ .posix = .{ .bsd = .{ .other = f } } }, + .macos => Os{ .posix = .{ .bsd = .{ .darwin = @as(void, undefined) } } }, + else => unreachable, + }; + } + + pub fn filtered(this: Os, other: Os) bool { + return switch (this) { + .windows => switch (other) { + .windows => true, + else => false, + }, + .posix => |p0| switch (other) { + // .release => |r1| if (r1 == null or r0 == null) true else (r0.? == r1.?), + .posix => |p1| if (p0 == null or p1 == null) true else switch (p0.?) { + .linux => if (p1.? == .linux) true else false, + .android => if (p1.? == .android) true else false, + .bsd => |b0| if (b0 == null or p1.?.bsd == null) true else switch (p1.?.bsd.?) { + .darwin => if (b0.? == .darwin) true else false, + .other => |o0| if (o0 == null or p1.?.other == null) true else if (p1.? == .other and p1.?.other == o0.?) true else false, + }, + .other => |o0| if (o0 == null or p1.?.other == null) true else if (p1.? == .other and p1.?.other == o0.?) true else false, + }, + else => false, + }, + }; + } +}; + +pub const Arch = union(enum) { + amd64: void, + i386: void, + + pub fn filtered(this: Arch, other: Arch) bool { + return switch (this) { + .amd64 => (other == .amd64), + .i386 => (other == .i386), + }; + } + + pub fn from(f: std.Target.Cpu.Arch) Arch { + return switch (f) { + .x86_64 => Arch{ .amd64 = @as(void, undefined) }, + .x86 => Arch{ .i386 = @as(void, undefined) }, + else => unreachable, + }; + } +}; + +pub const Mode = union(enum) { + release: ?std.builtin.OptimizeMode, + debug: void, + + pub fn filtered(this: Mode, other: Mode) bool { + return switch (this) { + .debug => switch (other) { + .debug => true, + else => false, + }, + .release => |r0| switch (other) { + .debug => false, + .release => |r1| if (r1 == null or r0 == null) true else (r0.? == r1.?), + }, + }; + } + + pub fn from(f: std.builtin.OptimizeMode) Mode { + return switch (f) { + .Debug => Mode{ .debug = @as(void, undefined) }, + else => Mode{ .release = f }, + }; + } +}; + +pub const Api = union(enum) { + sdl: void, + gl: void, + togles: void, + + pub fn filtered(this: Api, other: Api) bool { + return switch (this) { + .sdl => switch (other) { + .sdl => true, + else => false, + }, + .gl => switch (other) { + .gl => true, + else => false, + }, + .togles => switch (other) { + .togles => true, + else => false, + }, + }; + } + + // pub fn from(from: Config) Api { + + // } +}; + +pub const Spec = struct { + os: ?Os = null, + arch: ?Arch = null, + mode: ?Mode = null, + api: ?Api = null, + + pub fn from(t: std.Build.ResolvedTarget, o: std.builtin.OptimizeMode, c: Config) Spec { + _ = c; + return Spec{ + .os = Os.from(t.result.os.tag), + .arch = Arch.from(t.result.cpu.arch), + .mode = Mode.from(o), + .api = null, + }; + } + + pub fn filtered(this: Spec, other: Spec) bool { + const os_match = if (this.os == null or other.os == null) true else this.os.?.filtered(other.os.?); + const arch_match = if (this.arch == null or other.arch == null) true else this.arch.?.filtered(other.arch.?); + const mode_match = if (this.mode == null or other.mode == null) true else this.mode.?.filtered(other.mode.?); + const api_match = if (this.api == null or other.api == null) true else this.api.?.filtered(other.api.?); + return os_match and arch_match and mode_match and api_match; + } +}; + +pub const PlatformSrc = struct { data: []const []const u8, spec: ?Spec = null }; +pub const PlatformLink = struct { data: []const []const u8, spec: ?Spec = null }; +pub const PlatformCflags = struct { data: []const []const u8, spec: ?Spec = null }; +pub const PlatformMacros = struct { data: []const Macro, spec: ?Spec = null }; +pub const PlatformIncludePaths = struct { data: []const Path, spec: ?Spec = null }; +pub const PlatformLinkPaths = struct { data: []const Path, spec: ?Spec = null }; + +pub const Config = struct { + use_sdl: bool, + use_gl: bool, + use_togles: bool, +}; + +pub const ModType = enum { + static, + shared, + exe, +}; + +pub fn make_module(b_: *std.Build, t_: std.Build.ResolvedTarget, o_: std.builtin.OptimizeMode, name_: []const u8, cfg_: Config, modtype_: ModType, mod_root_: ?Path, src_cpp_: []const PlatformSrc, cpp_flags_: ?[]const PlatformCflags, src_assembly_: ?[]const PlatformSrc, links_: ?[]const PlatformLink, macros_: ?[]const PlatformMacros, incpaths_: ?[]const PlatformIncludePaths, linkpaths_: ?[]const PlatformLinkPaths) *std.Build.Step.Compile { + const IPATH = [_]PlatformIncludePaths{ + PlatformIncludePaths{ .data = &[_]Path{ + b_.path("."), + b_.path("../thirdparty"), + b_.path("../"), + b_.path("../public"), + b_.path("../public/tier0"), + b_.path("../public/tier1"), + } }, + PlatformIncludePaths{ .data = &[_]Path{b_.path("../thirdparty/SDL")}, .spec = .{ .api = .{ .sdl = @as(void, undefined) } } }, + }; + + const LPATH = [_]PlatformLinkPaths{ + PlatformLinkPaths{ + .data = &[_]Path{b_.path("../thirdparty")}, + }, + }; + + const LINK = [_]PlatformLink{ PlatformLink{ .data = &[_][]const u8{ "dl", "bz2", "rt", "m" }, .spec = .{ .os = .{ + .posix = null, + } } }, PlatformLink{ .data = &[_][]const u8{ + "user32", + "shell32", + "gdi32", + "advapi32", + "dbghelp", + "psapi", + "ws2_32", + "rpcrt4", + "winmm", + "wininet", + "ole32", + "shlwapi", + "imm32", + }, .spec = .{ .os = .{ .windows = @as(void, undefined) } } } }; + + const MACROS = [_]PlatformMacros{ + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "GIT_COMMIT_HASH" }, + } }, + PlatformMacros{ + .data = &[_]Macro{ + Macro{ .name = "DEBUG" }, + // Macro{ .name = "_DEBUG" }, + }, + .spec = .{ + .mode = .{ .debug = @as(void, undefined) }, + }, + }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "NDEBUG" }, + }, .spec = .{ + .mode = .{ .release = null }, + } }, + PlatformMacros{ + .data = &[_]Macro{ + Macro{ .name = "POSIX", .val = "1" }, + Macro{ .name = "_POSIX", .val = "1" }, + Macro{ .name = "PLATFORM_POSIX", .val = "1" }, + Macro{ .name = "GNUC", .val = "1" }, + Macro{ .name = "NO_MEMOVERRIDE_NEW_DELETE", .val = "1" }, + // for darwin + Macro{ .name = "_DLL_EXT", .val = t_.result.os.tag.dynamicLibSuffix() }, + }, + .spec = .{ + .os = .{ .posix = null }, + }, + }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "LINUX", .val = "1" }, + Macro{ .name = "_LINUX", .val = "1" }, + Macro{ .name = "NO_HOOK_MALLOC", .val = "1" }, + }, .spec = .{ + .os = .{ .posix = .{ .linux = @as(void, undefined) } }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "PLATFORM_BSD", .val = "1" }, + }, .spec = .{ + .os = .{ .posix = .{ .bsd = null } }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "OSX", .val = "1" }, + Macro{ .name = "_OSX", .val = "1" }, + Macro{ + .name = "NO_HOOK_MALLOC", + }, + }, .spec = .{ + .os = .{ .posix = .{ .bsd = .{ .darwin = @as(void, undefined) } } }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "WIN32", .val = "1" }, + Macro{ .name = "_WIN32", .val = "1" }, + Macro{ + .name = "_WINDOWS", + }, + Macro{ + .name = "_CRT_SECURE_NO_DEPRECATE", + }, + Macro{ + .name = "_CRT_NONSTDC_NO_DEPRECATE", + }, + Macro{ + .name = "_ALLOW_RUNTIME_LIBRARY_MISMATCH", + }, + Macro{ + .name = "_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH", + }, + Macro{ + .name = "_ALLOW_MSC_VER_MISMATCH", + }, + Macro{ + .name = "NO_X360_XDK", + }, + Macro{ .name = "_DLL_EXT", .val = ".dll" }, + }, .spec = .{ + .os = .{ .windows = @as(void, undefined) }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "PLATFORM_64BITS", .val = "1" }, + }, .spec = .{ + .arch = .{ .amd64 = @as(void, undefined) }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ .name = "USE_SDL", .val = "1" }, + }, .spec = .{ + .api = .{ .sdl = @as(void, undefined) }, + } }, + PlatformMacros{ .data = &[_]Macro{ + Macro{ + .name = "DX_TO_GL_ABSTRACTION", + }, + Macro{ + .name = "GL_GLEXT_PROTOTYPES", + }, + Macro{ + .name = "BINK_VIDEO", + }, + }, .spec = .{ + .api = .{ .gl = @as(void, undefined) }, + } }, + PlatformMacros{ .data = &[_]Macro{Macro{ .name = "TOGLES" }}, .spec = .{ + .api = .{ .togles = @as(void, undefined) }, + } }, + }; + + const FLAGS = [_]PlatformCflags{ + PlatformCflags{ + .data = &[_][]const u8{ + "-std=c++11", + "-fpermissive", + }, + }, + PlatformCflags{ .data = &[_][]const u8{ "-Og", "-ggdb" }, .spec = .{ + .mode = .{ .debug = @as(void, undefined) }, + } }, + PlatformCflags{ .data = &[_][]const u8{ + "-Ofast", + }, .spec = .{ + .mode = .{ .release = .ReleaseFast }, + } }, + PlatformCflags{ .data = &[_][]const u8{ + "-O3", + }, .spec = .{ + .mode = .{ .release = .ReleaseSafe }, + } }, + PlatformCflags{ .data = &[_][]const u8{ + "-Os", + }, .spec = .{ + .mode = .{ .release = .ReleaseSmall }, + } }, + }; + + const root = if (mod_root_) |r| r else b_.path("."); + + var cxxsrc = std.ArrayList([]const u8).init(b_.allocator); + var asmsrc = std.ArrayList([]const u8).init(b_.allocator); + var cflags = std.ArrayList([]const u8).init(b_.allocator); + var macros = std.ArrayList(Macro).init(b_.allocator); + var links = std.ArrayList([]const u8).init(b_.allocator); + var ipaths = std.ArrayList(Path).init(b_.allocator); + var lpaths = std.ArrayList(Path).init(b_.allocator); + + defer { + macros.deinit(); + links.deinit(); + cxxsrc.deinit(); + asmsrc.deinit(); + cflags.deinit(); + lpaths.deinit(); + ipaths.deinit(); + } + + const spec = Spec.from(t_, o_, cfg_); + + const fns = struct { + pub fn walk(sp: Spec, T: type, I: type, list: []const T, arr: *std.ArrayList(I)) void { + for (list) |item| { + if (@field(item, "spec") == null or sp.filtered(@field(item, "spec").?)) { + arr.appendSlice(@field(item, "data")) catch unreachable; + } + } + } + }; + + // defaults + fns.walk(spec, PlatformIncludePaths, Path, &IPATH, &ipaths); + fns.walk(spec, PlatformLinkPaths, Path, &LPATH, &lpaths); + fns.walk(spec, PlatformLink, []const u8, &LINK, &links); + fns.walk(spec, PlatformMacros, Macro, &MACROS, ¯os); + fns.walk(spec, PlatformCflags, []const u8, &FLAGS, &cflags); + + // for this module + if (incpaths_) |ip| { + fns.walk(spec, PlatformIncludePaths, Path, ip, &ipaths); + } + if (linkpaths_) |lp| { + fns.walk(spec, PlatformLinkPaths, Path, lp, &lpaths); + } + if (links_) |l| { + fns.walk(spec, PlatformLink, []const u8, l, &links); + } + if (macros_) |m| { + fns.walk(spec, PlatformMacros, Macro, m, ¯os); + } + if (cpp_flags_) |f| { + fns.walk(spec, PlatformCflags, []const u8, f, &cflags); + } + if (src_assembly_) |a| { + fns.walk(spec, PlatformSrc, []const u8, a, &asmsrc); + } + fns.walk(spec, PlatformSrc, []const u8, src_cpp_, &cxxsrc); + + const mod = b_.addModule(name_, .{ + .target = t_, + .optimize = o_, + .link_libcpp = true, + .link_libc = true, + }); + + const compile = switch (modtype_) { + .static => b_.addLibrary(.{ + .name = name_, + .root_module = mod, + .linkage = .static, + }), + .shared => b_.addLibrary(.{ + .name = name_, + .root_module = mod, + .linkage = .dynamic, + }), + .exe => b_.addExecutable(.{ + .root_module = mod, + .name = name_, + .link_libc = true, + }), + }; + compile.linkLibC(); + compile.linkLibCpp(); + + for (macros.items) |d| { + mod.addCMacro(d.name, d.val); + } + + for (ipaths.items) |i| { + mod.addIncludePath(root.join(b_.allocator, i.src_path.sub_path) catch unreachable); + } + + for (lpaths.items) |lp| { + mod.addLibraryPath(root.join(b_.allocator, lp.src_path.sub_path) catch unreachable); + } + + for (links.items) |l| { + mod.linkSystemLibrary(l, .{}); + } + + mod.addCSourceFiles(.{ + .files = cxxsrc.items, + .flags = cflags.items, + .root = root, + .language = .cpp, + }); + + mod.addCSourceFiles(.{ .files = asmsrc.items, .root = root, .language = .assembly }); + + return compile; +} diff --git a/public/tier0/platform.h b/public/tier0/platform.h index 73047e1b..3d055c05 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -159,7 +159,7 @@ #else #define IsLinux() false #endif - + #if defined( OSX ) #define IsOSX() true #else @@ -420,7 +420,7 @@ typedef void * HINSTANCE; #endif // defined(_WIN32) && !defined(WINDED) -#define MAX_FILEPATH 512 +#define MAX_FILEPATH 512 // Defines MAX_PATH #ifndef MAX_PATH @@ -504,7 +504,7 @@ typedef void * HINSTANCE; #ifdef _WIN32 #define DECL_ALIGN(x) __declspec(align(x)) -#elif GNUC +#elif defined GNUC #define DECL_ALIGN(x) __attribute__((aligned(x))) #else #define DECL_ALIGN(x) /* */ @@ -526,7 +526,7 @@ typedef void * HINSTANCE; #elif defined( GNUC ) // gnuc has the align decoration at the end #define ALIGN4 -#define ALIGN8 +#define ALIGN8 #define ALIGN16 #define ALIGN32 #define ALIGN128 @@ -674,7 +674,7 @@ typedef void * HINSTANCE; #define STDCALL __stdcall #ifdef FORCEINLINE #undef FORCEINLINE -#endif +#endif #define FORCEINLINE __forceinline #define FORCEINLINE_TEMPLATE __forceinline #else @@ -982,7 +982,7 @@ template inline T QWordSwapC( T dw ) { // Assert sizes passed to this are already correct, otherwise - // the cast to uint64 * below is unsafe and may have wrong results + // the cast to uint64 * below is unsafe and may have wrong results // or even crash. PLAT_COMPILE_TIME_ASSERT( sizeof( dw ) == sizeof(uint64) ); @@ -1202,7 +1202,7 @@ FORCEINLINE void StoreLittleDWord( uint32 *base, unsigned int dwordIndex, uint32 // // It should not be changed after startup unless you really know what you're doing. The only place // that should do this is the benchmark code itself so it can output a legit duration. -PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode ); +PLATFORM_INTERFACE void Plat_SetBenchmarkMode( bool bBenchmarkMode ); PLATFORM_INTERFACE bool Plat_IsInBenchmarkMode(); @@ -1326,7 +1326,7 @@ struct MemoryInformation uint m_nPhysicalRamMbTotal; uint m_nPhysicalRamMbAvailable; - + uint m_nVirtualRamMbTotal; uint m_nVirtualRamMbAvailable; diff --git a/public/tier1/utlblockmemory.h b/public/tier1/utlblockmemory.h index 35ef2da2..d6028dab 100644 --- a/public/tier1/utlblockmemory.h +++ b/public/tier1/utlblockmemory.h @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -137,10 +137,28 @@ CUtlBlockMemory::~CUtlBlockMemory() template< class T, class I > void CUtlBlockMemory::Swap( CUtlBlockMemory< T, I > &mem ) { - this->swap( m_pMemory, mem.m_pMemory ); - this->swap( m_nBlocks, mem.m_nBlocks ); - this->swap( m_nIndexMask, mem.m_nIndexMask ); - this->swap( m_nIndexShift, mem.m_nIndexShift ); + // valb - not a member?? + // this->swap( m_pMemory, mem.m_pMemory ); + // this->swap( m_nBlocks, mem.m_nBlocks ); + // this->swap( m_nIndexMask, mem.m_nIndexMask ); + // this->swap( m_nIndexShift, mem.m_nIndexShift ); + + // let's see if this breaks everything! + auto mem_tmp = m_pMemory; + m_pMemory = mem.m_pMemory; + mem.m_pMemory = mem_tmp; + + auto blk_tmp = m_nBlocks; + m_nBlocks = mem.m_nBlocks; + mem.m_nBlocks = mem_tmp; + + auto im_tmp = m_nIndexMask; + m_nIndexMask = mem.m_nIndexMask; + mem.m_nIndexMask = mem_tmp; + + auto is_tmp = m_nIndexShift; + m_nIndexShift = mem.m_nIndexShift; + mem.m_nIndexShift = mem_tmp; } diff --git a/tier0/InterlockedCompareExchange128.S b/tier0/InterlockedCompareExchange128.S new file mode 100644 index 00000000..a77bdb2c --- /dev/null +++ b/tier0/InterlockedCompareExchange128.S @@ -0,0 +1,46 @@ +// call cpuid with args in eax, ecx +// store eax, ebx, ecx, edx to p + +.section .text +_InterlockedCompareExchange128: + // fastcall conventions: + // RCX = Destination + // RDX = Exchange High + // R8 = Exchange Lo + // R9 = ComparandResult + + // CMPXCHG16B refernece: + // http://download.intel.com/design/processor/manuals/253666.pdf + + // Stash RBX in R11 + movq %rbx, %r11 + + // Destination ptr to r10 + movq %rcx, %r10 + + // RCX:RBX Exchange + movq %rdx, %rcx + movq %r8, %rbx + + // RDX:RAX Comparand + movq (%r9), %rax + movq 8(%r9), %rdx + + // Do the atomic operation + lock + cmpxchg16b (%r10) + + // RDX:RAX now contains the value of the destination, before the atomic operation. + // (Either it already matched and was not changed, or it did not match, in which case + // the value has been loaded into RDX:RAX.) The _InterlockedCompareExchange128 intrinsic + // semantics specify that this is always written out to CompareResult, so give it + // back to the caller. + movq %rax, (%r9) + movq %rdx, 8(%r9) + + // Return value is in AL, set it equal to the zero flag + setz %al + + // Restore RBX and get out + movq %r11, %rbx + ret \ No newline at end of file diff --git a/tier0/dbg.cpp b/tier0/dbg.cpp index 84da0471..e77169f3 100644 --- a/tier0/dbg.cpp +++ b/tier0/dbg.cpp @@ -1,6 +1,6 @@ //========= Copyright Valve Corporation, All rights reserved. ============// // -// Purpose: +// Purpose: // // $NoKeywords: $ // @@ -118,8 +118,8 @@ void CDbgLogger::Init(const char *logfile) #ifdef GNUC fprintf(file, "Compiler version: %s\n", __VERSION__); #endif - fprintf(file, "Compiler CFLAGS: %s\n", WAF_CFLAGS); - fprintf(file, "Compiler LDFLAGS: %s\n", WAF_LDFLAGS); + // fprintf(file, "Compiler CFLAGS: %s\n", WAF_CFLAGS); + // fprintf(file, "Compiler LDFLAGS: %s\n", WAF_LDFLAGS); fflush(file); for( int i = 0; i < iMsg; i++ ) @@ -185,7 +185,7 @@ IDbgLogger *DebugLogger() { return &g_DbgLogger; } //----------------------------------------------------------------------------- enum { - MAX_GROUP_NAME_LENGTH = 48 + MAX_GROUP_NAME_LENGTH = 48 }; struct SpewGroup_t @@ -431,7 +431,7 @@ static SpewRetval_t _SpewMessage( SpewType_t spewType, const char *pGroupName, i // Add \n for warning and assert if ( spewType == SPEW_ASSERT ) { - len += _stprintf( &pTempBuffer[len], _T("\n") ); + len += _stprintf( &pTempBuffer[len], _T("\n") ); } assert( len < sizeof(pTempBuffer)/sizeof(pTempBuffer[0]) - 1 ); /* use normal assert here; to avoid recursion. */ @@ -465,7 +465,7 @@ static SpewRetval_t _SpewMessage( SpewType_t spewType, const char *pGroupName, i DebuggerBreak(); } break; - + case SPEW_ABORT: { // MessageBox(NULL,"Error in _SpewMessage","Error",MB_OK); @@ -668,8 +668,8 @@ void ErrorV( PRINTF_FORMAT_STRING const tchar *pMsg, va_list arglist ) } //----------------------------------------------------------------------------- -// A couple of super-common dynamic spew messages, here for convenience -// These looked at the "developer" group, print if it's level 1 or higher +// A couple of super-common dynamic spew messages, here for convenience +// These looked at the "developer" group, print if it's level 1 or higher //----------------------------------------------------------------------------- void DevMsg( int level, const tchar* pMsgFormat, ... ) { @@ -739,8 +739,8 @@ void DevLog( const tchar *pMsgFormat, ... ) //----------------------------------------------------------------------------- -// A couple of super-common dynamic spew messages, here for convenience -// These looked at the "console" group, print if it's level 1 or higher +// A couple of super-common dynamic spew messages, here for convenience +// These looked at the "console" group, print if it's level 1 or higher //----------------------------------------------------------------------------- void ConColorMsg( int level, const Color& clr, const tchar* pMsgFormat, ... ) { @@ -877,8 +877,8 @@ void ConDLog( const tchar *pMsgFormat, ... ) //----------------------------------------------------------------------------- -// A couple of super-common dynamic spew messages, here for convenience -// These looked at the "network" group, print if it's level 1 or higher +// A couple of super-common dynamic spew messages, here for convenience +// These looked at the "network" group, print if it's level 1 or higher //----------------------------------------------------------------------------- void NetMsg( int level, const tchar* pMsgFormat, ... ) { @@ -922,14 +922,14 @@ void NetLog( int level, const tchar *pMsgFormat, ... ) void SpewActivate( const tchar* pGroupName, int level ) { Assert( pGroupName ); - + // check for the default group first... if ((pGroupName[0] == '*') && (pGroupName[1] == '\0')) { s_DefaultLevel = level; return; } - + // Normal case, search in group list using binary search. // If not found, grow the list of groups and insert it into the // right place to maintain sorted order. Then set the level. @@ -940,17 +940,17 @@ void SpewActivate( const tchar* pGroupName, int level ) ++s_GroupCount; if ( s_pSpewGroups ) { - s_pSpewGroups = (SpewGroup_t*)PvRealloc( s_pSpewGroups, + s_pSpewGroups = (SpewGroup_t*)PvRealloc( s_pSpewGroups, s_GroupCount * sizeof(SpewGroup_t) ); - + // shift elements down to preserve order int numToMove = s_GroupCount - ind - 1; - memmove( &s_pSpewGroups[ind+1], &s_pSpewGroups[ind], + memmove( &s_pSpewGroups[ind+1], &s_pSpewGroups[ind], numToMove * sizeof(SpewGroup_t) ); // Update standard groups for ( int i = 0; i < GROUP_COUNT; ++i ) - { + { if ( ( ind <= s_pGroupIndices[i] ) && ( s_pGroupIndices[i] >= 0 ) ) { ++s_pGroupIndices[i]; @@ -959,9 +959,9 @@ void SpewActivate( const tchar* pGroupName, int level ) } else { - s_pSpewGroups = (SpewGroup_t*)PvAlloc( s_GroupCount * sizeof(SpewGroup_t) ); + s_pSpewGroups = (SpewGroup_t*)PvAlloc( s_GroupCount * sizeof(SpewGroup_t) ); } - + Assert( _tcslen( pGroupName ) < MAX_GROUP_NAME_LENGTH ); _tcscpy( s_pSpewGroups[ind].m_GroupName, pGroupName ); @@ -1008,8 +1008,8 @@ void ValidateSpew( CValidator &validator ) //----------------------------------------------------------------------------- // Purpose: For debugging startup times, etc. -// Input : *fmt - -// ... - +// Input : *fmt - +// ... - //----------------------------------------------------------------------------- void COM_TimestampedLog( char const *fmt, ... ) { diff --git a/wscript b/wscript index 16f2263b..632eeb61 100644 --- a/wscript +++ b/wscript @@ -27,14 +27,14 @@ int main() { return (int)FcInit(); } ''' CPP_64BIT_CHECK=''' -#define TEST(a) (sizeof(void*) == a ? 1 : -1) +#define TEST(a) (sizeof(void*) == a ? 1 : -1) int g_Test[TEST(8)]; int main () { return 0; } ''' CPP_32BIT_CHECK=''' -#define TEST(a) (sizeof(void*) == a ? 1 : -1) +#define TEST(a) (sizeof(void*) == a ? 1 : -1) int g_Test[TEST(4)]; int main () { return 0; } @@ -236,7 +236,7 @@ def define_platform(conf): 'NO_HOOK_MALLOC', '_DLL_EXT=.so' ]) - + elif conf.env.DEST_OS == 'win32': conf.env.append_unique('DEFINES', [ 'WIN32=1', '_WIN32=1',