Skip to content

Commit

Permalink
Tweak timer logic. Now a single CTRL-C signal should quit properly
Browse files Browse the repository at this point in the history
  • Loading branch information
capehill committed Oct 10, 2019
1 parent f43447f commit d08117e
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 23 deletions.
123 changes: 106 additions & 17 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ static struct Params params = { 0, 0, 0, 0, NULL, NULL, NULL };

static struct MsgPort* port;

struct Task* mainTask;
BYTE mainSig = -1;

static ULONG startTime;
static ULONG duration;

static BOOL running = TRUE;

static BOOL already_running(void)
{
IExec->Forbid();
Expand Down Expand Up @@ -64,6 +69,38 @@ static void remove_port()
}
}

static void sanitiseParams(void)
{
if (params.gui) {
// Some of these limitations may be lifted in the future
if (startTime) {
puts("Using STARTTIME with GUI is not possible yet");
startTime = 0;
}

if (duration) {
puts("Using DURATION with GUI is not possible yet");
duration = 0;
}
}

if (!params.profiling) {
if (startTime) {
puts("STARTTIME is meant to be used with PROFILE");
startTime = 0;
}
if (duration) {
puts("DURATION is meant to be used with PROFILE");
duration = 0;
}
}

if (!params.ogles2 && !params.nova) {
// If user gives nothing, assume everything
params.ogles2 = params.nova = TRUE;
}
}

static BOOL parse_args(void)
{
const char* const enabled = "enabled";
Expand Down Expand Up @@ -93,10 +130,7 @@ static BOOL parse_args(void)
return FALSE;
}

if (!params.ogles2 && !params.nova) {
// If user gives nothing, assume everything
params.ogles2 = params.nova = TRUE;
}
sanitiseParams();

puts("--- Configuration ---");
printf(" OGLES2 module: [%s]\n", params.ogles2 ? enabled : disabled);
Expand All @@ -118,7 +152,7 @@ static void install_patches(void)
}

if (params.nova) {
warp3dnova_install_patches(startTime);
warp3dnova_install_patches(startTime, duration);
}
}

Expand Down Expand Up @@ -150,22 +184,33 @@ static void remove_patches(void)
ogles2_free();
}

static void waitForStartAndStop()
// When STARTTIME > 0
static void waitForStartTimer()
{
const uint32 timerSig = timer_signal(&triggerTimer);

if (timer_wait_for_signal(timerSig, "Start") == ESignalType_Timer) {
puts("First timer signal - start profiling");
const ESignalType type = timer_wait_for_signal(timerSig, "Start");

if (type == ESignalType_Timer) {
puts("Timer signal - start profiling");

timer_handle_events(&triggerTimer);

ogles2_start_profiling();
warp3dnova_start_profiling();
} else if (type == ESignalType_Break) {
running = FALSE;
}
}

if (duration) {
timer_start(&triggerTimer, duration, 0);
puts("Waiting...");
}
static void waitForEndTimer()
{
if (running) {
timer_start(&triggerTimer, duration, 0);

const uint32 timerSig = timer_signal(&triggerTimer);

puts("Waiting for timer...");

if (timer_wait_for_signal(timerSig, "Stop") == ESignalType_Timer) {
puts("Timer signal - stop profiling");
Expand All @@ -174,10 +219,41 @@ static void waitForStartAndStop()
}
}

static void waitForBreakSignal()
static void waitForSignal()
{
if (running) {
const uint32 sigMask = 1L << mainSig;
const uint32 wait = IExec->Wait(sigMask | SIGBREAKF_CTRL_C);

if (wait & sigMask) {
puts("Start signal received");
}

if (wait & SIGBREAKF_CTRL_C) {
puts("Break signal received");
running = FALSE;
}
}
}

static void waitForTimers()
{
if (IExec->Wait(SIGBREAKF_CTRL_C)) {
puts("*** Control-C detected ***");
if (startTime) {
waitForStartTimer();
}

if (duration) {
if (!startTime) {
// NOVA module Signal()s us
puts("Waiting for signal...");
waitForSignal();
}

waitForEndTimer();
} else {
if (startTime) {
waitForSignal();
}
}
}

Expand All @@ -187,9 +263,9 @@ static void run(void)
run_gui(params.profiling);
} else {
if (startTime || duration) {
waitForStartAndStop();
waitForTimers();
} else {
waitForBreakSignal();
waitForSignal();
}
}
}
Expand All @@ -207,6 +283,8 @@ int main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
goto out;
}

mainTask = IExec->FindTask(NULL);

if (!timer_init(&timer)) {
goto out;
}
Expand All @@ -217,6 +295,12 @@ int main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
}
}

mainSig = IExec->AllocSignal(-1);
if (mainSig == -1) {
puts("Failed to allocate signal");
goto out;
}

create_port();

if (!load_filters(filterFile)) {
Expand All @@ -239,6 +323,11 @@ int main(int argc __attribute__((unused)), char* argv[] __attribute__((unused)))
puts("Patches removed. glSnoop terminating");

out:
if (mainSig != -1) {
IExec->FreeSignal(mainSig);
mainSig = -1;
}

remove_port();

free_filters();
Expand Down
1 change: 1 addition & 0 deletions timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ void timer_stop(TimerContext * tc)
}

if (!IExec->CheckIO((struct IORequest *) tc->request)) {
logLine("%s: aborting timer IO request %p", __func__, tc->request);
IExec->AbortIO((struct IORequest *) tc->request);
IExec->WaitIO((struct IORequest *) tc->request);
}
Expand Down
22 changes: 17 additions & 5 deletions warp3dnova_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <stdio.h>
#include <string.h>

extern BYTE mainSig;
extern struct Task* mainTask;

typedef enum NovaFunction {
BindBitMapAsTexture,
BindShaderDataBuffer,
Expand Down Expand Up @@ -248,6 +251,7 @@ static unsigned errorCount;
static BOOL profilingStarted = TRUE;

static ULONG startTime = 0;
static ULONG duration = 0;

static const char* mapNovaError(const W3DN_ErrorCode code)
{
Expand Down Expand Up @@ -2983,10 +2987,17 @@ static W3DN_Context* my_W3DN_CreateContext(struct Warp3DNovaIFace *Self, W3DN_Er
patch_context_functions(nova);
PROF_INIT(nova, NovaFunctionCount)

logLine("Trigger start timer in %lu seconds", startTime);
// TODO: supports only one app. A proper implementation
// would need a some kind of a timer pool?
timer_start(&triggerTimer, startTime, 0);
if (startTime) {
logLine("Trigger timer in %lu seconds", startTime);
// TODO: supports only one app. A proper implementation
// would need a some kind of a timer pool?
timer_start(&triggerTimer, startTime, 0);
} else {
if (duration) {
logLine("Signal glSnoop task %p with signal %d", mainTask, mainSig);
IExec->Signal(mainTask, 1L << mainSig);
}
}
}
} else {
logAlways("Cannot allocate memory for NOVA context data: cannot patch");
Expand All @@ -2999,9 +3010,10 @@ static W3DN_Context* my_W3DN_CreateContext(struct Warp3DNovaIFace *Self, W3DN_Er

GENERATE_PATCH(Warp3DNovaIFace, W3DN_CreateContext, my, ContextCreation)

void warp3dnova_install_patches(ULONG startTimeInSeconds)
void warp3dnova_install_patches(ULONG startTimeInSeconds, ULONG durationTimeInSeconds)
{
startTime = startTimeInSeconds;
duration = durationTimeInSeconds;

mutex = IExec->AllocSysObject(ASOT_MUTEX, TAG_DONE);

Expand Down
2 changes: 1 addition & 1 deletion warp3dnova_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <exec/types.h>

void warp3dnova_install_patches(ULONG startTimeInSeconds);
void warp3dnova_install_patches(ULONG startTimeInSeconds, ULONG durationTimeInSeconds);
void warp3dnova_remove_patches(void);
void warp3dnova_free(void);

Expand Down

0 comments on commit d08117e

Please sign in to comment.