RTX5 osThreadJoin() return value

Greetings,

The osThreadJoin() documentation indicates osOK should be returned if the identified "thread has already been terminated and joined or once the thread has been terminated and the join operations succeeds".  I'm trying to follow the code in rtx_thread.c::svcRtxThreadJoin() (from GitHub):

...
  if (thread->state == osRtxThreadTerminated) {
    osRtxThreadListUnlink(&osRtxInfo.thread.terminate_list, thread);
    osRtxThreadFree(thread);
    EvrRtxThreadJoined(thread);
    status = osOK;
  } else {
    // Suspend current Thread                                                                                                        
    if (osRtxThreadWaitEnter(osRtxThreadWaitingJoin, osWaitForever)) {
      thread_running = osRtxThreadGetRunning();
      thread_running->thread_next = thread;
      thread->thread_join = thread_running;
      thread->attr &= ~osThreadJoinable;
      EvrRtxThreadJoinPending(thread);
    } else {
      EvrRtxThreadError(thread, (int32_t)osErrorResource);
    }
    status = osErrorResource;
  }

  return status;

In the else clause where the calling thread must wait for the identified thread to join, how does the calling thread get osOK?  What did I miss?

Thanks very much!

Parents
  • When you are in an SVC function, you are running in Handler Mode using the MSP.  This is opposed to Thread Mode.  When your thread made the Call to Join, you were running in thread mode using the USP.  Each thread has its own stack, and the USP is switched to point to the proper thread.

    When the system changes from Thread Mode to Handler Mode, Many registers are saved on the USP.  When you return from the SVC, these values are restored.  One of these resisters is R0.  R0 is the register that is used to hold the status after a return from a function.

    Since the R0 in the SVC function is overwritten on return from SVC, if you want to return a status  you need to overwrite the value on the USP stack.

    void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool_t dispatch) {
      uint32_t *reg;
    
      EvrRtxThreadUnblocked(thread, ret_val);
    
    // reg is loaded with the top of the USP for the thread specified
      reg = osRtxThreadRegPtr(thread);
    // reg[0] is the location of R0 that will be restored on return to thread mode
      reg[0] = ret_val;

     You can look at OsRtxThreadJoinWakeup() to see the ThreadWaitExit call.

Reply
  • When you are in an SVC function, you are running in Handler Mode using the MSP.  This is opposed to Thread Mode.  When your thread made the Call to Join, you were running in thread mode using the USP.  Each thread has its own stack, and the USP is switched to point to the proper thread.

    When the system changes from Thread Mode to Handler Mode, Many registers are saved on the USP.  When you return from the SVC, these values are restored.  One of these resisters is R0.  R0 is the register that is used to hold the status after a return from a function.

    Since the R0 in the SVC function is overwritten on return from SVC, if you want to return a status  you need to overwrite the value on the USP stack.

    void osRtxThreadWaitExit (os_thread_t *thread, uint32_t ret_val, bool_t dispatch) {
      uint32_t *reg;
    
      EvrRtxThreadUnblocked(thread, ret_val);
    
    // reg is loaded with the top of the USP for the thread specified
      reg = osRtxThreadRegPtr(thread);
    // reg[0] is the location of R0 that will be restored on return to thread mode
      reg[0] = ret_val;

     You can look at OsRtxThreadJoinWakeup() to see the ThreadWaitExit call.

Children
No data