Menu

#806 Allow RexxInstance->Terminate() to be called from any thread.

5.0.0
unread
nobody
None
none
1
2023-02-23
2022-07-20
No

For some applications, it can prove difficult to match up the thread on which an interpreter instance has been created so that the instance can be terminated. It should be possible to do this on any thread so that memory resources don't get leaked.

Related

Feature Requests: #806

Discussion

1 2 > >> (Page 1 of 2)
  • Rick McGuire

    Rick McGuire - 2022-07-20
    • Milestone: None --> 5.0.0
     
  • Rick McGuire

    Rick McGuire - 2022-07-20

    Code committed [r12480], docs committed [r12481]

     

    Related

    Commit: [r12480]
    Commit: [r12481]

  • Rony G. Flatscher

    Running the test case with this version hangs when the 63rd Rexx interpreter instance (RII) gets terminated. If that matters there is always an additional ("root") RII in the system which gets created first.

    (The test case is shaped such that sequentially 1,000 Rexx interpreter instances get created, run a program and get terminated.)

     
    • Rick McGuire

      Rick McGuire - 2022-07-21

      It should only hang if there's still an active thread running on the
      instance. In that case, it will wait for any active threads to terminate. A
      stack trace might help, but I'm pretty sure I know where it's waiting.

      Rick

      On Thu, Jul 21, 2022 at 6:02 AM Rony G. Flatscher orexx@users.sourceforge.net wrote:

      Running the test case with this version hangs when the 63rd Rexx
      interpreter instance (RII) gets terminated. If that matters there is always
      an additional ("root") RII in the system which gets created first.

      (The test case is shaped such that sequentially 1,000 Rexx interpreter
      instances get created, run a program and get terminated.)


      [feature-requests:#806] Allow RexxInstance->Terminate() to be called
      from any thread.

      Status: unread
      Milestone: 5.0.0
      Created: Wed Jul 20, 2022 07:22 PM UTC by Rick McGuire
      Last Updated: Wed Jul 20, 2022 07:33 PM UTC
      Owner: nobody

      For some applications, it can prove difficult to match up the thread on
      which an interpreter instance has been created so that the instance can be
      terminated. It should be possible to do this on any thread so that memory
      resources don't get leaked.


      Sent from sourceforge.net because you indicated interest in <
      https://sourceforge.net/p/oorexx/feature-requests/806/>

      To unsubscribe from further messages, please visit <
      https://sourceforge.net/auth/subscriptions/>

       

      Related

      Feature Requests: #806

      • Rony G. Flatscher

        Reran the test case and had it sit for a while and indeed it continues! Sometimes the next following engine termination will block, then a few ones go on before blocking for a short while. But it continues!

        Will try to terminate the Rexx engine from a separate Java thread such that the block in Rexx does not block the Java thread that issues the termination.

         
  • Rony G. Flatscher

    O.K. eventually the test case finished, all 1,000 engines got created and terminated.

    org.rexxla.bsf.engines.rexx.RexxCleanupRef:
    RexxCleanupRef [2022-07-21 12:58:59.237000000]
                 RefKind:         Instances:         Finalized: Not Yet Finalized:
    ------------------------------------------------------------------------------
    [TEST]..............: [               0] [               0] [               0]
    [REXX_ENGINE].......: [           1 002] [              57] [             945]
    [REXX_PROXY]........: [           9 000] [           8 534] [             466]
    [REXX_SCRIPT_ENGINE]: [           1 000] [             937] [              63]
    ------------------------------------------------------------------------------
    Totals..............: [          11 002] [           9 528] [           1 474]
    
    ---
    
    OREXX_REGISTRY related:
            OREXX_REGISTRY           ~items: 442
            OREXX_REGISTRY_REFCOUNTER~items: 442
    
    t_jsr223.rex: ooRexx 5.0.0 r12481 (21 Jul 2022) / BSF 641.20220717 / Java 17.0.3.1 (released: 2022-04-22), 64-bit (amd64) / Windows 10.0.19043
    
    1000 *** needed: 00:13:40.422000 (820422000micros): 820422 micros/engine
         ***         1.21888492 engines/sec
    
    
    --> count_rexx_gc: [0] count_java_gc: [0]
    
    --> L(oop again) 1000 times | J(ava gc) | R(exx gc) | <return> (end)
    

    Doing Java and Rexx gc() a couple of times got the engine and proxy references down to the minimum.

    The ooRexx .local objects all got garbage collected with this revision!

     
    • Rony G. Flatscher

      Further observations: terminating each RII from a separate Java thread still causes those blocks to occur which inhibit the creation of new RIIs!

      Here just to illustrate (each dot represents a separate RII which ran successfully a program that issues a dot). In this use case the RexxEngines get garbage collected by Java and terminated from the clean thread where the RexxEngine terminate() will create a separate Java thread to invoke Terminate() via JNI (watch out for interleaved output from different threads):

      org.rexxla.bsf.engines.rexx.RexxEngine@7960847b.terminate(): before jniRexxTerminateInterpreterInstance(000001763434EBC0)...
      org.rexxla.bsf.engines.rexx.RexxEngine@7960847b.terminate(): about to create & start a thread named: [RexxEngine.terminate_1_rii_ID_00000
      1763434EBC0]
      org.rexxla.bsf.engines.rexx.RexxEngine$1@d1d7eb7.terminate(): AFTER jniRexxTerminateInterpreterInstance(000001763434EBC0)
      .............................................................org.rexxla.bsf.engines.rexx.RexxEngine@44010e8e.terminate(): before jniRexxT
      erminateInterpreterInstance(0000017634780710)...
      org.rexxla.bsf.engines.rexx.RexxEngine@44010e8e.terminate(): about to create & start a thread named: [RexxEngine.terminate_2_rii_ID_00000
      17634780710]
      org.rexxla.bsf.engines.rexx.RexxEngine$1@37768cad.terminate(): AFTER jniRexxTerminateInterpreterInstance(0000017634780710)
      org.rexxla.bsf.engines.rexx.RexxEngine@4ac6f87e.terminate(): before jniRexxTerminateInterpreterInstance(00000176343E5410)...
      org.rexxla.bsf.engines.rexx.RexxEngine@4ac6f87e.terminate(): about to create & start a thread named: [RexxEngine.terminate_3_rii_ID_00000
      176343E5410]
      org.rexxla.bsf.engines.rexx.RexxEngine$1@1f7e9008.terminate(): AFTER jniRexxTerminateInterpreterInstance(00000176343E5410)
      org.rexxla.bsf.engines.rexx.RexxEngine@4ef965fe.terminate(): before jniRexxTerminateInterpreterInstance(0000017660098A10)...
      org.rexxla.bsf.engines.rexx.RexxEngine@4ef965fe.terminate(): about to create & start a thread named: [RexxEngine.terminate_4_rii_ID_00000
      17660098A10]
      .org.rexxla.bsf.engines.rexx.RexxEngine$1@46b8adab.terminate(): AFTER jniRexxTerminateInterpreterInstance(0000017660098A10)
      org.rexxla.bsf.engines.rexx.RexxEngine@bfbf245.terminate(): before jniRexxTerminateInterpreterInstance(0000017634552770)...
      org.rexxla.bsf.engines.rexx.RexxEngine@bfbf245.terminate(): about to create & start a thread named: [RexxEngine.terminate_5_rii_ID_000001
      7634552770]
      org.rexxla.bsf.engines.rexx.RexxEngine$1@5a7e2681.terminate(): AFTER jniRexxTerminateInterpreterInstance(0000017634552770)
      org.rexxla.bsf.engines.rexx.RexxEngine@47c2e8ca.terminate(): before jniRexxTerminateInterpreterInstance(0000017634606240)...
      org.rexxla.bsf.engines.rexx.RexxEngine@47c2e8ca.terminate(): about to create & start a thread named: [RexxEngine.terminate_6_rii_ID_00000
      17634606240]
      org.rexxla.bsf.engines.rexx.RexxEngine$1@3788b783.terminate(): AFTER jniRexxTerminateInterpreterInstance(0000017634606240)
      org.rexxla.bsf.engines.rexx.RexxEngine@3a3afd44.terminate(): before jniRexxTerminateInterpreterInstance(000001765FF0A4C0)...
      org.rexxla.bsf.engines.rexx.RexxEngine@3a3afd44.terminate(): about to create & start a thread named: [RexxEngine.terminate_7_rii_ID_00000
      1765FF0A4C0]
      
       
      • Rick McGuire

        Rick McGuire - 2022-07-21

        Each termination call is going to run a garbage collection and call uninit
        methods. Since these are activities that are cooperatively multitasked,
        they might take some time to complete, particularly if the uninit methods
        make calls to methods written in native code. Depending on how much live
        data there is, this can take a while.

        Rick

        On Thu, Jul 21, 2022 at 7:33 AM Rony G. Flatscher orexx@users.sourceforge.net wrote:

        Further observations: terminating each RII from a separate Java thread
        still causes those blocks to occur which inhibit the creation of new RIIs!

        Here just to illustrate (each dot represents a separate RII which ran
        successfully a program that issues a dot). In this use case the RexxEngines
        get garbage collected by Java and terminated from the clean thread where
        the RexxEngine terminate() will create a separate Java thread to invoke
        Terminate() via JNI (watch out for interleaved output from different
        threads):

        ~~~
        org.rexxla.bsf.engines.rexx.RexxEngine@7960847b.terminate(): before
        jniRexxTerminateInterpreterInstance(000001763434EBC0)...
        org.rexxla.bsf.engines.rexx.RexxEngine@7960847b.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_1_rii_ID_00000
        1763434EBC0]

        org.rexxla.bsf.engines.rexx.RexxEngine$1@d1d7eb7.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(000001763434EBC0)

        .............................................................org.rexxla.bsf.engines.rexx.RexxEngine@44010e8e.terminate():
        before jniRexxT
        erminateInterpreterInstance(0000017634780710)...
        org.rexxla.bsf.engines.rexx.RexxEngine@44010e8e.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_2_rii_ID_00000
        17634780710]

        org.rexxla.bsf.engines.rexx.RexxEngine$1@37768cad.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(0000017634780710)
        org.rexxla.bsf.engines.rexx.RexxEngine@4ac6f87e.terminate(): before
        jniRexxTerminateInterpreterInstance(00000176343E5410)...
        org.rexxla.bsf.engines.rexx.RexxEngine@4ac6f87e.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_3_rii_ID_00000
        176343E5410]

        org.rexxla.bsf.engines.rexx.RexxEngine$1@1f7e9008.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(00000176343E5410)
        org.rexxla.bsf.engines.rexx.RexxEngine@4ef965fe.terminate(): before
        jniRexxTerminateInterpreterInstance(0000017660098A10)...
        org.rexxla.bsf.engines.rexx.RexxEngine@4ef965fe.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_4_rii_ID_00000
        17660098A10]

        .org.rexxla.bsf.engines.rexx.RexxEngine$1@46b8adab.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(0000017660098A10)
        org.rexxla.bsf.engines.rexx.RexxEngine@bfbf245.terminate(): before
        jniRexxTerminateInterpreterInstance(0000017634552770)...
        org.rexxla.bsf.engines.rexx.RexxEngine@bfbf245.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_5_rii_ID_000001
        7634552770]

        org.rexxla.bsf.engines.rexx.RexxEngine$1@5a7e2681.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(0000017634552770)
        org.rexxla.bsf.engines.rexx.RexxEngine@47c2e8ca.terminate(): before
        jniRexxTerminateInterpreterInstance(0000017634606240)...
        org.rexxla.bsf.engines.rexx.RexxEngine@47c2e8ca.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_6_rii_ID_00000
        17634606240]

        org.rexxla.bsf.engines.rexx.RexxEngine$1@3788b783.terminate(): AFTER
        jniRexxTerminateInterpreterInstance(0000017634606240)
        org.rexxla.bsf.engines.rexx.RexxEngine@3a3afd44.terminate(): before
        jniRexxTerminateInterpreterInstance(000001765FF0A4C0)...
        org.rexxla.bsf.engines.rexx.RexxEngine@3a3afd44.terminate(): about to
        create & start a thread named: [RexxEngine.terminate_7_rii_ID_00000
        1765FF0A4C0]

        ~~~


        [feature-requests:#806] Allow RexxInstance->Terminate() to be called
        from any thread.

        Status: unread
        Milestone: 5.0.0
        Created: Wed Jul 20, 2022 07:22 PM UTC by Rick McGuire
        Last Updated: Thu Jul 21, 2022 11:06 AM UTC
        Owner: nobody

        For some applications, it can prove difficult to match up the thread on
        which an interpreter instance has been created so that the instance can be
        terminated. It should be possible to do this on any thread so that memory
        resources don't get leaked.


        Sent from sourceforge.net because you indicated interest in <
        https://sourceforge.net/p/oorexx/feature-requests/806/>

        To unsubscribe from further messages, please visit <
        https://sourceforge.net/auth/subscriptions/>

         

        Related

        Feature Requests: #806

        • Rony G. Flatscher

          It should not take between 50 times longer than before judging by the number of RII/sec.

          Will post three more stack traces from the same process just did a "Break all" at different point in times. There is one stack trace for a RII termination in it.

          Please advise if I can try to come up with more information.

           
          • Rony G. Flatscher

            Here the three stack traces (process is currently halted):

                win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
                user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
            >   rexx.dll!waitHandle(void * s=0x0000000000000648, unsigned int timeOut=50, bool bypassMessageLoop=false) Line 290    C++
                rexx.dll!SysSemaphore::wait(unsigned int timeout=50) Line 74    C++
                rexx.dll!Activity::waitForDispatch() Line 268   C++
                rexx.dll!ActivityManager::addWaitingActivity(Activity * waitingAct=0x000002af3816a460, bool release=true) Line 201  C++
                rexx.dll!ActivityManager::relinquishIfNeeded(Activity * activity=0x000002af3816a460) Line 140   C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002af37d02020, RexxString * name=0x000002af374292d0, RexxObject * * _arglist=0x0000000000000000, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 588 C++
                rexx.dll!RexxCode::run(Activity * activity=0x000002af3816a460, MethodClass * method=0x000002af37676a10, RexxObject * receiver=0x000002af37d02020, RexxString * msgname=0x000002af374292d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 211  C++
                rexx.dll!MethodClass::run(Activity * activity=0x000002af3816a460, RexxObject * receiver=0x000002af37d02020, RexxString * msgname=0x000002af374292d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 172   C++
                rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002af374292d0, RexxObject * * arguments=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 902   C++
                rexx.dll!RexxObject::sendMessage(RexxString * message=0x000002af374292d0, ProtectedObject & result={...}) Line 509  C++
                rexx.dll!RexxObject::uninit() Line 2580 C++
                rexx.dll!UninitDispatcher::run() Line 55    C++
                rexx.dll!NativeActivation::run(TrappingDispatcher & dispatcher={...}) Line 1743 C++
                rexx.dll!Activity::run(TrappingDispatcher & target={...}) Line 3378 C++
                rexx.dll!MemoryObject::runUninits() Line 373    C++
                rexx.dll!MemoryObject::collectAndUninit(bool clearStack=false) Line 315 C++
                rexx.dll!InterpreterInstance::terminate() Line 513  C++
                rexx.dll!Terminate(RexxInstance_ * c=0x000002af37843600) Line 58    C++
                BSF4ooRexx.dll!RexxInstance_::Terminate() Line 701  C++
                BSF4ooRexx.dll!impl_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002af62a9ab98, _jobject * jobj=0x000000f05f47f380, _jstring * j_rii_ID=0x000000f05f47f378) Line 9605 C++
                BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002af62a9ab98, _jobject * jobj=0x000000f05f47f380, _jstring * j_rii_ID=0x000000f05f47f378) Line 9627 C++
                000002af415ad621()  Unknown
                000002af62a9ab98()  Unknown
                000000f05f47f380()  Unknown
                000000f05f47f378()  Unknown
            
            -------------------------
            
            Main (Rexx) thread
            
                win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
                user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
            >   rexx.dll!waitHandle(void * s=0x0000000000000158, bool bypassMessageLoop=false) Line 213 C++
                rexx.dll!SysMutex::request() Line 120   C++
                rexx.dll!ActivityManager::lockKernel() Line 84  C++
                rexx.dll!Activity::waitForKernel() Line 2180    C++
                rexx.dll!ActivityManager::addWaitingApiActivity(Activity * waitingAct=0x000002af3818e3d0) Line 280  C++
                rexx.dll!Activity::requestApiAccess() Line 2166 C++
                rexx.dll!Activity::enterCurrentThread() Line 318    C++
                rexx.dll!ApiContext::ApiContext(RexxThreadContext_ * c=0x000002af3818e3f8) Line 76  C++
                rexx.dll!ArraySize(RexxThreadContext_ * c=0x000002af3818e3f8, _RexxArrayObject * a=0x000002af37d8db00) Line 1409    C++
                BSF4ooRexx.dll!RexxThreadContext_::ArraySize(_RexxArrayObject * ao=0x000002af37d8db00) Line 1184    C++
                BSF4ooRexx.dll!RexxCallContext_::ArraySize(_RexxArrayObject * ao=0x000002af37d8db00) Line 2633  C++
                BSF4ooRexx.dll!BSF_impl(RexxCallContext_ * context=0x000000f05e2e9488, _RexxArrayObject * argArray=0x000002af37d8db00) Line 6438    C++
                BSF4ooRexx.dll!BSF(RexxCallContext_ * context=0x000000f05e2e9488, ValueDescriptor * arguments=0x000000f05e2e9370) Line 6409 C++
                rexx.dll!NativeActivation::callNativeRoutine(RoutineClass * _routine=0x000002af37619030, NativeRoutine * _code=0x000002af37618ff0, RexxString * functionName=0x000002af37618fa0, RexxObject * * list=0x000002af37e24940, unsigned __int64 count=4, ProtectedObject & resultObj={...}) Line 1423 C++
                rexx.dll!NativeRoutine::call(Activity * activity=0x000002af3818e3d0, RoutineClass * routine=0x000002af37619030, RexxString * functionName=0x000002af37618fa0, RexxObject * * argPtr=0x000002af37e24940, unsigned __int64 count=4, ProtectedObject & result={...}) Line 356  C++
                rexx.dll!RoutineClass::callWithRexx(ArrayClass * args=0x000002af37e248e0) Line 228  C++
                rexx.dll!CPPCode::run(Activity * activity=0x000002af3818e3d0, MethodClass * method=0x000002af374e0790, RexxObject * receiver=0x000002af37619030, RexxString * messageName=0x000002af37612fd0, RexxObject * * argPtr=0x000002af384cd198, unsigned __int64 count=1, ProtectedObject & result={...}) Line 174  C++
                rexx.dll!MethodClass::run(Activity * activity=0x000002af3818e3d0, RexxObject * receiver=0x000002af37619030, RexxString * msgname=0x000002af37612fd0, RexxObject * * argPtr=0x000002af384cd198, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
                rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002af37612fd0, RexxObject * * arguments=0x000002af384cd198, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
                rexx.dll!ExpressionStack::send(RexxString * message=0x000002af37612fd0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
                rexx.dll!RexxExpressionMessage::evaluate(RexxActivation * context=0x000002af381976f0, ExpressionStack * stack=0x000002af38197858) Line 191  C++
                rexx.dll!RexxInstruction::evaluateArguments(RexxActivation * context=0x000002af381976f0, ExpressionStack * stack=0x000002af38197858, RexxInternalObject * * argArray=0x000002af3767f698, unsigned __int64 argCount=1) Line 154  C++
                rexx.dll!RexxExpressionFunction::evaluate(RexxActivation * context=0x000002af381976f0, ExpressionStack * stack=0x000002af38197858) Line 187 C++
                rexx.dll!RexxInstructionExpression::evaluateExpression(RexxActivation * context=0x000002af381976f0, ExpressionStack * stack=0x000002af38197858) Line 229    C++
                rexx.dll!RexxInstructionReturn::execute(RexxActivation * context=0x000002af381976f0, ExpressionStack * stack=0x000002af38197858) Line 72    C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002af379a1150, RexxString * name=0x000002af373fd580, RexxObject * * _arglist=0x000000f05e2e9d08, unsigned __int64 _argcount=2, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
                rexx.dll!RexxCode::run(Activity * activity=0x000002af3818e3d0, MethodClass * method=0x000002af3767ff70, RexxObject * receiver=0x000002af379a1150, RexxString * msgname=0x000002af373fd580, RexxObject * * argPtr=0x000000f05e2e9d08, unsigned __int64 argcount=2, ProtectedObject & result={...}) Line 211  C++
                rexx.dll!MethodClass::run(Activity * activity=0x000002af3818e3d0, RexxObject * receiver=0x000002af379a1150, RexxString * msgname=0x000002af373fd580, RexxObject * * argPtr=0x000000f05e2e9d08, unsigned __int64 count=2, ProtectedObject & result={...}) Line 172   C++
                rexx.dll!RexxObject::processUnknown(RexxErrorCodes error=Error_No_method_name, RexxString * messageName=0x000002af3762ba50, RexxObject * * arguments=0x000002af37e61800, unsigned __int64 count=1, ProtectedObject & result={...}) Line 1022    C++
                rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002af3762ba50, RexxObject * * arguments=0x000002af37e61800, unsigned __int64 count=1, ProtectedObject & result={...}) Line 907   C++
                rexx.dll!RexxActivation::forward(RexxObject * target=0x000002af379a1150, RexxString * message=0x000002af3762ba50, RexxClass * superClass=0x0000000000000000, RexxObject * * arguments=0x000002af37e61800, unsigned __int64 argcount=1, bool continuing=false) Line 1275 C++
                rexx.dll!RexxInstructionForward::execute(RexxActivation * context=0x000002af381a3380, ExpressionStack * stack=0x000002af381a34e8) Line 242  C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002af379ab350, RexxString * name=0x000002af373fd580, RexxObject * * _arglist=0x000000f05e2ea1c8, unsigned __int64 _argcount=2, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
                rexx.dll!RexxCode::run(Activity * activity=0x000002af3818e3d0, MethodClass * method=0x000002af37663550, RexxObject * receiver=0x000002af379ab350, RexxString * msgname=0x000002af373fd580, RexxObject * * argPtr=0x000000f05e2ea1c8, unsigned __int64 argcount=2, ProtectedObject & result={...}) Line 211  C++
                rexx.dll!MethodClass::run(Activity * activity=0x000002af3818e3d0, RexxObject * receiver=0x000002af379ab350, RexxString * msgname=0x000002af373fd580, RexxObject * * argPtr=0x000000f05e2ea1c8, unsigned __int64 count=2, ProtectedObject & result={...}) Line 172   C++
                rexx.dll!RexxObject::processUnknown(RexxErrorCodes error=Error_No_method_name, RexxString * messageName=0x000002af3762ba50, RexxObject * * arguments=0x000002af384cd008, unsigned __int64 count=1, ProtectedObject & result={...}) Line 1022    C++
                rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002af3762ba50, RexxObject * * arguments=0x000002af384cd008, unsigned __int64 count=1, ProtectedObject & result={...}) Line 907   C++
                rexx.dll!ExpressionStack::send(RexxString * message=0x000002af3762ba50, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
                rexx.dll!RexxExpressionMessage::evaluate(RexxActivation * context=0x000002af381720f0, ExpressionStack * stack=0x000002af38172258) Line 191  C++
                rexx.dll!RexxInstructionAssignment::execute(RexxActivation * context=0x000002af381720f0, ExpressionStack * stack=0x000002af38172258) Line 129   C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000002af376165a0, RexxObject * * _arglist=0x000002af384ccec8, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
                rexx.dll!RexxCode::call(Activity * activity=0x000002af3818e3d0, RoutineClass * routine=0x000002af377faaa0, RexxString * routineName=0x000002af376165a0, RexxObject * * argPtr=0x000002af384ccec8, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c2110, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
                rexx.dll!RoutineClass::call(Activity * activity=0x000002af3818e3d0, RexxString * routineName=0x000002af376165a0, RexxObject * * argPtr=0x000002af384ccec8, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c2110, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 194 C++
                rexx.dll!RexxActivation::externalCall(RexxString * target=0x000002af376165a0, RoutineClass * routine=0x000002af377faaa0, RexxObject * * arguments=0x000002af384ccec8, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c2110, ProtectedObject & resultObj={...}) Line 2903   C++
                rexx.dll!RexxInstructionCall::execute(RexxActivation * context=0x000002af38168820, ExpressionStack * stack=0x000002af38168988) Line 173 C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000002af37607570, RexxObject * * _arglist=0x0000000000000000, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
                rexx.dll!RexxCode::call(Activity * activity=0x000002af3818e3d0, RoutineClass * routine=0x000002af37801140, RexxString * routineName=0x000002af37607570, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c1f20, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
                rexx.dll!RoutineClass::call(Activity * activity=0x000002af3818e3d0, RexxString * routineName=0x000002af37607570, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c1f20, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 194 C++
                rexx.dll!PackageClass::runProlog(Activity * activity=0x000002af3818e3d0) Line 2101  C++
                rexx.dll!InterpreterInstance::loadRequires(Activity * activity=0x000002af3818e3d0, RexxString * shortName=0x000002af37f1a1f0, RexxString * fullName=0x000002af37f5a9c0) Line 944    C++
                rexx.dll!PackageClass::newRexx(RexxObject * * init_args=0x000002af384cce40, unsigned __int64 argCount=1) Line 148   C++
                rexx.dll!CPPCode::run(Activity * activity=0x000002af3818e3d0, MethodClass * method=0x000002af374e7860, RexxObject * receiver=0x000002af374e27f0, RexxString * messageName=0x000002af37f69640, RexxObject * * argPtr=0x000002af384cce30, unsigned __int64 count=1, ProtectedObject & result={...}) Line 147  C++
                rexx.dll!MethodClass::run(Activity * activity=0x000002af3818e3d0, RexxObject * receiver=0x000002af374e27f0, RexxString * msgname=0x000002af37f69640, RexxObject * * argPtr=0x000002af384cce30, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
                rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002af37f69640, RexxObject * * arguments=0x000002af384cce30, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
                rexx.dll!ExpressionStack::send(RexxString * message=0x000002af37f69640, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
                rexx.dll!RexxExpressionMessage::evaluate(RexxActivation * context=0x000002af3816a210, ExpressionStack * stack=0x000002af3816a378) Line 191  C++
                rexx.dll!RexxInstruction::evaluateArguments(RexxActivation * context=0x000002af3816a210, ExpressionStack * stack=0x000002af3816a378, RexxInternalObject * * argArray=0x000002af38088630, unsigned __int64 argCount=1) Line 154  C++
                rexx.dll!RexxInstructionMessage::execute(RexxActivation * context=0x000002af3816a210, ExpressionStack * stack=0x000002af3816a378) Line 183  C++
                rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000002af373bbac0, RexxObject * * _arglist=0x000002af37ffd120, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
                rexx.dll!RexxCode::call(Activity * activity=0x000002af3818e3d0, RoutineClass * routine=0x000002af37809480, RexxString * routineName=0x000002af373bbac0, RexxObject * * argPtr=0x000002af37ffd120, unsigned __int64 argcount=0, RexxString * calltype=0x000002af375c2110, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
                rexx.dll!RexxCode::call(Activity * activity=0x000002af3818e3d0, RoutineClass * routine=0x000002af37809480, RexxString * msgname=0x000002af373bbac0, RexxObject * * argPtr=0x000002af37ffd120, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 159 C++
                rexx.dll!RoutineClass::call(Activity * activity=0x000002af3818e3d0, RexxString * routineName=0x000002af373bbac0, RexxObject * * argPtr=0x000002af37ffd120, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 170    C++
                rexx.dll!CallRoutineDispatcher::run() Line 212  C++
                rexx.dll!NativeActivation::run(ActivityDispatcher & dispatcher={...}) Line 1641 C++
                rexx.dll!Activity::run(ActivityDispatcher & target={...}) Line 3305 C++
                rexx.dll!CallRoutine(RexxThreadContext_ * c=0x000002af3818e3f8, _RexxRoutineObject * r=0x000002af37809480, _RexxArrayObject * a=0x000002af37ffd0c0) Line 500    C++
                BSF4ooRexx.dll!RexxThreadContext_::CallRoutine(_RexxRoutineObject * m=0x000002af37809480, _RexxArrayObject * a=0x000002af37ffd0c0) Line 862 C++
                BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxRunProgram(JNIEnv_ * env=0x000002af386d4ce8, _jobject * raj=0x000000f05e2eb630, _jstring * j_rii_ID=0x000000f05e2eb628, long invocationType=2, _jstring * j_fileName=0x000000f05e2eb618, _jstring * j_programData=0x000000f05e2eb610, _jobjectArray * j_args=0x0000000000000000) Line 8732   C++
                000002af415ad621()  Unknown
                000002af386d4ce8()  Unknown
                000000f05e2eb630()  Unknown
                000000f05e2eb628()  Unknown
                00007ffe00000002()  Unknown
                000000f05e2eb618()  Unknown
                000000f05e2eb610()  Unknown
            
            -------------------------
            
            Main (ooRexx) thread:
            
                win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
                user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
            >   rexx.dll!waitHandle(void * s=0x0000000000000158, bool bypassMessageLoop=false) Line 213 C++
                rexx.dll!SysMutex::request() Line 120   C++
                rexx.dll!ActivityManager::lockKernel() Line 84  C++
                rexx.dll!Activity::waitForKernel() Line 2180    C++
                rexx.dll!ActivityManager::addWaitingApiActivity(Activity * waitingAct=0x000002af3818e3d0) Line 280  C++
                rexx.dll!Activity::requestApiAccess() Line 2166 C++
                rexx.dll!Activity::enterCurrentThread() Line 318    C++
                rexx.dll!ApiContext::ApiContext(RexxThreadContext_ * c=0x000002af3818e3f8) Line 76  C++
                rexx.dll!CheckCondition(RexxThreadContext_ * c=0x000002af3818e3f8) Line 1931    C++
                BSF4ooRexx.dll!RexxThreadContext_::CheckCondition() Line 1383   C++
                BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxSendMessageToRexxObject(JNIEnv_ * env=0x000002af386d4ce8, _jobject * jobj=0x000000f05e2eb508, _jstring * j_rii_ID=0x000000f05e2eb510, _jstring * j_obj_ID=0x000000f05e2eb518, _jstring * j_userData_ID=0x0000000000000000, _jstring * j_javaObjectBean=0x0000000000000000, _jstring * j_methodObjectBean=0x0000000000000000, _jstring * j_messageName=0x000000f05e2eb550, _jstring * j_methodDescription=0x0000000000000000, _jobjectArray * j_args=0x000000f05e2eb560, _jstring * j_returnType=0x0000000000000000) Line 9251    C++
                000002af490b5b5a()  Unknown
                000002af386d4ce8()  Unknown
                000000f05e2eb508()  Unknown
                000000f05e2eb510()  Unknown
                000000f05e2eb518()  Unknown
            
            
            -------------------------
            
             
  • Rony G. Flatscher

    Think I got a meaningful stack trace:

        win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
        user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
    >   rexx.dll!waitHandle(void * s=0x0000000000000148, bool bypassMessageLoop=false) Line 213 C++
        rexx.dll!SysMutex::request() Line 120   C++
        rexx.dll!ActivityManager::lockKernel() Line 84  C++
        rexx.dll!Activity::waitForKernel() Line 2180    C++
        rexx.dll!ActivityManager::addWaitingActivity(Activity * waitingAct=0x000001d57d94aa90, bool release=false) Line 215 C++
        rexx.dll!Activity::requestAccess() Line 2147    C++
        rexx.dll!NativeActivation::callNativeRoutine(RoutineClass * _routine=0x000001d551afdc40, NativeRoutine * _code=0x000001d551afdc00, RexxString * functionName=0x000001d551af62d0, RexxObject * * list=0x000001d552850958, unsigned __int64 count=0, ProtectedObject & resultObj={...}) Line 1426 C++
        rexx.dll!NativeRoutine::call(Activity * activity=0x000001d57d94aa90, RoutineClass * routine=0x000001d551afdc40, RexxString * functionName=0x000001d551af62d0, RexxObject * * argPtr=0x000001d552850958, unsigned __int64 count=0, ProtectedObject & result={...}) Line 356  C++
        rexx.dll!BaseCode::call(Activity * activity=0x000001d57d94aa90, RoutineClass * routine=0x000001d551afdc40, RexxString * msgname=0x000001d551af62d0, RexxObject * * arguments=0x000001d552850958, unsigned __int64 argcount=0, RexxString * ct=0x000001d551a9c700, RexxString * env=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 94  C++
        rexx.dll!RoutineClass::call(Activity * activity=0x000001d57d94aa90, RexxString * routineName=0x000001d551af62d0, RexxObject * * argPtr=0x000001d552850958, unsigned __int64 argcount=0, RexxString * calltype=0x000001d551a9c700, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 194 C++
        rexx.dll!RexxActivation::externalCall(RexxString * target=0x000001d551af62d0, RoutineClass * routine=0x000001d551afdc40, RexxObject * * arguments=0x000001d552850958, unsigned __int64 argcount=0, RexxString * calltype=0x000001d551a9c700, ProtectedObject & resultObj={...}) Line 2903   C++
        rexx.dll!RexxExpressionFunction::evaluate(RexxActivation * context=0x000001d552672fd0, ExpressionStack * stack=0x000001d552673138) Line 192 C++
        rexx.dll!RexxBinaryOperator::evaluate(RexxActivation * context=0x000001d552672fd0, ExpressionStack * stack=0x000001d552673138) Line 182 C++
        rexx.dll!RexxInstructionIf::execute(RexxActivation * context=0x000001d552672fd0, ExpressionStack * stack=0x000001d552673138) Line 139   C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000001d551aeb580, RexxObject * * _arglist=0x0000000000000000, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::call(Activity * activity=0x000001d57d94aa90, RoutineClass * routine=0x000001d551ce5150, RexxString * routineName=0x000001d551aeb580, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, RexxString * calltype=0x000001d551a9cf20, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
        rexx.dll!RoutineClass::call(Activity * activity=0x000001d57d94aa90, RexxString * routineName=0x000001d551aeb580, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, RexxString * calltype=0x000001d551a9cf20, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 194 C++
        rexx.dll!PackageClass::runProlog(Activity * activity=0x000001d57d94aa90) Line 2101  C++
        rexx.dll!InterpreterInstance::loadRequires(Activity * activity=0x000001d57d94aa90, RexxString * shortName=0x000001d57da3ac80, RexxString * fullName=0x000001d552690c30) Line 944    C++
        rexx.dll!PackageClass::newRexx(RexxObject * * init_args=0x000001d5528508d0, unsigned __int64 argCount=1) Line 148   C++
        rexx.dll!CPPCode::run(Activity * activity=0x000001d57d94aa90, MethodClass * method=0x000001d5519c2860, RexxObject * receiver=0x000001d5519bd7f0, RexxString * messageName=0x000001d57da3ac30, RexxObject * * argPtr=0x000001d5528508c0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 147  C++
        rexx.dll!MethodClass::run(Activity * activity=0x000001d57d94aa90, RexxObject * receiver=0x000001d5519bd7f0, RexxString * msgname=0x000001d57da3ac30, RexxObject * * argPtr=0x000001d5528508c0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000001d57da3ac30, RexxObject * * arguments=0x000001d5528508c0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!ExpressionStack::send(RexxString * message=0x000001d57da3ac30, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
        rexx.dll!RexxExpressionMessage::evaluate(RexxActivation * context=0x000001d57da3d270, ExpressionStack * stack=0x000001d57da3d3d8) Line 191  C++
        rexx.dll!RexxInstruction::evaluateArguments(RexxActivation * context=0x000001d57da3d270, ExpressionStack * stack=0x000001d57da3d3d8, RexxInternalObject * * argArray=0x000001d57da3af30, unsigned __int64 argCount=1) Line 154  C++
        rexx.dll!RexxInstructionMessage::execute(RexxActivation * context=0x000001d57da3d270, ExpressionStack * stack=0x000001d57da3d3d8) Line 183  C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000001d551896ac0, RexxObject * * _arglist=0x000001d57da2cfc0, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::call(Activity * activity=0x000001d57d94aa90, RoutineClass * routine=0x000001d57da3b0e0, RexxString * routineName=0x000001d551896ac0, RexxObject * * argPtr=0x000001d57da2cfc0, unsigned __int64 argcount=0, RexxString * calltype=0x000001d551a9d110, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
        rexx.dll!RexxCode::call(Activity * activity=0x000001d57d94aa90, RoutineClass * routine=0x000001d57da3b0e0, RexxString * msgname=0x000001d551896ac0, RexxObject * * argPtr=0x000001d57da2cfc0, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 159 C++
        rexx.dll!RoutineClass::call(Activity * activity=0x000001d57d94aa90, RexxString * routineName=0x000001d551896ac0, RexxObject * * argPtr=0x000001d57da2cfc0, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 170    C++
        rexx.dll!CallRoutineDispatcher::run() Line 212  C++
        rexx.dll!NativeActivation::run(ActivityDispatcher & dispatcher={...}) Line 1641 C++
        rexx.dll!Activity::run(ActivityDispatcher & target={...}) Line 3305 C++
        rexx.dll!CallRoutine(RexxThreadContext_ * c=0x000001d57d94aab8, _RexxRoutineObject * r=0x000001d57da3b0e0, _RexxArrayObject * a=0x000001d57da2cf60) Line 500    C++
        BSF4ooRexx.dll!00007ffe95747862()   Unknown
        000001d55c18d621()  Unknown
        000001d5533beaa0()  Unknown
        000001d57cc2bde8()  Unknown
        0000001004d8b618()  Unknown
        0000000689c00f90()  Unknown
        0000001004d8b648()  Unknown
        0000001004d8b640()  Unknown
    
     
  • Rony G. Flatscher

    Testing new r12482: blocks still occur, here the stack traces that I could get (process on hold):

        win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
        user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
    >   rexx.dll!waitHandle(void * s=0x0000000000000720, unsigned int timeOut=50, bool bypassMessageLoop=false) Line 290    C++
        rexx.dll!SysSemaphore::wait(unsigned int timeout=50) Line 74    C++
        rexx.dll!Activity::waitForDispatch() Line 268   C++
        rexx.dll!ActivityManager::addWaitingActivity(Activity * waitingAct=0x000002631c98ce20, bool release=true) Line 201  C++
        rexx.dll!ActivityManager::relinquishIfNeeded(Activity * activity=0x000002631c98ce20) Line 140   C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002636fcc3c70, RexxString * name=0x000002636f6862d0, RexxObject * * _arglist=0x0000000000000000, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 588 C++
        rexx.dll!RexxCode::run(Activity * activity=0x000002631c98ce20, MethodClass * method=0x000002636f9361b0, RexxObject * receiver=0x000002636fcc3c70, RexxString * msgname=0x000002636f6862d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x000002631c98ce20, RexxObject * receiver=0x000002636fcc3c70, RexxString * msgname=0x000002636f6862d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636f6862d0, RexxObject * * arguments=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!RexxObject::sendMessage(RexxString * message=0x000002636f6862d0, ProtectedObject & result={...}) Line 509  C++
        rexx.dll!RexxObject::uninit() Line 2580 C++
        rexx.dll!UninitDispatcher::run() Line 55    C++
        rexx.dll!NativeActivation::run(TrappingDispatcher & dispatcher={...}) Line 1743 C++
        rexx.dll!Activity::run(TrappingDispatcher & target={...}) Line 3378 C++
        rexx.dll!MemoryObject::runUninits() Line 373    C++
        rexx.dll!MemoryObject::collectAndUninit(bool clearStack=false) Line 315 C++
        rexx.dll!InterpreterInstance::terminate() Line 515  C++
        rexx.dll!Terminate(RexxInstance_ * c=0x000002631d0153e0) Line 58    C++
        BSF4ooRexx.dll!RexxInstance_::Terminate() Line 701  C++
        BSF4ooRexx.dll!impl_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002631be5dc18, _jobject * jobj=0x000000c9cb3ff1f0, _jstring * j_rii_ID=0x000000c9cb3ff1e8) Line 9605 C++
        BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002631be5dc18, _jobject * jobj=0x000000c9cb3ff1f0, _jstring * j_rii_ID=0x000000c9cb3ff1e8) Line 9627 C++
        000002630000d621()  Unknown
        000002631be5dc18()  Unknown
        000000c9cb3ff1f0()  Unknown
        000000c9cb3ff1e8()  Unknown
    
    ------------------------
    
    
        win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
        user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
    >   rexx.dll!waitHandle(void * s=0x0000000000000964, unsigned int timeOut=50, bool bypassMessageLoop=false) Line 290    C++
        rexx.dll!SysSemaphore::wait(unsigned int timeout=50) Line 74    C++
        rexx.dll!Activity::waitForDispatch() Line 268   C++
        rexx.dll!ActivityManager::addWaitingActivity(Activity * waitingAct=0x000002637042e6e0, bool release=true) Line 201  C++
        rexx.dll!ActivityManager::relinquishIfNeeded(Activity * activity=0x000002637042e6e0) Line 140   C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002631c6324f0, RexxString * name=0x000002636f6862d0, RexxObject * * _arglist=0x0000000000000000, unsigned __int64 _argcount=0, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 588 C++
        rexx.dll!RexxCode::run(Activity * activity=0x000002637042e6e0, MethodClass * method=0x000002636f8dba10, RexxObject * receiver=0x000002631c6324f0, RexxString * msgname=0x000002636f6862d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 argcount=0, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x000002637042e6e0, RexxObject * receiver=0x000002631c6324f0, RexxString * msgname=0x000002636f6862d0, RexxObject * * argPtr=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636f6862d0, RexxObject * * arguments=0x0000000000000000, unsigned __int64 count=0, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!RexxObject::sendMessage(RexxString * message=0x000002636f6862d0, ProtectedObject & result={...}) Line 509  C++
        rexx.dll!RexxObject::uninit() Line 2580 C++
        rexx.dll!UninitDispatcher::run() Line 55    C++
        rexx.dll!NativeActivation::run(TrappingDispatcher & dispatcher={...}) Line 1743 C++
        rexx.dll!Activity::run(TrappingDispatcher & target={...}) Line 3378 C++
        rexx.dll!MemoryObject::runUninits() Line 373    C++
        rexx.dll!MemoryObject::collectAndUninit(bool clearStack=false) Line 315 C++
        rexx.dll!InterpreterInstance::terminate() Line 515  C++
        rexx.dll!Terminate(RexxInstance_ * c=0x000002636ff64c80) Line 58    C++
        BSF4ooRexx.dll!RexxInstance_::Terminate() Line 701  C++
        BSF4ooRexx.dll!impl_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002631be5c8d8, _jobject * jobj=0x000000c9cb3ff250, _jstring * j_rii_ID=0x000000c9cb3ff248) Line 9605 C++
        BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxTerminateInterpreterInstance(JNIEnv_ * env=0x000002631be5c8d8, _jobject * jobj=0x000000c9cb3ff250, _jstring * j_rii_ID=0x000000c9cb3ff248) Line 9627 C++
        000002630000d621()  Unknown
        000002631be5c8d8()  Unknown
        000000c9cb3ff250()  Unknown
        000000c9cb3ff248()  Unknown
    
    
    ------------------------
    
    Main (Rexx) thread:
    
        win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
        user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
    >   rexx.dll!waitHandle(void * s=0x0000000000000128, bool bypassMessageLoop=false) Line 213 C++
        rexx.dll!SysMutex::request() Line 120   C++
        rexx.dll!ActivityManager::lockKernel() Line 84  C++
        rexx.dll!Activity::waitForKernel() Line 2180    C++
        rexx.dll!ActivityManager::addWaitingApiActivity(Activity * waitingAct=0x0000026370310120) Line 280  C++
        rexx.dll!Activity::requestApiAccess() Line 2166 C++
        rexx.dll!Activity::enterCurrentThread() Line 318    C++
        rexx.dll!ApiContext::ApiContext(RexxThreadContext_ * c=0x0000026370310148) Line 76  C++
        rexx.dll!IsOfType(RexxThreadContext_ * c=0x0000026370310148, _RexxObjectPtr * o=0x000002636f8e3400, const char * cn=0x000000001003d8d4) Line 281    C++
        BSF4ooRexx.dll!RexxThreadContext_::IsOfType(_RexxObjectPtr * o=0x000002636f8e3400, const char * cn=0x000000001003d8d4) Line 800 C++
        BSF4ooRexx.dll!RgfValue4JavaIndicator(RexxThreadContext_ * rtc=0x0000026370310148, _RexxObjectPtr * robj=0x000002636f8e3400) Line 2726  C++
        BSF4ooRexx.dll!BSF_impl(RexxCallContext_ * context=0x000000c9ca4797d8, _RexxArrayObject * argArray=0x0000026370164d00) Line 6535    C++
        BSF4ooRexx.dll!BSF(RexxCallContext_ * context=0x000000c9ca4797d8, ValueDescriptor * arguments=0x000000c9ca4796c0) Line 6409 C++
        rexx.dll!NativeActivation::callNativeRoutine(RoutineClass * _routine=0x000002636f87e030, NativeRoutine * _code=0x000002636f87dff0, RexxString * functionName=0x000002636f87dfa0, RexxObject * * list=0x000002637022c480, unsigned __int64 count=4, ProtectedObject & resultObj={...}) Line 1423 C++
        rexx.dll!NativeRoutine::call(Activity * activity=0x0000026370310120, RoutineClass * routine=0x000002636f87e030, RexxString * functionName=0x000002636f87dfa0, RexxObject * * argPtr=0x000002637022c480, unsigned __int64 count=4, ProtectedObject & result={...}) Line 356  C++
        rexx.dll!RoutineClass::callWithRexx(ArrayClass * args=0x000002637022c420) Line 228  C++
        rexx.dll!CPPCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002636f73d790, RexxObject * receiver=0x000002636f87e030, RexxString * messageName=0x000002636f877fd0, RexxObject * * argPtr=0x00000263705c2ba0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 174  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002636f87e030, RexxString * msgname=0x000002636f877fd0, RexxObject * * argPtr=0x00000263705c2ba0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636f877fd0, RexxObject * * arguments=0x00000263705c2ba0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!ExpressionStack::send(RexxString * message=0x000002636f877fd0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
        rexx.dll!RexxExpressionMessage::evaluate(RexxActivation * context=0x0000026370420340, ExpressionStack * stack=0x00000263704204a8) Line 191  C++
        rexx.dll!RexxInstruction::evaluateArguments(RexxActivation * context=0x0000026370420340, ExpressionStack * stack=0x00000263704204a8, RexxInternalObject * * argArray=0x000002636f8e4698, unsigned __int64 argCount=1) Line 154  C++
        rexx.dll!RexxExpressionFunction::evaluate(RexxActivation * context=0x0000026370420340, ExpressionStack * stack=0x00000263704204a8) Line 187 C++
        rexx.dll!RexxInstructionExpression::evaluateExpression(RexxActivation * context=0x0000026370420340, ExpressionStack * stack=0x00000263704204a8) Line 229    C++
        rexx.dll!RexxInstructionReturn::execute(RexxActivation * context=0x0000026370420340, ExpressionStack * stack=0x00000263704204a8) Line 72    C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002636fd4c6a0, RexxString * name=0x000002636f65a580, RexxObject * * _arglist=0x000000c9ca47a058, unsigned __int64 _argcount=2, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002636f8e4f70, RexxObject * receiver=0x000002636fd4c6a0, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47a058, unsigned __int64 argcount=2, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002636fd4c6a0, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47a058, unsigned __int64 count=2, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::processUnknown(RexxErrorCodes error=Error_No_method_name, RexxString * messageName=0x000002636f9dec50, RexxObject * * arguments=0x00000263705c2ab0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 1022    C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636f9dec50, RexxObject * * arguments=0x00000263705c2ab0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 907   C++
        rexx.dll!ExpressionStack::send(RexxString * message=0x000002636f9dec50, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
        rexx.dll!RexxInstructionMessage::execute(RexxActivation * context=0x00000263701f35b0, ExpressionStack * stack=0x00000263701f3718) Line 189  C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002636fd5e550, RexxString * name=0x000002636fd5acc0, RexxObject * * _arglist=0x000002636f986c10, unsigned __int64 _argcount=1, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002636f9e0690, RexxObject * receiver=0x000002636fd5e550, RexxString * msgname=0x000002636fd5acc0, RexxObject * * argPtr=0x000002636f986c10, unsigned __int64 argcount=1, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002636fd5e550, RexxString * msgname=0x000002636fd5acc0, RexxObject * * argPtr=0x000002636f986c10, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636fd5acc0, RexxObject * * arguments=0x000002636f986c10, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!RexxActivation::forward(RexxObject * target=0x000002636fd5e550, RexxString * message=0x000002636fd5acc0, RexxClass * superClass=0x0000000000000000, RexxObject * * arguments=0x000002636f986c10, unsigned __int64 argcount=1, bool continuing=false) Line 1275 C++
        rexx.dll!RexxInstructionForward::execute(RexxActivation * context=0x00000263701f2bd0, ExpressionStack * stack=0x00000263701f2d38) Line 242  C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002636f98d290, RexxString * name=0x000002636f65a580, RexxObject * * _arglist=0x000000c9ca47a818, unsigned __int64 _argcount=2, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002636f771de0, RexxObject * receiver=0x000002636f98d290, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47a818, unsigned __int64 argcount=2, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002636f98d290, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47a818, unsigned __int64 count=2, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::processUnknown(RexxErrorCodes error=Error_No_method_name, RexxString * messageName=0x000002636fd5acc0, RexxObject * * arguments=0x00000263705c2968, unsigned __int64 count=1, ProtectedObject & result={...}) Line 1022    C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636fd5acc0, RexxObject * * arguments=0x00000263705c2968, unsigned __int64 count=1, ProtectedObject & result={...}) Line 907   C++
        rexx.dll!ExpressionStack::send(RexxString * message=0x000002636fd5acc0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
        rexx.dll!RexxInstructionMessage::execute(RexxActivation * context=0x00000263701f2750, ExpressionStack * stack=0x00000263701f28b8) Line 189  C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x0000000000000000, RexxString * name=0x000002637040d1f0, RexxObject * * _arglist=0x000002636f9886d0, unsigned __int64 _argcount=1, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::call(Activity * activity=0x0000026370310120, RoutineClass * routine=0x000002636fc394b0, RexxString * routineName=0x000002637040d1f0, RexxObject * * argPtr=0x000002636f9886d0, unsigned __int64 argcount=1, RexxString * calltype=0x000002636f81f110, RexxString * environment=0x0000000000000000, ActivationContext context=EXTERNALCALL, ProtectedObject & result={...}) Line 188  C++
        rexx.dll!RexxCode::call(Activity * activity=0x0000026370310120, RoutineClass * routine=0x000002636fc394b0, RexxString * msgname=0x000002637040d1f0, RexxObject * * argPtr=0x000002636f9886d0, unsigned __int64 argcount=1, ProtectedObject & result={...}) Line 159 C++
        rexx.dll!RoutineClass::callWithRexx(ArrayClass * args=0x000002636f988670) Line 228  C++
        rexx.dll!CPPCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002636f73d790, RexxObject * receiver=0x000002636fc394b0, RexxString * messageName=0x000002636f9d22d0, RexxObject * * argPtr=0x00000263705c28b8, unsigned __int64 count=1, ProtectedObject & result={...}) Line 174  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002636fc394b0, RexxString * msgname=0x000002636f9d22d0, RexxObject * * argPtr=0x00000263705c28b8, unsigned __int64 count=1, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636f9d22d0, RexxObject * * arguments=0x00000263705c28b8, unsigned __int64 count=1, ProtectedObject & result={...}) Line 902   C++
        rexx.dll!ExpressionStack::send(RexxString * message=0x000002636f9d22d0, unsigned __int64 count=1, ProtectedObject & result={...}) Line 80   C++
        rexx.dll!RexxInstructionMessage::execute(RexxActivation * context=0x00000263701f2510, ExpressionStack * stack=0x00000263701f2678) Line 189  C++
        rexx.dll!RexxActivation::run(RexxObject * _receiver=0x000002631cd83fb0, RexxString * name=0x000002636f65a580, RexxObject * * _arglist=0x000000c9ca47b178, unsigned __int64 _argcount=2, RexxInstruction * start=0x0000000000000000, ProtectedObject & resultObj={...}) Line 594 C++
        rexx.dll!RexxCode::run(Activity * activity=0x0000026370310120, MethodClass * method=0x000002631cd58a80, RexxObject * receiver=0x000002631cd83fb0, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47b178, unsigned __int64 argcount=2, ProtectedObject & result={...}) Line 211  C++
        rexx.dll!MethodClass::run(Activity * activity=0x0000026370310120, RexxObject * receiver=0x000002631cd83fb0, RexxString * msgname=0x000002636f65a580, RexxObject * * argPtr=0x000000c9ca47b178, unsigned __int64 count=2, ProtectedObject & result={...}) Line 172   C++
        rexx.dll!RexxObject::processUnknown(RexxErrorCodes error=Error_No_method_name, RexxString * messageName=0x000002636fe7b330, RexxObject * * arguments=0x000002636f98e830, unsigned __int64 count=1, ProtectedObject & result={...}) Line 1022    C++
        rexx.dll!RexxObject::messageSend(RexxString * msgname=0x000002636fe7b330, RexxObject * * arguments=0x000002636f98e830, unsigned __int64 count=1, ProtectedObject & result={...}) Line 907   C++
        rexx.dll!RexxObject::sendMessage(RexxString * message=0x000002636fe7b330, ArrayClass * arguments=0x000002636f98e7d0, ProtectedObject & result={...}) Line 749   C++
        rexx.dll!SendMessageArray(RexxThreadContext_ * c=0x0000026370310148, _RexxObjectPtr * o=0x000002631cd83fb0, const char * m=0x000002636d7dc100, _RexxArrayObject * a=0x000002636f98e7d0) Line 167    C++
        BSF4ooRexx.dll!RexxThreadContext_::SendMessageA(_RexxObjectPtr * o=0x000002631cd83fb0, const char * msg=0x000002636d7dc100, _RexxArrayObject * arr=0x000002636f98e7d0) Line 771 C++
        BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxSendMessageToRexxObject(JNIEnv_ * env=0x000002636d6bde48, _jobject * jobj=0x000000c9ca47b5b8, _jstring * j_rii_ID=0x000000c9ca47b5c0, _jstring * j_obj_ID=0x000000c9ca47b5c8, _jstring * j_userData_ID=0x0000000000000000, _jstring * j_javaObjectBean=0x0000000000000000, _jstring * j_methodObjectBean=0x0000000000000000, _jstring * j_messageName=0x000000c9ca47b600, _jstring * j_methodDescription=0x0000000000000000, _jobjectArray * j_args=0x000000c9ca47b610, _jstring * j_returnType=0x0000000000000000) Line 9231    C++
        0000026307b153da()  Unknown
        000002636d6bde48()  Unknown
        000000c9ca47b5b8()  Unknown
        000000c9ca47b5c0()  Unknown
        000000c9ca47b5c8()  Unknown
    
    -----------------------------
    
    Main (Rexx) thread:
    
        win32u.dll!NtUserMsgWaitForMultipleObjectsEx() Unknown
        user32.dll!RealMsgWaitForMultipleObjectsEx()    Unknown
    >   rexx.dll!waitHandle(void * s=0x0000000000000128, bool bypassMessageLoop=false) Line 213 C++
        rexx.dll!SysMutex::request() Line 120   C++
        rexx.dll!ActivityManager::lockKernel() Line 84  C++
        rexx.dll!Activity::waitForKernel() Line 2180    C++
        rexx.dll!ActivityManager::addWaitingApiActivity(Activity * waitingAct=0x000002631caff090) Line 280  C++
        rexx.dll!Activity::requestApiAccess() Line 2166 C++
        rexx.dll!Activity::enterCurrentThread() Line 318    C++
        rexx.dll!ApiContext::ApiContext(RexxThreadContext_ * c=0x000002631caff0b8) Line 76  C++
        rexx.dll!ReleaseLocalReference(RexxThreadContext_ * c=0x000002631caff0b8, _RexxObjectPtr * o=0x000002636fdd69d0) Line 147   C++
        BSF4ooRexx.dll!RexxThreadContext_::ReleaseLocalReference(_RexxObjectPtr * o=0x000002636fdd69d0) Line 766    C++
        BSF4ooRexx.dll!RgfAddProxyObject(RexxThreadContext_ * rtc=0x000002631caff0b8, _RexxObjectPtr * robj=0x000002637039d7f0, _RexxPackageObject * rpo=0x0000000000000000) Line 1817  C++
        BSF4ooRexx.dll!RgfCreateRexxProxy(JNIEnv_ * env=0x000002636d6bde48, _jobject * rajo=0x000000c9ca47b610, RexxThreadContext_ * rtc=0x000002631caff0b8, _RexxObjectPtr * robj=0x000002637039d7f0, _RexxPackageObject * rpo=0x0000000000000000, _RexxObjectPtr * userData=0x0000000000000000) Line 2564 C++
        BSF4ooRexx.dll!RgfProcessReturnValue4Java(JNIEnv_ * env=0x000002636d6bde48, _jobject * rajo=0x000000c9ca47b610, RexxThreadContext_ * rtc=0x000002631caff0b8, _RexxObjectPtr * robj=0x000002637039d7f0, _jstring * j_returnType=0x0000000000000000) Line 2835    C++
        BSF4ooRexx.dll!Java_org_rexxla_bsf_engines_rexx_RexxAndJava_jniRexxRunProgram(JNIEnv_ * env=0x000002636d6bde48, _jobject * raj=0x000000c9ca47b610, _jstring * j_rii_ID=0x000000c9ca47b608, long invocationType=2, _jstring * j_fileName=0x000000c9ca47b5f8, _jstring * j_programData=0x000000c9ca47b5f0, _jobjectArray * j_args=0x0000000000000000) Line 8820   C++
        000002630000d621()  Unknown
        000002636d6bde48()  Unknown
        000000c9ca47b610()  Unknown
        000000c9ca47b608()  Unknown
        0000000600000002()  Unknown
        000000c9ca47b5f8()  Unknown
        000000c9ca47b5f0()  Unknown
    
    
    -----------------------------
    
     
  • Rick McGuire

    Rick McGuire - 2022-07-21

    If it doesn't hand indefinitely, this is not a bug. You are running 1000 garbage collection cycles, which are not interruptible , while also doing other work on other threads. There are going to be delays because of the cooperative multitasking.

     
    • Rony G. Flatscher

      The 1000 engines are at the end of the test cycle.

      Yesterday, it took about 20 seconds altogether, including the more than 1000 garbage collector runs with the uninits; all executed according to the Java side statistics (using the version that replaced the monitors in .local right before termination).


      Did take (manual) timings of r12482 each time a noticeable (lasting a few seconds) blocking occurs. Here the results, each elapsed time shows the time between blocks at the very beginning of the test cycle (so the first noticeable block occurs after 3,98 seconds, the next one after 6,56 seconds, the next one after 12,91 seconds), stopped the timings after about 40 seconds:

      03,98
      06,56
      10,40
      12,91
      06,41
      06,13
      
       
  • Rick McGuire

    Rick McGuire - 2022-07-21

    Still not a bug. The calls yesterday experience no delays because they were not doing anything because they weren't getting called on the original creation thread. Now that that restriction has been lifted, they are now doing all of the shutdown activity, including performing the garbage collection and running the uninit methods.

     
    • Rony G. Flatscher

      OK, this is now with a test case (t_bsf.rex) doing principally the same: create an instance, run a program (.output~charout('.'), terminate the instance in a loop of 1000 runs. This testcase also changes the destination of .input, .output, .error, .traceoutput, .debuginput to BSF objects that redirect to the Java streams.

      Scenario A: everything runs on the same thread, creation, running the program, terminating. According to the Java statistics the BSF objects all got garbage collected and their uninit run:

      ... cut ...
      RexxAnalyzeRegistry category=[[B]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
                          - MemSize:  entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
      
      RexxAnalyzeRegistry category=[[C]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
                          - MemSize:  entries=[      2] | references: min=[        2] max=[        2] avg=[      2,0] sum=[        4]
      
      RexxAnalyzeRegistry category=[[I]
                          - RefCount: entries=[      4] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        4]
                          - MemSize:  entries=[      4] | references: min=[        4] max=[        4] avg=[      4,0] sum=[       16]
      
      RexxAnalyzeRegistry category=[java.io.BufferedInputStream]
                          - RefCount: entries=[      1] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        1]
      
      RexxAnalyzeRegistry category=[java.io.PrintStream]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
      ... cut ...
      
      org.rexxla.bsf.engines.rexx.RexxCleanupRef:
      RexxCleanupRef [2022-07-21 18:11:38.937000000]
                   RefKind:         Instances:         Finalized: Not Yet Finalized:
      ------------------------------------------------------------------------------
      [TEST]..............: [               0] [               0] [               0]
      [REXX_ENGINE].......: [           1á001] [             884] [             117]
      [REXX_PROXY]........: [               0] [               0] [               0]
      [REXX_SCRIPT_ENGINE]: [               0] [               0] [               0]
      ------------------------------------------------------------------------------
      Totals..............: [           1á001] [             884] [             117]
      ---
      
      OREXX_REGISTRY related:
              OREXX_REGISTRY           ~items: 0
              OREXX_REGISTRY_REFCOUNTER~items: 0
      
      t_bsf.rex: ooRexx 5.0.0 r12482 (21 Jul 2022) / BSF 641.20220717 / Java 17.0.3.1 (released: 2022-04-22), 64-bit (amd64) / Windows 10.0.19043
      
      1000 *** needed: 00:00:13.283000 (13283000micros): 13283 micros/engine
           ***         75.2841978 engines/sec
      
      
      --> count_rexx_gc: [0] count_java_gc: [0]
      
      --> L(oop again) 1000 times | J(ava gc) | R(exx gc) | <return> (end)
      

      Scenario B: the creation and running of the program is executed on the same thread, terminating the instance is done from a separate thread. According to the Java statistics the BSF objects all got garbage collected and their uninit run:

      ... cut ...
      RexxAnalyzeRegistry category=[[B]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
                          - MemSize:  entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
      
      RexxAnalyzeRegistry category=[[C]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
                          - MemSize:  entries=[      2] | references: min=[        2] max=[        2] avg=[      2,0] sum=[        4]
      
      RexxAnalyzeRegistry category=[[I]
                          - RefCount: entries=[      4] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        4]
                          - MemSize:  entries=[      4] | references: min=[        4] max=[        4] avg=[      4,0] sum=[       16]
      
      RexxAnalyzeRegistry category=[java.io.BufferedInputStream]
                          - RefCount: entries=[      1] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        1]
      
      RexxAnalyzeRegistry category=[java.io.PrintStream]
                          - RefCount: entries=[      2] | references: min=[        1] max=[        1] avg=[      1,0] sum=[        2]
      
      ... cut ...
      
      org.rexxla.bsf.engines.rexx.RexxCleanupRef:
      RexxCleanupRef [2022-07-21 18:28:30.351000000]
                   RefKind:         Instances:         Finalized: Not Yet Finalized:
      ------------------------------------------------------------------------------
      [TEST]..............: [               0] [               0] [               0]
      [REXX_ENGINE].......: [           1á001] [             953] [              48]
      [REXX_PROXY]........: [               0] [               0] [               0]
      [REXX_SCRIPT_ENGINE]: [               0] [               0] [               0]
      ------------------------------------------------------------------------------
      Totals..............: [           1á001] [             953] [              48]
      
      ---
      
      OREXX_REGISTRY related:
              OREXX_REGISTRY           ~items: 0
              OREXX_REGISTRY_REFCOUNTER~items: 0
      
      t_bsf.rex: ooRexx 5.0.0 r12482 (21 Jul 2022) / BSF 641.20220717 / Java 17.0.3.1 (released: 2022-04-22), 64-bit (amd64) / Windows 10.0.19043
      
      
      1000 *** needed: 00:13:48.357000 (828357000micros): 828357 micros/engine
           ***         1.20720897 engines/sec 
      

      To sum up:

      Runtime Scenario A (everything on same thread):          00:00:13.283000 (75.2841978 engines/sec)
      Runtime Scenario B (termination from different thread): 00:13:48.357000 (1.20720897 engines/sec)
      

      Scenario A needs 13.283 seconds for 1000 engines, scenario B needs 828.357 seconds.

      In both scenarios the .local entries get freed by Rexx and garbage collected with running their uninits.

       
  • Rick McGuire

    Rick McGuire - 2022-07-21

    And still NOT A BUG. Because the separate thread is competing with another thread for the interpreter lock, it is going to be held up frequently because of contention with the other thread. The external calls in the uninit methods are going to cause the lock to be released which will cause that thread to go to the back of the line for dispatching. As long as things complete eventually, things are doing what they are supposed to be doing. Your code happens to be non-optimally written.

     
    • Rony G. Flatscher

      This is very unfortunate as in Java based web servers where each request (e.g. of a JSP page) gets dispatched on different threads and the termination of the engines gets done from a single, different Java thread (a cleaner thread).

      Unfortunately, there is nothing I can do ( unlike with my own stand-alone test programs mimickring what the Java web servers do).

       
      • Rony G. Flatscher

        After further extensive testing I think that there is a problem somewhere as even in the case where there are ten instances only, each having five BSF objects in their .local monitors, termination of these ten instances needs six (!) seconds on a quite fast machine.

        Changed test logic: creating an instance, running a program (.local monitors with uninit objects) in a loop. The instances get collected and after the loop (for timing purposes) the Rexx gc gets invoked as many times as instances got created (just to see how long that would take at that particular point in time).

        Then another loop over the collected instances sends the terminate message (via the engine's BSFManager): this is the spot where there are dramatic differences comparing variant A with variant B (see below).

        • Variant A: the .local monitors do not get reset before termination
        • Variant B: the .local monitors do get reset in the Rexx program prior to its termination (such that the BSF objects get eligible for garbage collection at that point in time)

        loop=10
        BSF objects: loop * 5 (monitor destinations), hence totalling 50 objects that need their uninit methods run in this test run

        Creating instances, durations:

        • Variant A:
        10 *** needed: 00:00:00.089000 (89000micros): 8900 micros/engine
           ***         112.359551 engines/sec
        
        *** calling 10 times the gc lasted: 00:00:00.094000
        
        • Variant B:
        10 *** needed: 00:00:00.088000 (88000micros): 8800 micros/engine
           ***         113.636364 engines/sec
        
        *** calling 10 times the gc lasted: 00:00:00.078000
        

        Sending terminate message, durations:

        • Variant A
        *** sending terminate message to all lasted: *00:00:06.346000*
        *** now dropping array of BSFManagers and doing a Rexx gc():
        ***     lasted: 00:00:00.007000
        
        • Variant B
        *** sending terminate message to all lasted: *00:00:00.108000*
        *** now dropping array of BSFManagers and doing a Rexx gc():
        ***     lasted: 00:00:00.009000
        

        Variant B is almost 60 (!) times faster than Variant A (0.108 vs. 6.346 seconds)!

        The only difference being in this case, that Variant A needs to free the .local monitor destination objects and then run their uninits (five BSF objects per instance, test run of 10 instances hence a total of 50 BSF objects that need to have their uninit methods run, yet this lasts 6.2 seconds on a quite fast machine).

        These uninits are also run in Variant B, but the BSF objects got removed from .local long before the terminate message gets sent to the respective instance.


        The routine "bsf.redirectTo {Java | Rexx}" allows one to redirect the .local monitors to be redirected to Java ("Java") or to Rexx ("Rexx"). The current destination of each of the .input, .output, .error, .debuginput and .traceoutput monitors gets popped, unless it is the very first destination of the monitor, then the respective Java or standard Rexx destinations get added.

        • Variant A code:
        rexxCode="call bsf.redirectTo j;.error~current~prefix='';.error~charout('.');::requires BSF.CLS"
        
        • Variant B code:
        rexxCode="call bsf.redirectTo j;.error~current~prefix='';.error~charout('.'); call bsf.redirectTo rexx;::requires BSF.CLS"
        
         
  • Rick McGuire

    Rick McGuire - 2022-07-21

    Additional updates [r12483]

     

    Related

    Commit: [r12483]

  • Erich

    Erich - 2022-07-21
    POINTER RexxEntry MutableBufferData(RexxThreadContext *c, RexxMutableBufferObject b)
     {
    -    ApiContext context(c);
    +    ApiContext context(c, false);     // no lock required
    

    if MutableBufferLength must be a blocking API, shouldn't MutableBufferData also be a blocking API?

     
    • Rick McGuire

      Rick McGuire - 2022-07-21

      you're right, the backing buffer can be reallocated, which makes it risky.
      However, that could happen in any event immediately after the pointer was
      requested. I suspect it's safe to leave it this way, but I'll back that one
      off.

      Rick

      On Thu, Jul 21, 2022 at 5:07 PM Erich erich_st@users.sourceforge.net
      wrote:

      ~~~
      POINTER RexxEntry MutableBufferData(RexxThreadContext *c,
      RexxMutableBufferObject b)
      {
      - ApiContext context(c);
      + ApiContext context(c, false); // no lock required
      ~~~

      if MutableBufferLength must be a blocking API, shouldn't MutableBufferData
      also be a blocking API?


      [feature-requests:#806] Allow RexxInstance->Terminate() to be called
      from any thread.

      Status: unread
      Milestone: 5.0.0
      Created: Wed Jul 20, 2022 07:22 PM UTC by Rick McGuire
      Last Updated: Thu Jul 21, 2022 07:53 PM UTC
      Owner: nobody

      For some applications, it can prove difficult to match up the thread on
      which an interpreter instance has been created so that the instance can be
      terminated. It should be possible to do this on any thread so that memory
      resources don't get leaked.


      Sent from sourceforge.net because you indicated interest in <
      https://sourceforge.net/p/oorexx/feature-requests/806/>

      To unsubscribe from further messages, please visit <
      https://sourceforge.net/auth/subscriptions/>

       

      Related

      Feature Requests: #806

  • Rick McGuire

    Rick McGuire - 2022-07-22

    The only thing wrong here is how your code is written and your expectations of what will happen. Once Terminate is called, it waits for all the threads to terminate, then obtains the global dispatch lock and runs a garbage collection (a long running. non-interruptible operation). Once the garbage is collected, the uninit methods get run on objects that are now out of scope. Since your uninit objects are in native code, the dispatch lock is given up before the callout is made and it needs to be reobtained for things to continue. It goes back to the end of the dispatch queue. If for example, the thread holding the lock itself need to run a garbage collection, then it could be a long wait. Adding to this, if you native methods are making calls to APIs that have to get the dispatch lock, there can be a bit of waiting involved. I saw from the stack traces you posted that there's a least one of these API calls being made. Depending on how many threads are running and what they are doing, these calls can experience some substantial delays, but the fact that they actually run to completion means means the underlying mechanisms are working correctly.

    Things can be improved by trying to optimize your uninit code to minimize callbacks or reducing the number of things you're attempting to do currently, but this is working correctly.

    This is the absolute last time I'm going to comment on this issue. If you still feel there's a bug here, then you need to figure it out and fix it.

    Rick

     
    • Rony G. Flatscher

      Hmm. It is strange that those "few calls with locks" cause such enormous delays when running on a (debug) system that almost does 1,000,000 RexxCPS. So in the time terminating ten instances lasting six seconds there could be alternatively 6,000,000 RexxCPS executed.

      Even if the implementation (as no memory leaks occur anymore which is good) is correct, the runtime characteristics definitely do not look ok at all. E.g. it inhibits deploying ooRexx in Java based web servers serving JSPs, which would be a pity as the ooRexx solution is just simple and easy to employ for ooRexx programmers, a real boon! Hence trying hard to come up with a solution that would help solve the problem.


      Ad uninit: the call to native code is needed to inform the Java side that a particular Rexx object releases its reference to its peer Java object (the Java side decreases the reference counter and if the counter drops to 0 it will remove the pinned Java object from the Java registry).

      The uninit logic is written with as few clauses as possible to get the best performance (in native code just an argument check, an ObjectToString() is carried out and the necessary Java method gets invoked directly via JNI), hence these calls are short and fast. There are no callbacks to ooRexx during its execution.


      Looking from the outside in a form of a black-box analysis it surely looks like some sort of a race condition or wrong locking as really, the same uninits run in one case 60 times slower than in the other case, the difference being simply 50 objects with uninits in .local in the termination phase (needing 50 simple callouts without callbacks).

      Therefore there seems to be a significant difference in garbage collection running uninits during normal operation of an instance compared to doing it in the termination phase. It is as if in the termination phase some sort of a race condition occurs or some sort of additional/wrong locking with timeouts.

      Notabene: the test case is the same for both runs, the difference is the existence of 5 BSF objects in .local when the termination phase starts for each instance which slows the termination down so tremendously. I cannot see how normal locking for five uninit invocations would cause such delays in the termination phase hence speculating some sort of a race condition or waiting on a wrong object or using a wrong lock and the like.


      Not sure whether this observation helps: in a different test scenario, where creating an instance, running the program and termination occurs in the loop, the main thread seems to be blocked at instance creation time in the next loop run as long as the termination of the previous instance is being carried out on the separate thread. Only upon termination of that instance on that separate thread would the new instance be created it seems.


      As there seems to be nothing that I can do to improve these abysmal termination times (one callout per uninit, no callback to ooRexx on this callout, shortest possible paths in ooRexx code, native code and Java code for uninits) the only thing I can do then would be to warn people about using ooRexx in such use cases which I really, really would hate a lot, needless to say!

      An immensely amount of time and effort would have been all in vain.

       
  • Rony G. Flatscher

    OK, went out and started to debug interpreter/runtime/InterpreterInstance.cpp, eventually it worked surprisingly, then systematically commenting out the debug statements until a state was arrived that keeps working, but removing any of the debug statements would create those abysmal blocks.

    So inserting fprintf(stderr,...);fflush(stderr); at two specific locations makes it work. Both must be present.

    The locations in the attached file are line # 484 (before "ResourceSection lock;") and # 497 (after "terminated = allActivities->items() == 1;").

     
1 2 > >> (Page 1 of 2)

Anonymous
Anonymous

Add attachments
Cancel