Open bo-tato opened 1 year ago
Thanks for the nice report.
I originally ported this function from Rutils to Serapeum.
https://github.com/ruricolist/serapeum/blob/master/hash-tables.lisp#L568
rutils: https://github.com/vseloved/rutils/blob/master/core/hash-table.lisp#L120
So, I suggest you open an issue on Serapeum first and we see what happens?
Your solution is simple and non-intrusive so it looks like an acceptable patch.
interesting, it seems the issue isn't present though in the serapeum and rutils version, they are using pprint-indent
to manage the nested indentation which works multithreaded where it seems in ciel that got replaced with *current-pprint-indentation*
with the comment:
We use custom indentation instead of the pretty printer, because it doesn't print correctly in the shell (indentations are way too large).
I'm just using ciel in emacs repl where they both look the same with exception that the ciel version prints fresh-line at the end, but it's true in the ciel standalone shell the serapeum version has way too large indentation, I'm not sure what is difference between shell and repl that would cause it.
I was printing hash tables to debug a very concurrent program, and it would crash with:
it seems all threads share the same
*current-pprint-indentation*
, and incf and decf is not atomic, so sometimes when two threads both incf at same time it will only increment once, or when two threads decf at same time it will only decrement once, for minimal example run:randomly
*current-pprint-indentation*
will get incremented or decremented too much, you will either get that error as it reaches -1, or after finishing both threads it's value will be 5 or something rather than 1 as it should be.I added
*current-pprint-indentation*
to the let binding at the start ofpretty-print-hash-table
inciel.lisp
:so then each thread modifies it's own thread-local
*current-pprint-indentation*
. I don't know whether this is really a real issue as I should put some locking around debugging prints in multithreaded program anyway so the output doesn't get intermixed, but at least this way when I'm too lazy to add locking it's just some interleaved output rather than crashing