Luca Dariz, le mer. 21 août 2024 18:36:16 +0200, a ecrit:
> * tests/test-machmsg.c: add two use cases used by glibc during signal
>   handling
> * tests/include/testlib.h
> * tests/testlib.c: add new wait_thread_terminated() helper

Applied, thanks!

> ---
>  tests/include/testlib.h |  1 +
>  tests/test-machmsg.c    | 80 +++++++++++++++++++++++++++++++++++++++++
>  tests/testlib.c         | 15 ++++++++
>  3 files changed, 96 insertions(+)
> 
> diff --git a/tests/include/testlib.h b/tests/include/testlib.h
> index 1d08067b..737efd41 100644
> --- a/tests/include/testlib.h
> +++ b/tests/include/testlib.h
> @@ -70,6 +70,7 @@ thread_t test_thread_start(task_t task, 
> void(*routine)(void*), void* arg);
>  mach_port_t host_priv(void);
>  mach_port_t device_priv(void);
>  void wait_thread_suspended(thread_t th);
> +void wait_thread_terminated(thread_t th);
>  
>  extern vm_size_t vm_page_size;
>  
> diff --git a/tests/test-machmsg.c b/tests/test-machmsg.c
> index ac292376..7f535bde 100644
> --- a/tests/test-machmsg.c
> +++ b/tests/test-machmsg.c
> @@ -499,6 +499,83 @@ void test_msg_emptydesc(void)
>  }
>  
>  
> +void recv_to_be_interrupted(void *arg)
> +{
> +  mach_msg_header_t msg;
> +  kern_return_t ret;
> +  mach_port_t rcv_name;
> +  long err = (long)arg;
> +
> +  ret = mach_port_allocate(mach_task_self (), MACH_PORT_RIGHT_RECEIVE, 
> &rcv_name);
> +  ASSERT_RET(ret, "creating rx port");
> +
> +  ret = mach_msg(&msg, MACH_RCV_MSG,
> +                 0, sizeof(msg), rcv_name,
> +                 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
> +
> +  printf("mach_msg returned %x\n", ret);
> +  ASSERT(ret == err, "recv not interrupted correctly");
> +
> +  thread_terminate(mach_thread_self());
> +  FAILURE("thread_terminate");
> +}
> +
> +void test_recv_interrupted(void)
> +{
> +  kern_return_t ret;
> +  thread_t th;
> +  th = test_thread_start(mach_task_self(), recv_to_be_interrupted, 
> (void*)MACH_RCV_INTERRUPTED);
> +  msleep(100);
> +
> +  ret = thread_suspend(th);
> +  ASSERT_RET(ret, "thread_suspend");
> +
> +  ret = thread_abort(th);
> +  ASSERT_RET(ret, "thread_abort");
> +
> +  ret = thread_resume(th);
> +  ASSERT_RET(ret, "thread_resume");
> +
> +  wait_thread_terminated(th);
> +}
> +
> +void test_recv_interrupted_setreturn(void)
> +{
> +  kern_return_t ret;
> +  thread_t th;
> +  th = test_thread_start(mach_task_self(), recv_to_be_interrupted, 
> (void*)123L);
> +  msleep(100);
> +
> +  ret = thread_suspend(th);
> +  ASSERT_RET(ret, "thread_suspend");
> +
> +  ret = thread_abort(th);
> +  ASSERT_RET(ret, "thread_abort");
> +
> +
> +  struct i386_thread_state state;
> +  unsigned int count;
> +  count = i386_THREAD_STATE_COUNT;
> +  ret = thread_get_state(th, i386_REGS_SEGS_STATE,
> +                         (thread_state_t) &state, &count);
> +  ASSERT_RET(ret, "thread_get_state()");
> +
> +#ifdef __i386__
> +  state.eax = 123;
> +#elif defined(__x86_64__)
> +  state.rax = 123;
> +#endif
> +  ret = thread_set_state(th, i386_REGS_SEGS_STATE,
> +                         (thread_state_t) &state, i386_THREAD_STATE_COUNT);
> +  ASSERT_RET(ret, "thread_set_state");
> +
> +  ret = thread_resume(th);
> +  ASSERT_RET(ret, "thread_resume");
> +
> +  wait_thread_terminated(th);
> +}
> +
> +
>  int
>  main (int argc, char *argv[], int envc, char *envp[])
>  {
> @@ -512,5 +589,8 @@ main (int argc, char *argv[], int envc, char *envp[])
>    test_msg_emptydesc();
>    printf("test_iters()\n");
>    test_iterations();
> +  printf("test_recv_interrupted()\n");
> +  test_recv_interrupted();
> +  test_recv_interrupted_setreturn();
>    return 0;
>  }
> diff --git a/tests/testlib.c b/tests/testlib.c
> index df9d7113..4200979d 100644
> --- a/tests/testlib.c
> +++ b/tests/testlib.c
> @@ -225,6 +225,21 @@ void wait_thread_suspended(thread_t th)
>    } while (1);
>  }
>  
> +void wait_thread_terminated(thread_t th)
> +{
> +  int err;
> +  struct thread_basic_info info;
> +  mach_msg_type_number_t count;
> +  do {
> +    count = THREAD_BASIC_INFO_COUNT;
> +    err = thread_info(th, THREAD_BASIC_INFO, (thread_info_t)&info, &count);
> +    if (err == MACH_SEND_INVALID_DEST)
> +        break;
> +    ASSERT_RET(err, "error in thread_info");
> +    msleep(100); // don't poll continuously
> +  } while (1);
> +}
> +
>  /*
>   * Minimal _start() for test modules, we just take the arguments from the
>   * kernel, call main() and reboot. As in glibc, we expect the argument 
> pointer
> -- 
> 2.39.2
> 
> 

-- 
Samuel
War doesn't prove who's right, just who's left.

Reply via email to