Chame uma biblioteca compartilhada nativa não reentrante de vários encadeamentos Java

Eu tenho algum código Java que está chamando algum código nativo, originalmente escrito em Fortran, usando o JNA. (É uma biblioteca numérica, e muitas pessoas matemáticas fazem sua codificação em Fortran.) É compilada em um.so biblioteca, veja abaixo:

Fortran:https://github.com/mizzao/libmao/tree/master/src/main/fortranLigação de Java:https://github.com/mizzao/libmao/blob/master/src/main/java/net/andrewmao/probability/MvnPackDirect.java

Eu estava obtendo ótimos resultados com todas as unidades testadas no meu código, mas depois tentei usar o código de vários threads, e tudo começou a falhar com erros estranhos. Então eu olhei em algunscoisas sobre reentrada código Fortran e percebi que a biblioteca que eu estava usando tem o equivalente de algumas variáveis ​​globais (SAVE palavras-chave no Fortran, que lembram os valores das variáveis ​​quando uma função é chamada novamente:declaração fortran SAVE)

Por enquanto eu estou enrolando chamadas para a biblioteca emsynchronized blocos, mas isso está prejudicando o desempenho significativamente. Parece-me que seria preciso um esforço significativo para reprojetar a biblioteca para ser reentrante (ela tem alguns milhares de linhas de código numérico, e não está claro como os valores transitam quando as sub-rotinas estão sendo executadas). Alguém sabe a melhor maneira de contornar o problema? Minha imaginação sugere ...

Existe alguma maneira de obter cada encadeamento Java para carregar uma cópia separada da biblioteca compartilhada na memória, para que as variáveis ​​globais sejam efetivamente locais de encadeamento? É mesmo possível? Eu não tenho certeza sobre como a ligação direta ou a ligação de biblioteca do JNA funciona, e se há uma maneira de usá-lo dessa maneira.Ainda seria parafusado mesmo que fosse chamado de diferentes VMs? Como posso verificar para ter certeza?Existe alguma maneira de obtergfortran (gcc) compilar o código Fortran de forma reentrante?Existe alguma maneira rápida e suja para tornar o código Fortran reentrante? Eu pesquisei sobre oRECURSIVE keyword, que aparentemente mantém variáveis ​​na pilha, mas isso não parece ser compatível com o código existente.Alguma outra solução possível?

Confirmo que tudo está bem com várias VMs; isso faz sentido, já que eles não compartilham memória. Ainda um PITA e muito mais inconveniente do que tópicos embora.

questionAnswers(2)

yourAnswerToTheQuestion