Skip to content

Commit

Permalink
Implement support for --MaxSolveTimeoutInSeconds.
Browse files Browse the repository at this point in the history
  • Loading branch information
tpn committed Dec 7, 2022
1 parent 5ca1248 commit a10b8c5
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/PerfectHash.h
Original file line number Diff line number Diff line change
Expand Up @@ -3172,6 +3172,7 @@ typedef RNG_VTBL *PRNG_VTBL;
ENTRY(RngOffset) \
ENTRY(Seed3Byte1MaskCounts) \
ENTRY(Seed3Byte2MaskCounts) \
ENTRY(MaxSolveTimeInSeconds) \
LAST_ENTRY(Remark)

#define TABLE_CREATE_PARAMETER_TABLE_ENTRY(ENTRY) \
Expand Down
32 changes: 29 additions & 3 deletions include/PerfectHashErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ Module Name:
//
#define PH_I_TABLE_CREATED_BUT_VALUES_ARRAY_ALLOC_FAILED ((HRESULT)0x60040087L)

//
// MessageId: PH_I_SOLVE_TIMEOUT_EXPIRED
//
// MessageText:
//
// Solve timeout expired.
//
#define PH_I_SOLVE_TIMEOUT_EXPIRED ((HRESULT)0x60040088L)


////////////////////////////////////////////////////////////////////////////////
// PH_SEVERITY_INFORMATIONAL -- Usage Messages
Expand Down Expand Up @@ -899,6 +908,11 @@ Module Name:
// be returned if the provided string contains commas (as this will
// break the .csv output).
//
// --MaxSolveTimeInSeconds=<Seconds>
//
// Supplies the maximum number of seconds to try and solve an individual
// graph.
//
//
// Console Output Character Legend
//
Expand All @@ -913,7 +927,7 @@ Module Name:
// were possible (due to the maximum resize limit also being hit).
//
// F Failed to create a table due to a target not being reached by a specific
// number of attempts or time duration. Not yet implemented.
// number of attempts.
//
// * None of the worker threads were able to allocate sufficient memory to
// attempt solving the graph.
Expand All @@ -928,13 +942,16 @@ Module Name:
//
// V The graph was created successfully, however, we weren't able to allocate
// enough memory for the table values array in order for the array to be
// used after creation. This can be avoided by omitting --TestAfterCreate.
// used after creation. This can be avoided by supplying the command line
// parameter --SkipTestAfterCreate.
//
// T The requested number of table elements was too large (exceeded 32 bits).
// T The requested number of table elements was too large.
//
// S A shutdown event was received. This shouldn't be seen unless externally
// signaling the named shutdown event associated with a context.
//
// t The solve timeout was reached before a solution was found.
//
//
#define PH_MSG_PERFECT_HASH_USAGE ((HRESULT)0x60040101L)

Expand Down Expand Up @@ -4057,3 +4074,12 @@ Module Name:
//
#define PH_E_INVALID_REMARK ((HRESULT)0xE00403D3L)

//
// MessageId: PH_E_INVALID_MAX_SOLVE_TIME_IN_SECONDS
//
// MessageText:
//
// Invalid --MaxSolveTimeInSeconds.
//
#define PH_E_INVALID_MAX_SOLVE_TIME_IN_SECONDS ((HRESULT)0xE00403D4L)

26 changes: 25 additions & 1 deletion src/PerfectHash/Chm01.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,18 @@ Return Value:
}
}

//
// If we've been asked to cap the maximum solve time, submit a threadpool
// timer now to achieve that.
//

if (Table->MaxSolveTimeInSeconds > 0) {
SetThreadpoolTimer(Context->SolveTimeout,
&Table->RelativeMaxSolveTimeInFiletime.AsFileTime,
0,
0);
}

//
// Submit all of the file preparation work items.
//
Expand Down Expand Up @@ -840,6 +852,7 @@ Return Value:

WaitForThreadpoolWorkCallbacks(Context->MainWork, TRUE);
WaitForThreadpoolWorkCallbacks(Context->FinishedWork, FALSE);
WaitForThreadpoolTimerCallbacks(Context->SolveTimeout, TRUE);

