New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
optimize some buffer operations (implements #6148) #8596
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we have an assert
at the end of resize
that the postcondition b.position + more <= Bytes.length b.buffer
holds?
When I reviewed the file to ensure that these
I would prefer if |
That should be easy to prove from the code of |
To review a change from a safe function to an unsafe function, I try to convince myself ("mentally prove") that the check being removed is redundant at the call site. If the proof is obvious or easy, the change is safe, is the proof is subtle or hard or impossible-without-writing-stuff-down, the change is not necessarily a good idea, or at least this suggests a better documentation of the various invariants in the codebase. In the case of this PR, ensuring that the change is correct requires reviewing |
My approval of the PR extends to the |
Are buffers supposed to be thread-safe? The documentation doesn't say. Even if they currently are because of implicit critical sections, this implementation certainly won't be when we switch to multicore OCaml. For |
I've added the assertion and the comments. |
We should indeed document that their are not thread-safe (and also do it for Hashtbl, etc). |
I make a distinction between "this module may behave incorrect if used in multi-threaded environments" and breaking the memory-safety guarantees of the language. In particular, I believe that it is incorrect to make single-threading assumptions to remove bound checks -- even if we make the assumption for correctness.
I agree with this analysis, but still the |
Wouln't that exclude most of those unsafe functions in Buffer? Even in add_char, it's not clear to me that unsafe_set is ok. |
let add_char b c =
let pos = b.position in
if pos >= b.length then resize b 1;
Bytes.unsafe_set b.buffer pos c;
b.position <- pos + 1 I believe that the invariant that |
Ok, this works under the asumptions that "sequences of instructions" without allocations cannot be interleaved with other threads. Does this still hold under Multicore? |
Yes, I believe it does. But note that if we had doubts, we should move back to safe writes, instead of giving up on memory-safety in the multi-threaded case. |
I don't think so. If |
But |
Maybe we should rewrite |
Ah, sorry. I was implicitly assuming that we were in the case where |
My current understanding is summarized as follows:
|
You can't use |
Indeed, thanks. Where do we stand with the current PR? It could be merged as-is -- do you agree? Or are you convinced that there is a small issue with |
I'm convinced there is a problem with |
See ocaml#8596 (comment) and the rest of the conversation.
See ocaml#8596 (comment) and the rest of the conversation.
Buffer.add_string
andBuffer.add_substring
are the two remaining functions from #6148 that were not optimized when we switched to safe strings.