insaf021 opened a new pull request, #340:
URL: https://github.com/apache/commons-math/pull/340
jstack of 16 threads calling `GaussIntegratorFactory.legendre(n)` with
different `n` on one shared factory, 600 s in:
"pool-1-thread-3" RUNNABLE cpu=605610.03ms elapsed=613.34s
at java.util.TreeMap.getEntry(TreeMap.java:392)
at java.util.TreeMap.get(TreeMap.java:290)
at
o.a.c.math4.legacy.analysis.integration.gauss.BaseRuleFactory.getRule(BaseRuleFactory.java:63)
at
o.a.c.math4.legacy.analysis.integration.gauss.GaussIntegratorFactory.legendre(GaussIntegratorFactory.java:68)
Six threads were spinning there indefinitely. `getRule` reads and updates
the `pointsAndWeightsDouble` TreeMap without the instance lock that
`getRuleInternal` takes, so concurrent requests for different rules corrupt the
tree. Factories are shared in practice: `IterativeLegendreGaussIntegrator`
holds a static `GaussIntegratorFactory`.
`BaseRuleFactoryTest.testConcurrentCreation` only exercises `getRuleInternal`
with a single rule, which is why this went unnoticed. Making `getRule`
synchronized is the smallest fix; a cache hit is one lookup and two clones.
`PolynomialsUtils.createJacobiPolynomial` has the same kind of race on a
static cache. Its double-checked locking on a plain HashMap publishes the list
for a new `(v, w)` before seeding it, and `buildPolynomial` then locks the list
rather than `JACOBI_COEFFICIENTS`, so a racing caller extends a partially
seeded list. With 16 threads per fresh key, 335 of 32000 calls returned a wrong
polynomial (`P_3^(1,0)(1) = 5.8`, expected 4) and 29 threw. Lookup and seeding
now happen under the `JACOBI_COEFFICIENTS` lock, and `buildPolynomial` copies
the coefficients before releasing the list lock, as another thread may be
growing the same ArrayList.
`testJacobiConcurrentCreation` failed in 3 of 3 runs on master and passes
with the patch. The 3 `SimplexOptimizerTest` failures in the full legacy run
also occur on master (random inputs) and are unrelated.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]