Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the critical part of wasi_thread_start in asm #376

Merged
merged 3 commits into from
Jan 6, 2023

Conversation

yamt
Copy link
Contributor

@yamt yamt commented Jan 6, 2023

It's fragile to set up the critical part of C environment in C.

Copy link
Member

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

* Note: it's fragile to implement wasi_thread_start in C.
* On entry, we don't even have C stack (__stack_pointer)
* set up. Be careful when modifying this function.
*/
struct start_args *args = p;
__asm__(".globaltype __tls_base, i32\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to move this into the asm file too and have __wasi_thread_start_C take tls_base as a third argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's better to make the asm minimum.
unlike stack pointer, it's simple to avoid using tls in C.

Copy link
Member

@sbc100 sbc100 Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is asm code being written inline inside of C code, which seems more complex than just doing it in the asm file. e.g. it depends on this rather obscure gcc asm syntax (I personally have to look this up every time).

I probably wouldn't argue for this if it wasn't the case that we are adding a new asm already and it defines a function that is the caller of this function. Given we have a logical place to move this inline asm it makes sense to me that it live there.

Its maybe just comes down to distaste, and perhaps mistrust of the __asm__ syntax. IIRC, the support for inline asm in for wasm in clang is pretty limited and not very well tested. we kind of made it work enough for this kind of simple case, but anything more complex and I wouldn't bet on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is asm code being written inline inside of C code, which seems more complex than just doing it in the asm file. e.g. it depends on this rather obscure gcc asm syntax (I personally have to look this up every time).

I probably wouldn't argue for this if it wasn't the case that we are adding a new asm already and it defines a function that is the caller of this function. Given we have a logical place to move this inline asm it makes sense to me that it live there.

Its maybe just comes down to distaste, and perhaps mistrust of the __asm__ syntax. IIRC, the support for inline asm in for wasm in clang is pretty limited and not very well tested. we kind of made it work enough for this kind of simple case, but anything more complex and I wouldn't bet on it.

ok. i didn't know that the support of inline asm is limited. (do you have any references?)
i moved __tls_base stuff to asm.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunfishcode might know more details as he did most of the work for make it work at all. I don't think it ever got much very testing or attention. IIUC until wasi-libc, emscripten was the only place it was used at all. Basic things like this evidently work fine, which is great, but I wouldn't bet on much more.

.globaltype __stack_pointer, i32
.functype __wasi_thread_start_C (i32, i32) -> ()

.hidden wasi_thread_start
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logically (since this is an exported function) it maybe shouldn't be hidden?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as i know, symbol visibility here is a completely separate concept from wasm export.


.export_name wasi_thread_start, wasi_thread_start

.globaltype __stack_pointer, i32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the long run we might want to make this .S rather than a .s so we can using macros like __wasm64__ to detect pointer size. e.g.: https://github.com/emscripten-core/emscripten/blob/0d7014e1b20ead9739f1fce54b316152413601c3/system/lib/compiler-rt/stack_ops.S#L6-L12

For now this seems fine though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in future, maybe.
for now, i followed the style of nearby asm files.


local.get 1 # start_arg
i32.load 4 # tls_base
global.set __tls_base
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be simpler just to pass these as two extra args to __wasi_thread_start_C? This would avoid using memory at all, be smaller in terms of code size, and be less brittle in terms of struct offsets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be simpler just to pass these as two extra args to __wasi_thread_start_C? This would avoid using memory at all, be smaller in terms of code size, and be less brittle in terms of struct offsets.

i'm not sure what you mean.
do you mean to save a pthread_self() call in the C function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I was misunderstanding. This code lgtm!

@abrown abrown merged commit 35fee1d into WebAssembly:main Jan 6, 2023
john-sharratt pushed a commit to john-sharratt/wasix-libc that referenced this pull request Mar 6, 2023
)

* Implement the critical part of wasi_thread_start in asm

It's fragile to set up the critical part of C environment in C.

* Specify --target for asm files as well

* wasi_thread_start: Move __tls_base initialization to asm as well
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants