Minor documentation improvements
kuzminrobin opened this issue · 5 comments
In the file "https://www.boost.org/doc/libs/1_70_0/libs/context/doc/html/context/ff.html"
A. Major Questions
- The second occurrence of
return std::move(f2);
.
Why does labda (that must return void) actually return something? See fragment "The function passed as argument must accept a rvalue reference to fiber and return void." - Sentence "Another option is to execute a function on top of the fiber that throws an exception".
a. Causes the questions "Another option of what"? Of exception handling? Of executing a piece of code on top of a fiber?
b. Looking at the example code I feel that the sentence needs to be reworded to
".. is to execute a function that throws an exception on top of the fiber" - Fragment "and catched inside the for-loop".
Where is the for-loop? - Multiple occurrences of
return {}
. Is that a valid C++? Is that a correct return value? - f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func}
What is entry_func?
What if sp is replaced withstatic_cast<void*>(this)
?
(and the parameter sp is removed from the constructor 'my_control_structure(void * sp,',
and the argument sp is removed from the call 'cs=new(sp)my_control_structure( sp, size,sctx,salloc)')
B. Typos
- I see:
The locale variables b and next
I expected:
The local variables b and next
(in the word "locale" the last letter 'e' seems to me misleading). - I see: "inside c1,i==1",
I expected: "inside f1,i==1". - I see
emits ans exception
I expected
emits an exception - propagation ofs the
- requires to allocated the stack_context
- catched inside the for-loop
caught inside the for-loop - micro-processors
microprocessors - has to specify an fiber
has to specify a fiber - variables b and next remain their values
variables b and next retain their values - of an valid
of a valid
C. Recommended for clarity
- sink is captured (current-fiber)
sink (current-fiber) is captured - The function passed as argument must accept a rvalue reference
The function passed as an argument must accept an rvalue reference
D. I expect the confirmation form the author whether the following notes are applicable.
- When talking about
resume_with()
I would recommend to give different names (in the form of the code comments) to the 2 lambdas - the one associated withf1
(e.g.// Lambda A.
) and the other one invoked withresume_with()
(e.g.// Lambda B.
).
Then I would recommend to reword the sentence
"The expression f1.resume_with(...) executes a lambda on top of fiber f1, e.g. an additional stack frame is allocated on top of the stack"
to something like this:
"The expressionf1.resume_with(..)
executes the lambda B immediately prior to switching to lambda A, in particular an additional stack frame is allocated for lambda B on top of the stack frame of lambda A".
(In this sentence I also replaced "e.g." with "in particular" because the fragment "e.g." tells me that it is one of many possible ways, whereas I intuitively feel that it is the only implemented way. If I'm mistaken then feel free to leave "e.g.", however in that case I would recommend to add a clarification like this "e.g. one possible implementation can be ") - I see
This lambda assigns -1 to data and returns to the second invocation of f1.resume().
I expected
This lambda assigns -1 to data and returns to the third invocation of f1.resume(). - can be applied to and returned from a function
can be passed to and returned from a function - If the function executed inside a context-function emits ans exception
If an exception escapes from the context-function - Do not jump from inside a catch block
Do not switch to a different fiber inside of a catch block - Sometimes it is useful to execute a new function on top of a resumed fiber
Sometimes it is useful to execute some function immediately prior to resuming the other fiber
E. Note
I did not run through the Inverting the control flow section.
In the mean time I proceed to making fixes and preparing the pull-request.
A. Major Questions
- the lambda has to return a fiber
- a) one option is to modify some data (example: lambda assigns -1 to data) or the lambda throws an exception (can be used to unwind the stack)
- b) OK
- "and catched inside the for-loop" is unnecessary
- yes, its correct C++ code
- should be:
// captured fiber
ctx::fiber f;
ctx::fiber entry_func(ctx::fiber&&) {
...
}
template< typename StackAllocator >
my_control_structure(void * sp,std::size_t size,stack_context sctx,StackAllocator salloc) :
// create captured fiber
f{std::allocator_arg,preallocated(sp,size,sctx),salloc,entry_func} {
}
...
};
B and C are OK
D
- first part is OK,
"The expression f1.resume_with(..) executes the lambda B immediately prior to switching to lambda A, in particular an additional stack frame is allocated for lambda B on top of the stack frame of lambda A".
-> lambda B is immediately executed after switching to lambda A but is executed before entering lambda A again (resume_with() suspends main(), switches to f1 but executed lambda B inside f1 first) - not sure what you mean, but the example output is correct:
f1: entered first time: 0
f1: returned first time: 1
f1: entered second time: 2
f1: returned second time: 3
f2: entered: 4
f1: entered third time: -1
f1: returned third time
- OK
- OK
- OK
- OK
ty
@olk ,
(I observe a slight mismatch between
the enumeration of the questions and
the enumeration of the answers.
I assume that your
answer A.3.b relates to the question A.2.b,
answers A.4, A.5, and A.6 relate to the question A.3, A.4, and A.5 correspondingly)
A.1: You wrote: "the lambda has to return a fiber".
If the lambda has to return a fiber then in the sentence
"The function passed as argument must accept a rvalue reference to fiber and return void"
the fragment "and return void" misleads. The fragment needs to be
either replaced with "and return fiber"
or removed.
Do you agree? If yes then shall I (in my fix) replace the fragment with "and return fiber"? (In this case feel free to answer: "A.1: I agree, replace void with fiber")
A.2.a: (Still is not clear for me. I'll ask differently later if the answer is still required)
A.2.b: I assume your answer is
Yes, please reword to ".. is to execute a function that throws an exception on top of the fiber"
(feel free to confirm with "A.2.b: Confirmed")
A.3: (I have noticed extra fragments that attracted my attention, may be they are a result of recent changes in the documentation?) I assume your answer is:
Yes, please reword the sentence
"In this exception my_exception is throw from a function invoked on-top of fiber f and catched inside the for-loop"
to
"In this fragment my_exception is thrown by a function invoked on-top of fiber f"
(feel free to confirm with "A.3: Confirmed").
A.4: Consists of 2 parts (sub-questions). You answered the first part ("its correct C++ code"). But the second part ("Is that a correct return value?") is still unclear for me.
As I understand the statement return {}
returns the default-constructed instance of type ctx::fiber
, and that instance has no any relation to the lambda's parameter ctx::fiber && f
. But I intuitively feel that the value being returned should somehow be associated with the parameter f
.
Please clarify.
A.5.{What if sp
is ..}: What will happen if I write (optimize) like this? See the code comments only:
my_control_structure * cs=new(sp)my_control_structure(size,sctx,salloc); // I removed the first-most argument `sp`.
...
struct my_control_structure {
...
template< typename StackAllocator >
my_control_structure( // I removed the first-most parameter `sp`.
std::size_t size,stack_context sctx,StackAllocator salloc) :
f{std::allocator_arg,preallocated(static_cast<void*>(this), // I replaced the first-most argument `sp` with `static_cast<void*>(this)` (because the value is the same in case of a placement `new`).
size,sctx),salloc,entry_func} {
}
...
};
D.1 and D.2: I assume the fragment:
The expression f1.resume_with(...) executes a lambda on top of fiber f1, e.g. an additional stack frame is allocated on top of the stack. This lambda assigns -1 to data and returns to the second invocation of f1.resume()
can be re-written like this:
The expression
f1.resume_with(..)
executes the lambda B immediately after switching to but before resuming the lambda A, in particular an additional stack frame is allocated for lambda B on top of the stack frame of lambda A. Lambda B assigns -1 to data and returns to an address in the beginning of the fragmentstd::cout << "f1: entered third time: "
.
A.1: "The function passed as argument must accept a rvalue reference to fiber and return a fiber."
A.2.b: Confirmed
A.3: Confirmed
A.4: return {}
returns a default constructed fiber
throw my_exception(std::move(f),"abc");
return {};
});
resumes f
and executes the lambda on top of the resumed f
- return {}
is correct because the exception already takes the fiber (moveable only)
A.5: my_control_structure gets overwritten
D.1 and D.2 correct
no response - closing