initial import
diff --git a/src/utils/flactimer/flactimer.dsp b/src/utils/flactimer/flactimer.dsp
new file mode 100644
index 0000000..897d945
--- /dev/null
+++ b/src/utils/flactimer/flactimer.dsp
@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="flactimer" - Package Owner=<4>

+# Microsoft Developer Studio Generated Build File, Format Version 6.00

+# ** DO NOT EDIT **

+

+# TARGTYPE "Win32 (x86) Console Application" 0x0103

+

+CFG=flactimer - Win32 Debug

+!MESSAGE This is not a valid makefile. To build this project using NMAKE,

+!MESSAGE use the Export Makefile command and run

+!MESSAGE 

+!MESSAGE NMAKE /f "flactimer.mak".

+!MESSAGE 

+!MESSAGE You can specify a configuration when running NMAKE

+!MESSAGE by defining the macro CFG on the command line. For example:

+!MESSAGE 

+!MESSAGE NMAKE /f "flactimer.mak" CFG="flactimer - Win32 Debug"

+!MESSAGE 

+!MESSAGE Possible choices for configuration are:

+!MESSAGE 

+!MESSAGE "flactimer - Win32 Release" (based on "Win32 (x86) Console Application")

+!MESSAGE "flactimer - Win32 Debug" (based on "Win32 (x86) Console Application")

+!MESSAGE 

+

+# Begin Project

+# PROP AllowPerConfigDependencies 0

+# PROP Scc_ProjName ""

+# PROP Scc_LocalPath ""

+CPP=cl.exe

+RSC=rc.exe

+

+!IF  "$(CFG)" == "flactimer - Win32 Release"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 0

+# PROP BASE Output_Dir "Release"

+# PROP BASE Intermediate_Dir "Release"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 0

+# PROP Output_Dir "..\..\..\obj\release\bin"

+# PROP Intermediate_Dir "Release"

+# PROP Ignore_Export_Lib 0

+# PROP Target_Dir ""

+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c

+# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c

+# SUBTRACT CPP /YX /Yc /Yu

+# ADD BASE RSC /l 0x409 /d "NDEBUG"

+# ADD RSC /l 0x409 /d "NDEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386

+# ADD LINK32 /nologo /subsystem:console /machine:I386

+

+!ELSEIF  "$(CFG)" == "flactimer - Win32 Debug"

+

+# PROP BASE Use_MFC 0

+# PROP BASE Use_Debug_Libraries 1

+# PROP BASE Output_Dir "Debug"

+# PROP BASE Intermediate_Dir "Debug"

+# PROP BASE Target_Dir ""

+# PROP Use_MFC 0

+# PROP Use_Debug_Libraries 1

+# PROP Output_Dir "..\..\..\obj\debug\bin"

+# PROP Intermediate_Dir "Debug"

+# PROP Ignore_Export_Lib 0

+# PROP Target_Dir ""

+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c

+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c

+# SUBTRACT CPP /YX /Yc /Yu

+# ADD BASE RSC /l 0x409 /d "_DEBUG"

+# ADD RSC /l 0x409 /d "_DEBUG"

+BSC32=bscmake.exe

+# ADD BASE BSC32 /nologo

+# ADD BSC32 /nologo

+LINK32=link.exe

+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept

+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept

+

+!ENDIF 

+

+# Begin Target

+

+# Name "flactimer - Win32 Release"

+# Name "flactimer - Win32 Debug"

+# Begin Group "Source Files"

+

+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"

+# Begin Source File

+

+SOURCE=.\main.cpp

+# End Source File

+# End Group

+# Begin Group "Header Files"

+

+# PROP Default_Filter "h;hpp;hxx;hm;inl"

+# End Group

+# End Target

+# End Project

diff --git a/src/utils/flactimer/flactimer.vcproj b/src/utils/flactimer/flactimer.vcproj
new file mode 100644
index 0000000..63603bb
--- /dev/null
+++ b/src/utils/flactimer/flactimer.vcproj
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="Windows-1252"?>

+<VisualStudioProject

+	ProjectType="Visual C++"

+	Version="8.00"

+	Name="flactimer"

+	ProjectGUID="{4cefbc94-c215-11db-8314-0800200c9a66}"

+	RootNamespace="flactimer"

+	Keyword="Win32Proj"

+	>

+	<Platforms>

+		<Platform

+			Name="Win32"

+		/>

+	</Platforms>

+	<ToolFiles>

+	</ToolFiles>

+	<Configurations>

+		<Configuration

+			Name="Debug|Win32"

+			OutputDirectory="..\..\..\obj\debug\bin"

+			IntermediateDirectory="Debug"

+			ConfigurationType="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				Optimization="0"

+				AdditionalIncludeDirectories="."

+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DEBUG"

+				MinimalRebuild="true"

+				BasicRuntimeChecks="3"

+				RuntimeLibrary="1"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="4"

+				DisableSpecificWarnings="4267;4996"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="2"

+				IgnoreDefaultLibraryNames="uuid.lib"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+		<Configuration

+			Name="Release|Win32"

+			OutputDirectory="..\..\..\obj\release\bin"

+			IntermediateDirectory="Release"

+			ConfigurationType="1"

+			>

+			<Tool

+				Name="VCPreBuildEventTool"

+			/>

+			<Tool

+				Name="VCCustomBuildTool"

+			/>

+			<Tool

+				Name="VCXMLDataGeneratorTool"

+			/>

+			<Tool

+				Name="VCWebServiceProxyGeneratorTool"

+			/>

+			<Tool

+				Name="VCMIDLTool"

+			/>

+			<Tool

+				Name="VCCLCompilerTool"

+				EnableIntrinsicFunctions="true"

+				FavorSizeOrSpeed="1"

+				OmitFramePointers="true"

+				WholeProgramOptimization="true"

+				AdditionalIncludeDirectories="."

+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

+				RuntimeLibrary="0"

+				BufferSecurityCheck="false"

+				UsePrecompiledHeader="0"

+				WarningLevel="3"

+				Detect64BitPortabilityProblems="true"

+				DebugInformationFormat="3"

+				DisableSpecificWarnings="4267;4996"

+			/>

+			<Tool

+				Name="VCManagedResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCResourceCompilerTool"

+			/>

+			<Tool

+				Name="VCPreLinkEventTool"

+			/>

+			<Tool

+				Name="VCLinkerTool"

+				LinkIncremental="1"

+				IgnoreDefaultLibraryNames="uuid.lib"

+				GenerateDebugInformation="true"

+				SubSystem="1"

+				OptimizeReferences="2"

+				EnableCOMDATFolding="2"

+				LinkTimeCodeGeneration="1"

+				TargetMachine="1"

+			/>

+			<Tool

+				Name="VCALinkTool"

+			/>

+			<Tool

+				Name="VCManifestTool"

+			/>

+			<Tool

+				Name="VCXDCMakeTool"

+			/>

+			<Tool

+				Name="VCBscMakeTool"

+			/>

+			<Tool

+				Name="VCFxCopTool"

+			/>

+			<Tool

+				Name="VCAppVerifierTool"

+			/>

+			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

+				Name="VCPostBuildEventTool"

+			/>

+		</Configuration>

+	</Configurations>

+	<References>

+	</References>

+	<Files>

+		<Filter

+			Name="Header Files"

+			Filter="h;hpp;hxx;hm;inl;inc;xsd"

+			UniqueIdentifier="{93993580-89BD-4b04-88EB-625FBE52EBFB}"

+			>

+		</Filter>

+		<Filter

+			Name="Source Files"

+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"

+			UniqueIdentifier="{4CF737F1-C7A5-4376-A066-2A32D752A2FF}"

+			>

+			<File

+				RelativePath=".\main.cpp"

+				>

+			</File>

+		</Filter>

+	</Files>

+	<Globals>

+	</Globals>

+</VisualStudioProject>

diff --git a/src/utils/flactimer/main.cpp b/src/utils/flactimer/main.cpp
new file mode 100644
index 0000000..a8cd9ca
--- /dev/null
+++ b/src/utils/flactimer/main.cpp
@@ -0,0 +1,171 @@
+/* flactimer - Runs a command and prints timing information
+ * Copyright (C) 2007  Josh Coalson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <windows.h>
+
+#define int64_t __int64
+#define uint64_t unsigned int64_t
+
+static inline uint64_t time2nsec(const FILETIME &t)
+{
+	uint64_t n = t.dwHighDateTime;
+	n <<= 32;
+	n |= (uint64_t)t.dwLowDateTime;
+	return n * 100;
+}
+
+static void printtime(FILE *fout, uint64_t nsec, uint64_t total)
+{
+	unsigned pct = (unsigned)(100.0 * ((double)(int64_t)nsec / (double)(int64_t)total));
+	uint64_t msec = nsec / 1000000; nsec -= msec * 1000000;
+	uint64_t sec = msec / 1000; msec -= sec * 1000;
+	uint64_t min = sec / 60; sec -= min * 60;
+	uint64_t hour = min / 60; min -= hour * 60;
+	fprintf(fout, " %5u.%03u = %02u:%02u:%02u.%03u = %3u%%\n",
+		(unsigned)((hour*60+min)*60+sec),
+		(unsigned)msec,
+		(unsigned)hour,
+		(unsigned)min,
+		(unsigned)sec,
+		(unsigned)msec,
+		pct
+	);
+}
+
+int main(int argc, char *argv[])
+{
+	const char *usage = "usage: flactimer [-1 | -2 | -o outputfile] command\n";
+	FILE *fout = stderr;
+
+	if(argc == 1 || (argc > 1 && 0 == strcmp(argv[1], "-h"))) {
+		fprintf(stderr, usage);
+		return 0;
+	}
+	argv++;
+	argc--;
+	if(0 == strcmp(argv[0], "-1") || 0 == strcmp(argv[0], "/1")) {
+		fout = stdout;
+		argv++;
+		argc--;
+	}
+	else if(0 == strcmp(argv[0], "-2") || 0 == strcmp(argv[0], "/2")) {
+		fout = stdout;
+		argv++;
+		argc--;
+	}
+	else if(0 == strcmp(argv[0], "-o")) {
+		if(argc < 2) {
+			fprintf(stderr, usage);
+			return 1;
+		}
+		fout = fopen(argv[1], "w");
+		if(!fout) {
+			fprintf(fout, "ERROR opening file %s for writing\n", argv[1]);
+			return 1;
+		}
+		argv += 2;
+		argc -= 2;
+	}
+	if(argc <= 0) {
+		fprintf(fout, "ERROR, no command!\n\n");
+		fprintf(fout, usage);
+		fclose(fout);
+		return 1;
+	}
+
+	// improvement: double-quote all args
+	int i, n = 0;
+	for(i = 0; i < argc; i++) {
+		if(i > 0)
+			n++;
+		n += strlen(argv[i]);
+	}
+	char *args = (char*)malloc(n+1);
+	if(!args) {
+		fprintf(fout, "ERROR, no memory\n");
+		fclose(fout);
+		return 1;
+	}
+	args[0] = '\0';
+	for(i = 0; i < argc; i++) {
+		if(i > 0)
+			strcat(args, " ");
+		strcat(args, argv[i]);
+	}
+
+	//fprintf(stderr, "@@@@@@ cmd=[%s] args=[%s]\n", argv[0], args);
+
+	STARTUPINFO si;
+	GetStartupInfo(&si);
+
+	DWORD wallclock_msec = GetTickCount();
+
+	PROCESS_INFORMATION pi;
+	BOOL ok = CreateProcess(
+		argv[0], // lpApplicationName
+		args, // lpCommandLine
+		NULL, // lpProcessAttributes
+		NULL, // lpThreadAttributes
+		FALSE, // bInheritHandles
+		0, // dwCreationFlags
+		NULL, // lpEnvironment
+		NULL, // lpCurrentDirectory
+		&si, // lpStartupInfo (inherit from this proc?)
+		&pi // lpProcessInformation
+	);
+
+	if(!ok) {
+		fprintf(fout, "ERROR running command\n");
+		free(args); //@@@ ok to free here or have to wait to wait till process is reaped?
+		fclose(fout);
+		return 1;
+	}
+
+	//fprintf(stderr, "@@@@@@ waiting...\n");
+	WaitForSingleObject(pi.hProcess, INFINITE);
+	//fprintf(stderr, "@@@@@@ done\n");
+
+	wallclock_msec = GetTickCount() - wallclock_msec;
+
+	FILETIME creation_time;
+	FILETIME exit_time;
+	FILETIME kernel_time;
+	FILETIME user_time;
+	if(!GetProcessTimes(pi.hProcess, &creation_time, &exit_time, &kernel_time, &user_time)) {
+		fprintf(fout, "ERROR getting time info\n");
+		free(args); //@@@ ok to free here or have to wait to wait till process is reaped?
+		fclose(fout);
+		return 1;
+	}
+	uint64_t kernel_nsec = time2nsec(kernel_time);
+	uint64_t user_nsec = time2nsec(user_time);
+
+	fprintf(fout, "Kernel Time  = "); printtime(fout, kernel_nsec, (uint64_t)wallclock_msec * 1000000);
+	fprintf(fout, "User Time    = "); printtime(fout, user_nsec, (uint64_t)wallclock_msec * 1000000);
+	fprintf(fout, "Process Time = "); printtime(fout, kernel_nsec+user_nsec, (uint64_t)wallclock_msec * 1000000);
+	fprintf(fout, "Global Time  = "); printtime(fout, (uint64_t)wallclock_msec * 1000000, (uint64_t)wallclock_msec * 1000000);
+
+	CloseHandle(pi.hThread);
+	CloseHandle(pi.hProcess);
+
+	free(args); //@@@ always causes crash, maybe CreateProcess takes ownership?
+	fclose(fout);
+	return 0;
+}