if (!NoFileIo(Table)) {

Expand Down Expand Up @@ -975,6 +988,7 @@ Return Value:

WaitForThreadpoolWorkCallbacks(Context->MainWork, TRUE);
WaitForThreadpoolWorkCallbacks(Context->FinishedWork, FALSE);
WaitForThreadpoolTimerCallbacks(Context->SolveTimeout, TRUE);

Success = (Context->FinishedCount > 0);

Expand Down Expand Up @@ -1017,8 +1031,10 @@ Return Value:

} else if (FailedEventSet) {

if (Context->State.AllGraphsFailedMemoryAllocation == TRUE) {
if (Context->State.AllGraphsFailedMemoryAllocation != FALSE) {
Result = PH_I_FAILED_TO_ALLOCATE_MEMORY_FOR_ALL_GRAPHS;
} else if (Context->State.SolveTimeoutExpired != FALSE) {
Result = PH_I_SOLVE_TIMEOUT_EXPIRED;
} else {
Result = PH_I_CREATE_TABLE_ROUTINE_FAILED_TO_FIND_SOLUTION;
}
Expand All @@ -1040,6 +1056,12 @@ Return Value:

WaitForThreadpoolWorkCallbacks(Context->MainWork, CancelPending);

//
// Wait for the solve timeout, if applicable.
//

WaitForThreadpoolTimerCallbacks(Context->SolveTimeout, TRUE);

//
// Perform the same operation for the file work threadpool. Note that
// the only work item type we've dispatched to this pool at this point
Expand Down Expand Up @@ -1074,6 +1096,7 @@ Return Value:

WaitForThreadpoolWorkCallbacks(Context->MainWork, TRUE);
WaitForThreadpoolWorkCallbacks(Context->FinishedWork, FALSE);
WaitForThreadpoolTimerCallbacks(Context->SolveTimeout, TRUE);

if (CtrlCPressed) {
Result = PH_E_CTRL_C_PRESSED;
Expand Down Expand Up @@ -1383,6 +1406,7 @@ Return Value:

SetEvent(Context->ShutdownEvent);
WaitForThreadpoolWorkCallbacks(Context->MainWork, TRUE);
WaitForThreadpoolTimerCallbacks(Context->SolveTimeout, TRUE);
if (!NoFileIo(Table)) {
WaitForThreadpoolWorkCallbacks(Context->FileWork, TRUE);
}
Expand Down
2 changes: 2 additions & 0 deletions src/PerfectHash/ExtractArg.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,8 @@ Return Value:

ADD_PARAM_IF_EQUAL_AND_VALUE_IS_INTEGER(MinNumberOfKeysForFindBestGraph);

ADD_PARAM_IF_EQUAL_AND_VALUE_IS_INTEGER(MaxSolveTimeInSeconds);

#define IS_VALUE_EQUAL(ValueName) \
Rtl->RtlEqualUnicodeString(ValueString, &ValueName, TRUE)

Expand Down
72 changes: 71 additions & 1 deletion src/PerfectHash/PerfectHashContext.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ VOID
_Inout_ PTP_WORK Work
);

typedef
VOID
(NTAPI TP_TIMER_CALLBACK)(
_Inout_ PTP_CALLBACK_INSTANCE Instance,
_Inout_opt_ PVOID Context,
_Inout_ PTP_TIMER Work
);

typedef
VOID
Expand All @@ -56,6 +63,7 @@ TP_WORK_CALLBACK MainWorkCallback;
TP_WORK_CALLBACK FileWorkCallback;
TP_WORK_CALLBACK ErrorWorkCallback;
TP_WORK_CALLBACK FinishedWorkCallback;
TP_TIMER_CALLBACK SolveTimeoutCallback;
TP_CLEANUP_GROUP_CANCEL_CALLBACK CleanupCallback;

//
Expand Down Expand Up @@ -465,6 +473,19 @@ Return Value:
goto Error;
}

//
// Create the timer object for the solve timeout.
//

Context->SolveTimeout = CreateThreadpoolTimer(SolveTimeoutCallback,
Context,
&Context->MainCallbackEnv);
if (!Context->SolveTimeout) {
SYS_ERROR(CreateThreadpoolTimer);
Result = PH_E_SYSTEM_CALL_FAILED;
goto Error;
}

//
// Create the File threadpool structures. Automatically clamp the min/max
// threads for this threadpool to the number of system processors.
Expand Down Expand Up @@ -761,17 +782,19 @@ Return Value:
TRUE,
NULL);
Context->MainWork = NULL;
Context->SolveTimeout = NULL;
CloseThreadpoolCleanupGroup(Context->MainCleanupGroup);
Context->MainCleanupGroup = NULL;

} else {

//
// Invariant check: Context->MainWork should never be set if
// Invariant check: MainWork and SolveTimeout should never be set if
// MainCleanupGroup is not set.
//

ASSERT(!Context->MainWork);
ASSERT(!Context->SolveTimeout);
}

