lkml.org 
[lkml]   [2023]   [Sep]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRE: [RFC] tools/nolibc: replace duplicated -ENOSYS return with single -ENOSYS return
    Date
    Hi, David

    > ...
    > > We also need this style of checking for the delta logic in __atoi_add(). have
    > > randomly tried different clang and gcc versions, seems all of them work
    > > correctly, but the compiling speed is not that good if we want to support the
    > > worst cases like "((0x900000 + 0x0f0000) + 5)", the shorter one
    > > "((0x900000+0x0f0000)+5)" is used by ARM+OABI (not supported by nolibc
    > > currently), therefore, we can strip some tailing branches but it is either not
    > > that fast, of course, the other architectures/variants can use faster
    > > __atoi_add() versions with less branches and without hex detection, comparison
    > > and calculating.
    >
    > If there are only a few prefix offsets then the code can be optimised
    > to explicitly detect them - rather than decoding arbitrary hex values.
    > After all it only needs to decode the values that actually appear.
    >
    > The code also needs a compile-time assert that the result
    > is constant (__buitin_constant_p() will do the check.
    > But you can't use _Static_assert() to report the error
    > because that requires an 'integer constant expression'.
    >

    Thanks a lot, your above suggestion inspired me a lot.

    I have explored ARM and MIPS again and found their __NR_* definitions
    have only a 'dynamic' part, that is the right part:

    arch/mips/include/generated/uapi/asm/unistd_o32.h:#define __NR_io_uring_register (__NR_Linux + 427)
    arch/mips/include/generated/uapi/asm/unistd_o32.h:#define __NR_open_tree (__NR_Linux + 428)
    arch/mips/include/generated/uapi/asm/unistd_o32.h:#define __NR_move_mount (__NR_Linux + 429)
    arch/mips/include/generated/uapi/asm/unistd_o32.h:#define __NR_fsopen (__NR_Linux + 430)
    arch/mips/include/generated/uapi/asm/unistd_o32.h:#define __NR_fsconfig (__NR_Linux + 431)

    arch/arm/include/generated/uapi/asm/unistd-eabi.h:#define __NR_io_uring_setup (__NR_SYSCALL_BASE + 425)
    arch/arm/include/generated/uapi/asm/unistd-eabi.h:#define __NR_io_uring_enter (__NR_SYSCALL_BASE + 426)
    arch/arm/include/generated/uapi/asm/unistd-eabi.h:#define __NR_io_uring_register (__NR_SYSCALL_BASE + 427)
    arch/arm/include/generated/uapi/asm/unistd-eabi.h:#define __NR_open_tree (__NR_SYSCALL_BASE + 428)
    arch/arm/include/generated/uapi/asm/unistd-eabi.h:#define __NR_move_mount (__NR_SYSCALL_BASE + 429)

    The left part: __NR_Linux and __NR_SYSCALL_BASE are always defined, so,
    we can get their values directly, without the need of stringify and
    unstringify, as a result, the delta addition work becomes:

    base + __atoi_from(str, sizeof(#base) + 3)

    And we can simply convert our old __atoi() to __atoi_from(), change the
    fixed 0 'from' to a dynamic 'from'. and a simple __get_from() can help
    us to get the right offset for more complicated cases, such as:
    (__NR_Linux+1), (__NR_Linux + 1).

    So, the new __atoi_add() becomes:

    __atoi_add(str, base):

    --> __atoi_add(__stringify(__NR_open_tree), __NR_Linux)
    --> __atoi_add("(4000 + 428)", 4000)
    --> __atoi_from("(4000 + 428)", sizeof(#4000) + 3) + 4000
    --> __atoi_from("(4000 + 428)", 8) + 4000
    ~~~~ ^ / ~~~~
    base \___/ base
    from
    --> 428 + 4000
    --> 4428

    It is very fast and the cost time is deterministic. It also works for
    the most complicated case we have mentioned:

    __atoi_add("((0x900000+0x0f0000)+5)", (0x900000+0x0f0000))

    --> __atoi_from("((0x900000+0x0f0000)+5)", sizeof(#(0x900000+0x0f0000)) + 1) + (0x900000+0x0f0000)
    ^ /
    \_________________/
    --> ...
    --> 5 + (0x900000+0x0f0000)

    So, the calculating of the most complicated part can be simply skipped,
    we only need to convert the minimal 'dynamic' part from string to
    integer and since the 'dynamic' part is not that big, most of them may
    be less than 1000 in the not long future, only 4 characters and
    therefore only 4-level depth branches for __atoi_from(), so, even with
    hex 'dynamic' part conversion (but we may don't need it any more), the
    compile speed is also very fast.

    A simple local test on most of the architectures shows, the compile
    speed is very near to the one with our old proposed NOLIBC__NR_* macros
    for every __NR_* (defined as (-1L) when __NR_* not defined) and their
    generated binary size is the same, so, we are near the ultimate solution,
    but still need more tests. Thanks again for your positive suggestion!

    Best regards,
    Zhangjin

    > David
    >
    > -
    > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
    > Registration No: 1397386 (Wales)

    \
     
     \ /
      Last update: 2023-09-01 21:49    [W:2.118 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site