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

undefined asyncify_get_state #7317

Open
andrewmd5 opened this issue Feb 24, 2025 · 3 comments
Open

undefined asyncify_get_state #7317

andrewmd5 opened this issue Feb 24, 2025 · 3 comments

Comments

@andrewmd5
Copy link

andrewmd5 commented Feb 24, 2025

Is there currently a recommended way to go about calling asyncify_get_state from inside native code? To manage this with other methods currently I'm doing:

#ifndef ASYNCJMP_SUPPORT_ASYNCIFY_H
#define ASYNCJMP_SUPPORT_ASYNCIFY_H

__attribute__((import_module("asyncify"), import_name("start_unwind"))) void asyncify_start_unwind(void *buf);
#define asyncify_start_unwind(buf)         \
    do                                     \
    {                                      \
        extern void *pl_asyncify_unwind_buf; \
        pl_asyncify_unwind_buf = (buf);      \
        asyncify_start_unwind((buf));      \
    } while (0)

__attribute__((import_module("asyncify"), import_name("stop_unwind"))) void asyncify_stop_unwind(void);
#define asyncify_stop_unwind()             \
    do                                     \
    {                                      \
        extern void *pl_asyncify_unwind_buf; \
        pl_asyncify_unwind_buf = NULL;       \
        asyncify_stop_unwind();            \
    } while (0)

__attribute__((import_module("asyncify"), import_name("start_rewind"))) void asyncify_start_rewind(void *buf);

__attribute__((import_module("asyncify"), import_name("stop_rewind"))) void asyncify_stop_rewind(void);

__attribute__((import_module("asyncify"), import_name("get_state"))) int asyncify_get_state(void);

#endif

Which all get successfully turned into exports. But for asyncify_get_state the pass raises an error:

 "/opt/wasm-opt" zeroperl_unopt -O3 -o zeroperl_unopt
Fatal: call to unidenfied asyncify import: get_state

What I'm trying to achieve:

__attribute__((noinline))
ssize_t __wrap_read(int fd, void *buf, size_t count) {
    if (asyncify_get_state() == 2) {
        asyncify_stop_rewind();
        if (have_saved_result) {
            have_saved_result = false; 
            return saved_result;
        }
        return -1;
    }

    ssize_t r = sfs_read(fd, buf, count);
    if (r >= 0) {
        return r; // Fast path succeeded
    }
    
    
    ssize_t real_val = __real_read(fd, buf, count);

        if (asyncify_get_state() == 1) {
            saved_result     = real_val;
            have_saved_result = true;

            asyncify_stop_unwind();

            return real_val;
        }


        return real_val;

}

I'm using binaryen-version_121

edit:

looking at the pass more closely I can see get_state is missing from here & here, but the documentation says that it should be there

@andrewmd5 andrewmd5 changed the title asyncify_get_state undefined asyncify_get_state Feb 24, 2025
@andrewmd5
Copy link
Author

cc: @kripken

@andrewmd5
Copy link
Author

Here is a patch that unblocks me for the time being:

diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 994142e48..f6500ed2c 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -349,6 +349,7 @@ static const Name START_UNWIND = "start_unwind";
 static const Name STOP_UNWIND = "stop_unwind";
 static const Name START_REWIND = "start_rewind";
 static const Name STOP_REWIND = "stop_rewind";
+static const Name GET_STATE = "get_state";
 static const Name ASYNCIFY_GET_CALL_INDEX = "__asyncify_get_call_index";
 static const Name ASYNCIFY_CHECK_CALL_INDEX = "__asyncify_check_call_index";
 
@@ -569,6 +570,8 @@ public:
           renamings[func->name] = ASYNCIFY_START_REWIND;
         } else if (func->base == STOP_REWIND) {
           renamings[func->name] = ASYNCIFY_STOP_REWIND;
+	} else if (func->base == GET_STATE) {
+          renamings[func->name] = ASYNCIFY_GET_STATE;
         } else {
           Fatal() << "call to unidenfied asyncify import: " << func->base;
         }
@@ -624,6 +627,8 @@ public:
               } else if (target->base == STOP_REWIND) {
                 info.canChangeState = true;
                 info.isTopMostRuntime = true;
+	      } else if (target->base == GET_STATE) {
+		// NOTE: asyncify.get_state doesn't actually change the state; NOOP
               } else {
                 WASM_UNREACHABLE("call to unidenfied asyncify import");
               }

@kripken
Copy link
Member

kripken commented Feb 24, 2025

The patch makes sense to me (though we don't need the last part that is just a comment, I think). get_state doesn't modify the state, which is why this was missed I guess. But it is part of the API. A PR would be welcome.

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

No branches or pull requests

2 participants