if (Context->MainThreadpool) {
Expand Down Expand Up @@ -910,6 +933,7 @@ Return Value:
Context->GraphMemoryFailures = 0;
Context->LowMemoryObserved = 0;
Context->State.AllGraphsFailedMemoryAllocation = FALSE;
Context->State.SolveTimeoutExpired = FALSE;

Context->VertexCollisionFailures = 0;
Context->CyclicGraphFailures = 0;
Expand Down Expand Up @@ -1017,6 +1041,52 @@ Return Value:
return;
}

_Use_decl_annotations_
VOID
SolveTimeoutCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Ctx,
PTP_TIMER Timer
)
/*++
Routine Description:
This is the callback routine for the Main threadpool "solve timeout" timer.
Arguments:
Instance - Supplies a pointer to the callback instance responsible for this
threadpool callback invocation.
Ctx - Supplies a pointer to the owning PERFECT_HASH_CONTEXT.
Timer - Supplies a pointer to the TP_TIMER object for this routine.
Return Value:
None.
--*/
{
PPERFECT_HASH_CONTEXT Context;

UNREFERENCED_PARAMETER(Instance);
UNREFERENCED_PARAMETER(Timer);

if (!ARGUMENT_PRESENT(Ctx)) {
PH_RAISE(PH_E_INVARIANT_CHECK_FAILED);
}

Context = (PPERFECT_HASH_CONTEXT)Ctx;

SetStopSolving(Context);
Context->State.SolveTimeoutExpired = TRUE;
SubmitThreadpoolWork(Context->FinishedWork);

return;
}

