I'm the author of Params::Classify. <email@example.com> has drawn my attention to this thread, after reporting the problem as rt.cpan.org #72743.
You're entirely correct that the Params::Classify XS is not thread safe. Until now I haven't bothered with the complication of making any of my modules thread safe, because it seemed that no one was using threads (or at least no one was using my modules with threads). This is the first bug report I've had about thread safety, and shows that I do after all need to put some work into it. I guess other people adopting Module::Runtime, after the eval/require scare earlier this year, has led to Params::Classify suddenly being used far more widely than it was previously.
The reason why Params::Classify hooks entersub op checking is so that it can compile calls to its functions (at least in the simple cases) down to custom ops. This avoids the rather large function call overhead, which is significant for functions as small as most of P:C's are. Last year I added the custom op code as a result of profiling my employer's code base, which uses P:C extensively in its type system and for parameter checking. The P:C functions were very hot, and the custom ops made a big difference.
In the next version I expect to replace the manual entersub hooking with use of the new cv_set_call_checker API (via Devel::CallChecker for backwards compatibility). This is an API that I got added to the core because I've ended up doing the entersub dance many times. Usually I use custom ops for semantic reasons, where I have an operation that doesn't really fit as a callable function. Params::Classify is the only place so far that I've used custom ops for performance.