Hold 0050's budget, its floor and the order a decode waiting for room is started in - #257
Merged
Merged
Conversation
… is started in Two hundred decoded tiles held at once is enough to be killed by the operating system on a television, and that failure looks like a crash rather than like a cache that was too large. 0050 bounds it at sixty four mebibytes, and this is the admission rule that keeps the bound: a decode that would take the total past it does not start, it waits, and nothing fails. Most of the work in 0050 was deciding what the quantity is, because the phrase reads as a cache and is not one, and that is what this module is written to. 0009 hands a decoded image to the caller and never reads it again and 0006 caches encoded bytes rather than pixels, so what is counted is the buffers of decodes that are running plus those whose outcome has not reached the caller, and nothing else. Read the other way, the natural build is a store with an eviction policy for data 0006 deliberately does not keep. The floor is derived rather than chosen, which is 0050's own construction: it is 0055's per-image bound at four bytes a pixel, so no image the core will ever decode is larger than the smallest budget a client may set, and nothing can wait for room that will never exist. A buffer size exists only for dimensions 0055 admits, which is what makes that total rather than nearly total. The order is where a queue written from the number alone goes wrong. A decode that would fit right now still waits behind one that does not, because ordering by size starves the large ones, and the test for it asserts the poster fits before asserting it waits, so it is a test of the order rather than of the room. Two figures 0050 states do not follow from its own arithmetic. Both are already recorded on #50 and neither is repaired here, because 0001 admits neither as an edit; both are named at the top of this module because this is where an implementation written from those sentences would go wrong. The one that costs something says the THIRD maximal image waits on a four-processor television. Two maximal images are 128000000 bytes against a budget of 67108864, so it is the second, and admission written to the sentence would allow a hundred and twenty eight megabytes on the device the per-image bound was chosen against. Fourteen tests, and three deliberate violations reddening what they should: if self.fits(bytes) { // the queue-is-empty half removed test artwork::budget::tests::a_later_small_ask_does_not_step_past_an_earlier_large_one ... FAILED test result: FAILED. 409 passed; 1 failed if bytes < 1 { // the floor lowered test artwork::budget::tests::a_budget_below_the_per_image_bound_is_refused_with_both_numbers ... FAILED test result: FAILED. 409 passed; 1 failed dimensions.pixel_count() * 3 // three bytes a pixel test result: FAILED. 405 passed; 5 failed Refs #50. Its conditions ask for a caller's thread not being used and two hundred images driven through, and nothing in this tree decodes anything or starts a thread, so this closes nothing. Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
`no-view-vocabulary` refused four lines of the module that just landed on this
branch, and the rule is right rather than pedantic: 0003 places a scroll offset
outside the core by name and says a core that learns any of those words has
learned the shape of one client's screen. The sentences meant a tile a client no
longer wants, which is 0053's withdrawal and a thing the core does know about, so
they now say that.
::error::no-view-vocabulary: src/artwork/budget.rs:104
::error::no-view-vocabulary: src/artwork/budget.rs:105
::error::no-view-vocabulary: src/artwork/budget.rs:336
::error::no-view-vocabulary: src/artwork/budget.rs:585
::error::4 line(s) broke an invariant above.
Refs #50.
Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The issue this belongs to
Refs #50. It does not close it, and the reason is under "What this does not
cover" below.
What changed
src/artwork/budget.rsholds0050's bound and the admission
rule that keeps it. Two hundred decoded tiles held at once is enough to be killed
by the operating system on a television, and that failure looks like a crash
rather than like a cache that was too large.
It is a working set and never a store, which is most of 0050's value and the
thing an implementation gets wrong first. 0009 hands a decoded image to the caller
and never reads it again, and 0006 caches encoded artwork bytes and the declared
dimensions rather than pixels, so what is counted is the buffers of decodes that
are running plus those whose outcome has not reached the caller, and nothing else.
Read the other way, the natural build is a second store with a second eviction
policy for data 0006 deliberately does not keep, and the memory it occupies is the
memory the budget exists to bound.
Nothing fails at the bound. A decode that would take the total past the budget
does not start; it waits. There is no sixteenth kind in 0004 for it and none is
asked for, so the answer type is
WhatTheAskDoesand not aResult- a failurehere would be one whose occurrence depends on what other callers were doing, which
is the least reproducible thing a client can be handed.
The floor is derived rather than chosen, which is 0050's own construction:
0055's per-image bound at four bytes a pixel.
DecodedBytes::ofanswersNonefor dimensions 0055 refuses, and that is what makes the budget total rather than
nearly total - every buffer size this module can produce is no larger than the
smallest budget a client may set, so nothing can wait for room that will never
exist.
The order is where a queue written from the number alone goes wrong. A decode
that would fit at this instant still waits behind one that does not, because
ordering by size starves the large ones. The test asserts the poster fits before
asserting it waits, so it is a test of the order rather than of the room.
Two figures in 0050 that do not follow from its own arithmetic
Both are already recorded on #50 by an earlier reading, and neither is repaired
here: 0001 admits neither as an edit to a landed record. They are named at the top
of the module because this file is where an implementation written from those
sentences would go wrong, and this is the paragraph a reader of the module needs
rather than a second finding.
The one that costs something: 0050 says that on a four-processor television three
maximal images cannot be decoded at once and the THIRD waits. Two maximal images
are 128000000 bytes against a budget of 67108864, so it is the second, and one
maximal image fits with nothing beside it. Admission written to that sentence
would allow a hundred and twenty eight megabytes on the device the per-image bound
in 0055 was chosen against, which is the allocation that record exists to refuse
arriving by the route 0050 names in its own first paragraph. The module is written
to the arithmetic, and
one_maximal_image_fits_and_the_second_waitsis what wouldredden if somebody wrote it to the sentence.
The other is that the record calls the budget and the per-image bound within four
per cent of each other; it is 4.63 per cent of the budget and 4.86 per cent of the
bound. It changes nothing here and is named for completeness.
Evidence
At
2c919ac, the two commands the gate runs:Fourteen of those are this module's, and five of the 97 are 0009's thread
statements for its types, checked from outside the crate the way every other one
is.
The analyser, the formatter and the two shell legs that run on this machine:
The guards refusing
Three deliberate violations, each reddening what it names.
The order half of the admission removed, so a small decode can step past a
large one that is already waiting:
The floor lowered, so a client may set a budget under 0055's per-image bound
and make a legal image undecodable:
Three bytes a pixel instead of four, which is the arithmetic every number in
0050 rests on:
The tree is restored in each case, and the run above is the restored tree.
A fourth refusal was not deliberate and is worth reporting as such.
no-view-vocabularyrefused four lines of the module's own prose on the firstlocal run of the invariants leg, because they said what a tile did on a screen
rather than what a client withdrew. The rule is right - 0003 places a scroll
offset outside the core by name - and the second commit on this branch is that
repair. It is named here rather than tidied away, because a guard catching this
change is exactly what the guard is for.
The means
Rust in the crate that already exists, in
src/artwork/, beside the module thatholds the record this one derives its floor from. No dependency is added and no
new language enters the tree. The types are plain values and one piece of
bookkeeping, which is what lets 0009's thread statements be compile-time
assertions rather than something a run has to observe;
DecodedBytesHeldcarriesno interior mutability, so whoever holds it serialises access to it, the way the
cache bookkeeping is held.
What this does NOT cover
#50 is not closed by this. Its two conditions are a test proving the caller's
thread is not used for decode, and a test driving two hundred images through
against the bound. Nothing in this tree starts a thread and nothing turns admitted
bytes into pixels, so neither has a subject. The observation that the budget could
be built ahead of both was already recorded on #50 by an earlier reading; this is
that piece and it is not those conditions.
Nothing decodes. The sizes this module is told are the sizes a decoder would
allocate, and no buffer is allocated anywhere. A caller that reports a size other
than the one it allocated is not caught here and cannot be.
Where the lane comes from is #115. 0050 declines to add a second bound on how
many decodes run at once, because 0009 already sizes the processing lane, and this
module holds neither the lane nor a number for it.
Nothing reports a waiting decode.
a_wait_worth_reportinganswers whether thefive seconds 0050 names have passed; emitting the event through 0100 is the
diagnostics facility and is not done here, so no run of this tree reports one.
The two figures above are recorded, not repaired. 0050 still carries both
readings on the default branch, and an implementation written from the sentence
rather than from the arithmetic would still pass a reading of that record.
No second reader. Nobody other than the author has read this change.