_Use_decl_annotations_
VOID
FileWorkCallback(
Expand Down
9 changes: 8 additions & 1 deletion src/PerfectHash/PerfectHashContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,17 @@ typedef union _PERFECT_HASH_CONTEXT_STATE {

ULONG IsTableCreate:1;

//
// When set, indicates a solve timeout expired.
//

ULONG SolveTimeoutExpired:1;

//
// Unused bits.
//

ULONG Unused:24;
ULONG Unused:23;
};
LONG AsLong;
ULONG AsULong;
Expand Down Expand Up @@ -785,6 +791,7 @@ typedef struct _Struct_size_bytes_(SizeOfStruct) _PERFECT_HASH_CONTEXT {
PTP_CLEANUP_GROUP MainCleanupGroup;
PTP_POOL MainThreadpool;
PTP_WORK MainWork;
PTP_TIMER SolveTimeout;
ULONG MinimumConcurrency;
ULONG MaximumConcurrency;

Expand Down
2 changes: 2 additions & 0 deletions src/PerfectHash/PerfectHashErrors.dbg
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct {
(HRESULT) PH_I_LOW_MEMORY, "PH_I_LOW_MEMORY",
(HRESULT) PH_I_OUT_OF_MEMORY, "PH_I_OUT_OF_MEMORY",
(HRESULT) PH_I_TABLE_CREATED_BUT_VALUES_ARRAY_ALLOC_FAILED, "PH_I_TABLE_CREATED_BUT_VALUES_ARRAY_ALLOC_FAILED",
(HRESULT) PH_I_SOLVE_TIMEOUT_EXPIRED, "PH_I_SOLVE_TIMEOUT_EXPIRED",
(HRESULT) PH_MSG_PERFECT_HASH_ALGO_HASH_MASK_NAMES, "PH_MSG_PERFECT_HASH_ALGO_HASH_MASK_NAMES",
(HRESULT) PH_MSG_PERFECT_HASH_USAGE, "PH_MSG_PERFECT_HASH_USAGE",
(HRESULT) PH_MSG_PERFECT_HASH_SELF_TEST_EXE_USAGE, "PH_MSG_PERFECT_HASH_SELF_TEST_EXE_USAGE",
Expand Down Expand Up @@ -362,5 +363,6 @@ struct {
(HRESULT) PH_E_TRY_USE_AVX2_HASH_FUNC_FLAG_REQUIRE_HASH_ALL_KEYS_FIRST, "PH_E_TRY_USE_AVX2_HASH_FUNC_FLAG_REQUIRE_HASH_ALL_KEYS_FIRST",
(HRESULT) PH_E_TRY_USE_AVX512_HASH_FUNC_FLAG_REQUIRE_HASH_ALL_KEYS_FIRST, "PH_E_TRY_USE_AVX512_HASH_FUNC_FLAG_REQUIRE_HASH_ALL_KEYS_FIRST",
(HRESULT) PH_E_INVALID_REMARK, "PH_E_INVALID_REMARK",
(HRESULT) PH_E_INVALID_MAX_SOLVE_TIME_IN_SECONDS, "PH_E_INVALID_MAX_SOLVE_TIME_IN_SECONDS",
(HRESULT) 0xFFFFFFFF, NULL
};
30 changes: 27 additions & 3 deletions src/PerfectHash/PerfectHashErrors.mc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ Language=English
The table was created successfully, however, the values array could not be allocated. The table cannot be used.
.
MessageId=0x088
Severity=Informational
Facility=ITF
SymbolicName=PH_I_SOLVE_TIMEOUT_EXPIRED
Language=English
Solve timeout expired.
.
;
;////////////////////////////////////////////////////////////////////////////////
;// PH_SEVERITY_INFORMATIONAL -- Usage Messages
Expand Down Expand Up @@ -844,6 +852,11 @@ Table Create Parameters:
be returned if the provided string contains commas (as this will
break the .csv output).
--MaxSolveTimeInSeconds=<Seconds>
Supplies the maximum number of seconds to try and solve an individual
graph.
Console Output Character Legend
Expand All @@ -858,7 +871,7 @@ Console Output Character Legend
were possible (due to the maximum resize limit also being hit).
F Failed to create a table due to a target not being reached by a specific
number of attempts or time duration. Not yet implemented.
number of attempts.
* None of the worker threads were able to allocate sufficient memory to
attempt solving the graph.
Expand All @@ -873,13 +886,16 @@ Console Output Character Legend
V The graph was created successfully, however, we weren't able to allocate
enough memory for the table values array in order for the array to be
used after creation. This can be avoided by omitting --TestAfterCreate.
used after creation. This can be avoided by supplying the command line
parameter --SkipTestAfterCreate.
T The requested number of table elements was too large (exceeded 32 bits).
T The requested number of table elements was too large.
S A shutdown event was received. This shouldn't be seen unless externally
signaling the named shutdown event associated with a context.
t The solve timeout was reached before a solution was found.
.
MessageId=0x102
Expand Down Expand Up @@ -3682,3 +3698,11 @@ Language=English
--Remark must not contain commas.
.
MessageId=0x3d4
Severity=Fail
Facility=ITF
SymbolicName=PH_E_INVALID_MAX_SOLVE_TIME_IN_SECONDS
Language=English
Invalid --MaxSolveTimeInSeconds.
.
Binary file modified src/PerfectHash/PerfectHashErrors_English.bin
Binary file not shown.
Loading

0 comments on commit a10b8c5

Please sign in to comment.