mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +09:00
Implement a callback system for interrupting timed slice budgets for bug #1351790
Trying this again.
This commit is contained in:
parent
0864846be4
commit
51277f511c
2 changed files with 64 additions and 29 deletions
|
|
@ -34,12 +34,18 @@ struct JS_PUBLIC_API(WorkBudget)
|
|||
*/
|
||||
class JS_PUBLIC_API(SliceBudget)
|
||||
{
|
||||
typedef bool (*InterruptRequestCallback)(void*);
|
||||
|
||||
static const int64_t unlimitedDeadline = INT64_MAX;
|
||||
static const intptr_t unlimitedStartCounter = INTPTR_MAX;
|
||||
|
||||
bool checkOverBudget();
|
||||
|
||||
SliceBudget();
|
||||
SliceBudget()
|
||||
: timeBudget(UnlimitedTimeBudget), workBudget(UnlimitedWorkBudget), callbackBudget(nullptr)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
public:
|
||||
// Memory of the originally requested budget. If isUnlimited, neither of
|
||||
|
|
@ -56,22 +62,51 @@ class JS_PUBLIC_API(SliceBudget)
|
|||
static const int64_t UnlimitedTimeBudget = -1;
|
||||
static const int64_t UnlimitedWorkBudget = -1;
|
||||
|
||||
SliceBudget* callbackBudget;
|
||||
// If callbackBudget is nullptr, the following fields are uninitialized and unused.
|
||||
InterruptRequestCallback interruptRequested;
|
||||
void* callbackData;
|
||||
|
||||
/* Use to create an unlimited budget. */
|
||||
static SliceBudget unlimited() { return SliceBudget(); }
|
||||
|
||||
explicit SliceBudget(TimeBudget time,
|
||||
SliceBudget& callbackBudget_, InterruptRequestCallback callback,
|
||||
void* callbackData)
|
||||
: timeBudget(time), workBudget(UnlimitedWorkBudget)
|
||||
, callbackBudget(&callbackBudget_), interruptRequested(callback)
|
||||
, callbackData(callbackData)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/* Instantiate as SliceBudget(TimeBudget(n)). */
|
||||
explicit SliceBudget(TimeBudget time);
|
||||
explicit SliceBudget(TimeBudget time)
|
||||
: timeBudget(time), workBudget(UnlimitedWorkBudget), callbackBudget(nullptr)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/* Instantiate as SliceBudget(WorkBudget(n)). */
|
||||
explicit SliceBudget(WorkBudget work);
|
||||
explicit SliceBudget(WorkBudget work)
|
||||
: timeBudget(UnlimitedTimeBudget), workBudget(work), callbackBudget(nullptr)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
void makeUnlimited() {
|
||||
deadline = unlimitedDeadline;
|
||||
counter = unlimitedStartCounter;
|
||||
if (callbackBudget)
|
||||
callbackBudget->makeUnlimited();
|
||||
}
|
||||
|
||||
void step(intptr_t amt = 1) {
|
||||
counter -= amt;
|
||||
if (callbackBudget)
|
||||
callbackBudget->step(amt);
|
||||
}
|
||||
|
||||
bool isOverBudget() {
|
||||
|
|
|
|||
|
|
@ -2938,33 +2938,23 @@ ArenaLists::queueForegroundThingsForSweep(FreeOp* fop)
|
|||
gcScriptArenasToUpdate = arenaListsToSweep[AllocKind::SCRIPT];
|
||||
}
|
||||
|
||||
SliceBudget::SliceBudget()
|
||||
: timeBudget(UnlimitedTimeBudget), workBudget(UnlimitedWorkBudget)
|
||||
void
|
||||
SliceBudget::reset()
|
||||
{
|
||||
makeUnlimited();
|
||||
}
|
||||
MOZ_ASSERT_IF(timeBudget.budget < 0, !callbackBudget);
|
||||
if (timeBudget.budget >= 0) {
|
||||
|
||||
SliceBudget::SliceBudget(TimeBudget time)
|
||||
: timeBudget(time), workBudget(UnlimitedWorkBudget)
|
||||
{
|
||||
if (time.budget < 0) {
|
||||
makeUnlimited();
|
||||
} else {
|
||||
// Note: TimeBudget(0) is equivalent to WorkBudget(CounterReset).
|
||||
deadline = PRMJ_Now() + time.budget * PRMJ_USEC_PER_MSEC;
|
||||
deadline = PRMJ_Now() + timeBudget.budget * PRMJ_USEC_PER_MSEC;
|
||||
counter = CounterReset;
|
||||
}
|
||||
}
|
||||
|
||||
SliceBudget::SliceBudget(WorkBudget work)
|
||||
: timeBudget(UnlimitedTimeBudget), workBudget(work)
|
||||
{
|
||||
if (work.budget < 0) {
|
||||
makeUnlimited();
|
||||
} else {
|
||||
deadline = 0;
|
||||
counter = work.budget;
|
||||
}
|
||||
if (callbackBudget)
|
||||
callbackBudget->reset();
|
||||
} else if (workBudget.budget >= 0) {
|
||||
deadline = 0;
|
||||
counter = workBudget.budget;
|
||||
} else {
|
||||
makeUnlimited();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -2981,10 +2971,20 @@ SliceBudget::describe(char* buffer, size_t maxlen) const
|
|||
bool
|
||||
SliceBudget::checkOverBudget()
|
||||
{
|
||||
bool over = PRMJ_Now() >= deadline;
|
||||
if (!over)
|
||||
int64_t now = PRMJ_Now();
|
||||
bool over = now >= deadline;
|
||||
if (over)
|
||||
return true;
|
||||
if (!callbackBudget || !callbackBudget->isOverBudget()) {
|
||||
counter = CounterReset;
|
||||
return over;
|
||||
return false;
|
||||
}
|
||||
callbackBudget->reset();
|
||||
if (interruptRequested(callbackData)) {
|
||||
deadline = now;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue