diff --git a/source/tharsis/prof/accumulatedzonerange.d b/source/tharsis/prof/accumulatedzonerange.d index 05f86cb..e309526 100644 --- a/source/tharsis/prof/accumulatedzonerange.d +++ b/source/tharsis/prof/accumulatedzonerange.d @@ -105,7 +105,7 @@ auto accumulatedZoneRange(alias accumulate, alias match = defaultMatch, ZRange) @trusted pure nothrow @nogc { static assert(isForwardRange!ZRange && is(Unqual!(ElementType!ZRange) == ZoneData), - "ZRange parameter of accumulatedZoneRange must be a forward range of " + "ZRange parameter of accumulatedZoneRange must be a forward range of " ~ "ZoneData, e.g. ZoneRange"); debug { @@ -113,7 +113,7 @@ auto accumulatedZoneRange(alias accumulate, alias match = defaultMatch, ZRange) foreach(ref zoneRange; zones) { zoneCount += zoneRange.save.walkLength; } assert(storage.length >= zoneCount, - "storage param of accumulatedZoneRange must be long enough to hold zones " + "storage param of accumulatedZoneRange must be long enough to hold zones " ~ "from all passed zone ranges"); } alias AccumulatedZone = AccumulatedZoneData!accumulate; diff --git a/source/tharsis/prof/despikersender.d b/source/tharsis/prof/despikersender.d index 2431fd3..00ad23e 100644 --- a/source/tharsis/prof/despikersender.d +++ b/source/tharsis/prof/despikersender.d @@ -43,7 +43,7 @@ class DespikerSenderException : Exception * for(;;) * { * // Despiker will consider code in this zone (named "frame") a part of a single frame. - * // Which zone is considered a frame can be changed by setting the + * // Which zone is considered a frame can be changed by setting the * // sender.frameFilter property. * auto frame = Zone(profiler, "frame"); * @@ -72,7 +72,7 @@ class DespikerSender private: /* Profilers we're sending data from. * - * Despiker assumes that each profiler is used to profile a separate thread + * Despiker assumes that each profiler is used to profile a separate thread * (profilers_[0] - thread 0, profilers_[1] - thread 1, etc.). */ Profiler[] profilers_; @@ -85,7 +85,7 @@ private: ProcessPipes despikerPipes_; /* Storage for bytesSentPerProfiler. - * + * * Using a fixed-size array for simplest/fastest allocation. 8kiB is acceptable but * right at the edge of being acceptable... if we ever increase maxProfilers above * 1024, we should use malloc. @@ -110,7 +110,7 @@ public: * * Despiker will show results from passed profilers side-by-side, matching their * 'frame' zones. To get meaningful results, all profilers should start profiling - * at the same time and have one 'frame' zone for each frame of the profiled + * at the same time and have one 'frame' zone for each frame of the profiled * game/program. * * The main use of multiple profilers is to profile code in multiple threads @@ -231,11 +231,11 @@ public: } throw new DespikerSenderException - ("Failed to start Despiker.\n " + ("Failed to start Despiker.\n " ~ "Tried to look for it in:\n " ~ defaultPath is null ? "" : "0: path provided by caller: '%s'\n".format(defaultPath) ~ - "1: working directory, 2: directory of the running binary, 3: PATH.\n" + "1: working directory, 2: directory of the running binary, 3: PATH.\n" ~ "Got errors:\n" ~ errorStrings.join("\n")); } @@ -247,7 +247,7 @@ public: void reset() @trusted nothrow @nogc { sending_ = false; - // Not @nogc yet, although ProcessPipes destruction should not use GC. + // Not @nogc yet, although ProcessPipes destruction should not use GC. // Probably don't need to explicitly destroy this here anyway. // destroy(despikerPipes_).assumeWontThrow; bytesSentPerProfiler_[] = 0; diff --git a/source/tharsis/prof/event.d b/source/tharsis/prof/event.d index 5c67d74..e0546aa 100644 --- a/source/tharsis/prof/event.d +++ b/source/tharsis/prof/event.d @@ -146,13 +146,27 @@ struct Event return info_; } + // Set the info string if this is an Info event. + package void info(const(char)[] str) @trusted pure nothrow @nogc + { + assert(id == EventID.Info, "Can't set info if it's not an Info event"); + info_ = str; + } + + // Reset the union { info_, var_ }, no matter what type of event this is. + // Needed in tharsis.prof.ranges because one Event is reused several times. + package void resetInfo() @trusted pure nothrow @nogc + { + info_ = null; + } + Variable var() @trusted pure nothrow const @nogc { assert(id == EventID.Variable, "Can't access variable if it's not a Variable event"); return var_; } - bool opEquals(ref const(Event) rhs) @safe pure nothrow const @nogc + bool opEquals(ref const(Event) rhs) @safe pure nothrow const @nogc { if(id != rhs.id || time != rhs.time) { return false; } final switch(id) diff --git a/source/tharsis/prof/ranges.d b/source/tharsis/prof/ranges.d index e551758..87cb52a 100644 --- a/source/tharsis/prof/ranges.d +++ b/source/tharsis/prof/ranges.d @@ -139,7 +139,7 @@ struct NamedVariable * } * -------------------- */ -VariableRange!EventRange variableRange(const(ubyte)[] profileData) @safe pure nothrow @nogc +VariableRange!EventRange variableRange(const(ubyte)[] profileData) @safe pure nothrow @nogc { return VariableRange!EventRange(profileData.eventRange); } @@ -162,7 +162,7 @@ VariableRange!EventRange variableRange(const(ubyte)[] profileData) @safe pure no struct VariableRange(ERange) { static assert(isForwardRange!ERange && is(Unqual!(ElementType!ERange) == Event), - "ERange parameter of VariableRange must be a forward range of Event, " + "ERange parameter of VariableRange must be a forward range of Event, " ~ " e.g. EventRange"); private: // Range to read profiling events from. @@ -187,7 +187,7 @@ public: * events = The event range to read from. VariableRange will create a (shallow) copy, * and will not consume this range. */ - this(ERange events) @safe pure nothrow @nogc + this(ERange events) @safe pure nothrow @nogc { events_ = events.save; getToNextVariableEnd(); @@ -202,7 +202,7 @@ public: // variable off the front yet. if(events_.empty) { - assert(variableTime_ != ulong.max, "Non-empty VariableRange with empty " + assert(variableTime_ != ulong.max, "Non-empty VariableRange with empty " ~ "events_ must have non-default variableTime_"); return NamedVariable(variableInfo_, variableTime_, variable_); } @@ -342,7 +342,7 @@ unittest struct ZoneRange(ERange) { static assert(isForwardRange!ERange && is(Unqual!(ElementType!ERange) == Event), - "ERange parameter of ZoneRange must be a forward range of Event, e.g. " + "ERange parameter of ZoneRange must be a forward range of Event, e.g. " ~ "EventRange"); private: @@ -518,7 +518,7 @@ unittest // Sort top-level zones by duration. If there is one top-level zone per frame, this // sorts frames by duration: useful to get the worst-case frames. - // This example also uses C malloc/free and std.typecons.scoped + // This example also uses C malloc/free and std.typecons.scoped // to show how to do this without using the GC. import tharsis.prof; @@ -762,7 +762,7 @@ private: } parseTimeBytes(timeBytes); - front_.info_ = null; + front_.resetInfo(); with(EventID) switch(front_.id) { @@ -781,7 +781,7 @@ private: "Invalid profiling data: info event not followed by string length"); const infoBytes = profileData[0]; profileData = profileData[1 .. $]; - front_.info_ = cast(const(char)[])profileData[0 .. infoBytes]; + front_.info = cast(const(char)[])profileData[0 .. infoBytes]; assert(profileData.length >= infoBytes, "Invalid profiling data: info event not followed by info string"); @@ -860,7 +860,7 @@ private: // } // // parseTimeBytes(timeBytes); - // front_.info_ = null; + // front_.resetInfo(); // // with(EventID) switch(front_.id) // { @@ -879,7 +879,7 @@ private: // "Invalid profiling data: info event not followed by string length"); // const infoBytes = profileData_.front; // profileData_.popFront; - // front_.info_ = cast(const(char)[])profileData_[0 .. infoBytes]; + // front_.info = cast(const(char)[])profileData_[0 .. infoBytes]; // // assert(profileData_.length >= infoBytes, // "Invalid profiling data: info event not followed by info string");