wasi-libc icon indicating copy to clipboard operation
wasi-libc copied to clipboard

crt1-command.c: always call wasi_proc_exit for _REENTRANT

Open yamt opened this issue 2 years ago • 10 comments

Note: a return from main() is an equivalent of exit(), which should terminate sibling threads.

yamt avatar Dec 20 '22 06:12 yamt

To summarize my thinking based on this discussion:

  1. Returning from _start is semantically the same as calling proc_exit(0)
  2. Under those circumstance its up to the runtime to tear down all threads (just like on posix).
  3. The only way (in posix) to have threads outlive the main thread is to call pthread_exit from the main thread (which we don't yet implement).

sbc100 avatar Dec 21 '22 00:12 sbc100

To summarize my thinking based on this discussion:

1. Returning from `_start` is semantically the same as calling `proc_exit(0)`

2. Under those circumstance its up to the runtime to tear down all threads (just like on posix).

3. The only way (in posix) to have threads outlive the main thread is to call `pthread_exit` from the main thread (which we don't yet implement).

i still think returning from _start should be the same as thread_exit. with that approach, it might be possible to implement pthread_exit with other mechanisms (eg exception-handling) w/o wasi_thread_exit.

yamt avatar Dec 21 '22 04:12 yamt

i still think returning from _start should be the same as thread_exit.

But wouldn't that make it hard to port existing programs that assume posix semantics (returning from _start is the same as exiting the entire process).

If we are looking for way to achieve "exit while keeping background threads alive" why would we choose "return from start function" to implicitly mean that? Especially when existing program already assume that not to be true? Why not be explicit about that with a new API or an argument to new argument to the existing wasi_proc_exit?

I think this is another reason we need to add wasi_thread_exit: https://github.com/WebAssembly/wasi-threads/issues/7. Until we do that, we don't have a good to signal "exit with other threads staying alive" from the main thread.

sbc100 avatar Dec 21 '22 15:12 sbc100

i still think returning from _start should be the same as thread_exit.

But wouldn't that make it hard to port existing programs that assume posix semantics (returning from _start is the same as exiting the entire process).

C programs don't care about "returning from _start". what they care is "returning from main", which is this PR is about.

If we are looking for way to achieve "exit while keeping background threads alive" why would we choose "return from start function" to implicitly mean that? Especially when existing program already assume that not to be true? Why not be explicit about that with a new API or an argument to new argument to the existing wasi_proc_exit?

I think this is another reason we need to add wasi_thread_exit: WebAssembly/wasi-threads#7. Until we do that, we don't have a good to signal "exit with other threads staying alive" from the main thread.

i feel the opposite. actually, "terminate other threads" is a new concept which wasi-threads is going to introduce. why not be explicit about that?

yamt avatar Dec 21 '22 22:12 yamt

If I understand correctly, one of the motivations for this is so that if we say that exiting from _start is the same as wasi_thread_exit, then in the future we can more easily replace wasi_thread_exit with an unwind, once we have unwinding.

However, elsewhere, other people have been contemplating replacing proc_exit with an unwind, once we have unwinding. And that wants exiting from _start to be the same as proc_exit.

Both of these would eliminate an API function and simplify the system. But we can't easily do both. What should we do?

sunfishcode avatar Dec 22 '22 00:12 sunfishcode

C programs don't care about "returning from _start". what they care is "returning from main", which is this PR is about.

Ah, I think I see now. This PR mean that returning from main always results in proc_exit (at least in the multi-threaded case) which then means we can reserve returning from _start to potentially signify something else.

In that case, I withdraw my previous objection.

sbc100 avatar Dec 22 '22 01:12 sbc100

If I understand correctly, one of the motivations for this is so that if we say that exiting from _start is the same as wasi_thread_exit, then in the future we can more easily replace wasi_thread_exit with an unwind, once we have unwinding.

However, elsewhere, other people have been contemplating replacing proc_exit with an unwind, once we have unwinding. And that wants exiting from _start to be the same as proc_exit.

who is "other people" and where is it?

Both of these would eliminate an API function and simplify the system. But we can't easily do both. What should we do?

theoretically we can do the both if we want as a wasm function can return multiple return values.

yamt avatar Dec 22 '22 04:12 yamt

If I understand correctly, one of the motivations for this is so that if we say that exiting from _start is the same as wasi_thread_exit, then in the future we can more easily replace wasi_thread_exit with an unwind, once we have unwinding. However, elsewhere, other people have been contemplating replacing proc_exit with an unwind, once we have unwinding. And that wants exiting from _start to be the same as proc_exit.

who is "other people" and where is it?

I don't have links handy, but I think the motivation is straightforward: proc_exit is a special and non-virtualizable function. The platform would be cleaner if we didn't need it, and with unwinding support, we shouldn't need it. And it only supports i32 exit codes; as we add support for Typed Main, we'll want programs to be able to return other types of data too. And as we do more with linking multiple modules together, explicit unwinding clarifies the scope of the exit—_start would catch the exception, making it clear that the caller of _start isn't intended to be terminated.

Both of these would eliminate an API function and simplify the system. But we can't easily do both. What should we do?

theoretically we can do the both if we want as a wasm function can return multiple return values.

Are you suggesting having a return value that tells the caller of main whether to wait for all threads or kill all the threads?

sunfishcode avatar Dec 23 '22 00:12 sunfishcode

If I understand correctly, one of the motivations for this is so that if we say that exiting from _start is the same as wasi_thread_exit, then in the future we can more easily replace wasi_thread_exit with an unwind, once we have unwinding. However, elsewhere, other people have been contemplating replacing proc_exit with an unwind, once we have unwinding. And that wants exiting from _start to be the same as proc_exit.

who is "other people" and where is it?

I don't have links handy, but I think the motivation is straightforward: proc_exit is a special and non-virtualizable function. The platform would be cleaner if we didn't need it, and with unwinding support, we shouldn't need it. And it only supports i32 exit codes; as we add support for Typed Main, we'll want programs to be able to return other types of data too. And as we do more with linking multiple modules together, explicit unwinding clarifies the scope of the exit—_start would catch the exception, making it clear that the caller of _start isn't intended to be terminated.

ok.

the most of motivation (except Typed main one) seems to apply to thread_exit as well.

the "terminate other threads" part of proc_exit can't be implemented with unwind alone, right?

i'm not sure how the "Typed Main non-i32 return value" part can work when a non-main thread does proc_exit. do you have an idea?

Both of these would eliminate an API function and simplify the system. But we can't easily do both. What should we do?

theoretically we can do the both if we want as a wasm function can return multiple return values.

Are you suggesting having a return value that tells the caller of main whether to wait for all threads or kill all the threads?

sort of. eg. it can return two values like: (is_exit, exit_value)

yamt avatar Dec 23 '22 04:12 yamt

Let's figure this out in the "thread exit" issue (https://github.com/WebAssembly/wasi-threads/issues/7) and then come back to this.

abrown avatar Jul 11 '23 22:07 abrown