• Re: New PHP kits available (and a programming question)

    From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Thu Jan 1 20:51:57 2026
    From Newsgroup: comp.os.vms

    (2.5 year old thread long gone from NNTP servers, but I got time
    to look at it now)

    On Jul 10, 2023, 7:59:50rC>PM I wrote:
    On 7/10/2023 1:47 PM, Mark Berryman wrote:
    PHP 8.1 and later implement a new feature named fibers. It is
    advertised as allowing a program running in a single thread to run
    multiple threads. In reality, it simply allows one to create
    co-routines.

    In order to implement this feature, PHP needs to be able to save and
    restore execution context, as well as the ability to jump to a saved PC
    location. PHP uses the boost library to implement this and the boost
    library provides code in x86 assembly for the save/restore functions. I
    had planned to implement similar functionality for Alpha and Integrity
    using Macro32, only to discover that Macro32 doesn't provide access to
    the floating point registers.

    I have never used EXE$KP_* but in a recent thread I think it
    was agreed that they were really a coroutine implementation.
    So obvious question: could they be used to implement this?

    PHP is a very high level language and EXE$KP_* are a very
    low level construct.

    But they sure match pretty well.

    <?php

    function test($v) {
    echo "B1 ($v)\n";
    $v = Fiber::suspend(123);
    echo "B2 ($v)\n";
    $v = Fiber::suspend(456);
    echo "B3 ($v)\n";
    return 789;
    }

    echo "A1\n";
    $ctx = new Fiber('test');
    $v = $ctx->start('ABC');
    echo "A2 ($v)\n";
    $v = $ctx->resume('DEF');
    echo "A3 ($v)\n";
    $v = $ctx->resume('GHI');
    if($v === null) $v = $ctx->getReturn();
    echo "A4 ($v)\n";



    gives:

    A1
    B1 (ABC)
    A2 (123)
    B2 (DEF)
    A3 (456)
    B3 (GHI)
    A4 (789)

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #include <kpbdef.h>
    #include <exe_routines.h>

    int myalloc(int *siz, void **addr)
    {
    *addr = malloc(*siz);
    return 1;
    }

    struct myparam
    {
    int iv;
    char sv[100];
    };

    struct myparam *myparam_p(struct _kpb *ctx)
    {
    return (struct myparam *)(ctx + 1);
    }

    void test(struct _kpb *ctx)
    {
    printf("B1 (%s)\n", myparam_p(ctx)->sv);
    myparam_p(ctx)->iv = 123;
    exe$kp_stall_general(ctx);
    printf("B2 (%s)\n", myparam_p(ctx)->sv);
    myparam_p(ctx)->iv = 456;
    exe$kp_stall_general(ctx);
    printf("B3 (%s)\n", myparam_p(ctx)->sv);
    myparam_p(ctx)->iv = 789;
    exe$kp_end(ctx);
    }

    int main()
    {
    struct _kpb *ctx;
    exe$kp_user_alloc_kpb(&ctx,
    KP$M_VEST | KP$M_SET_STACK_LIMITS,
    sizeof(struct myparam),
    myalloc,
    1000000,
    exe$kp_alloc_mem_stack_user,
    10000,
    exe$kp_alloc_rse_stack_p2_any,
    NULL);
    printf("A1\n");
    strcpy(myparam_p(ctx)->sv, "ABC");
    exe$kp_start(ctx, test, KPREG$K_HLL_REG_MASK);
    printf("A2 (%d)\n", myparam_p(ctx)->iv);
    strcpy(myparam_p(ctx)->sv, "DEF");
    exe$kp_restart(ctx, 0);
    printf("A3 (%d)\n", myparam_p(ctx)->iv);
    strcpy(myparam_p(ctx)->sv, "GHI");
    exe$kp_restart(ctx, 0);
    printf("A4 (%d)\n", myparam_p(ctx)->iv);
    return 0;
    }

    gives:

    A1
    B1 (ABC)
    A2 (123)
    B2 (DEF)
    A3 (456)
    B3 (GHI)
    A4 (789)

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Thu Jan 1 20:59:57 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 8:51 PM, Arne Vajh|+j wrote:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #include <kpbdef.h>
    #include <exe_routines.h>

    int myalloc(int *siz, void **addr)
    {
    -a-a-a *addr = malloc(*siz);
    -a-a-a return 1;
    }

    struct myparam
    {
    -a-a-a int iv;
    -a-a-a char sv[100];
    };

    struct myparam *myparam_p(struct _kpb *ctx)
    {
    -a-a-a return (struct myparam *)(ctx + 1);
    }

    void test(struct _kpb *ctx)
    {
    -a-a-a printf("B1 (%s)\n", myparam_p(ctx)->sv);
    -a-a-a myparam_p(ctx)->iv = 123;
    -a-a-a exe$kp_stall_general(ctx);
    -a-a-a printf("B2 (%s)\n", myparam_p(ctx)->sv);
    -a-a-a myparam_p(ctx)->iv = 456;
    -a-a-a exe$kp_stall_general(ctx);
    -a-a-a printf("B3 (%s)\n", myparam_p(ctx)->sv);
    -a-a-a myparam_p(ctx)->iv = 789;
    -a-a-a exe$kp_end(ctx);
    }

    int main()
    {
    -a-a-a struct _kpb *ctx;
    -a-a-a exe$kp_user_alloc_kpb(&ctx,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a KP$M_VEST | KP$M_SET_STACK_LIMITS,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a sizeof(struct myparam),
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a myalloc,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 1000000,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a exe$kp_alloc_mem_stack_user,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a 10000,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a exe$kp_alloc_rse_stack_p2_any,
    -a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a NULL);
    -a-a-a printf("A1\n");
    -a-a-a strcpy(myparam_p(ctx)->sv, "ABC");
    -a-a-a exe$kp_start(ctx, test, KPREG$K_HLL_REG_MASK);
    -a-a-a printf("A2 (%d)\n", myparam_p(ctx)->iv);
    -a-a-a strcpy(myparam_p(ctx)->sv, "DEF");
    -a-a-a exe$kp_restart(ctx, 0);
    -a-a-a printf("A3 (%d)\n", myparam_p(ctx)->iv);
    -a-a-a strcpy(myparam_p(ctx)->sv, "GHI");
    -a-a-a exe$kp_restart(ctx, 0);
    -a-a-a printf("A4 (%d)\n", myparam_p(ctx)->iv);
    -a-a-a return 0;
    }

    In case anyone wants to build, then it is:

    $ cc kp + sys$library:sys$lib_c/libr
    $ link kp + sys$input/opt
    sys$loadable_images:sys$base_image/share
    $

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Robert A. Brooks@FIRST.LAST@vmssoftware.com to comp.os.vms on Thu Jan 1 22:07:36 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 8:59 PM, Arne Vajh|+j wrote:

    In case anyone wants to build, then it is:

    $ cc kp + sys$library:sys$lib_c/libr
    $ link kp + sys$input/opt
    sys$loadable_images:sys$base_image/share

    Or . . .

    $ link kp /sysexe
    --

    --- Rob
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Thu Jan 1 22:17:05 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 10:07 PM, Robert A. Brooks wrote:
    On 1/1/2026 8:59 PM, Arne Vajh|+j wrote:
    In case anyone wants to build, then it is:

    $ cc kp + sys$library:sys$lib_c/libr
    $ link kp + sys$input/opt
    sys$loadable_images:sys$base_image/share

    Or . . .

    $ link kp /sysexe

    That is much nicer.

    Thanks.

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Thu Jan 1 22:24:46 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 10:17 PM, Arne Vajh|+j wrote:
    On 1/1/2026 10:07 PM, Robert A. Brooks wrote:
    On 1/1/2026 8:59 PM, Arne Vajh|+j wrote:
    In case anyone wants to build, then it is:

    $ cc kp + sys$library:sys$lib_c/libr
    $ link kp + sys$input/opt
    sys$loadable_images:sys$base_image/share

    Or . . .

    $ link kp /sysexe

    That is much nicer.

    Thanks.

    Speaking of EXE$KP_*.

    Has DEC/CPQ/HP/HPE/VSI ever considered wrapping those
    functions in user mode only, like:

    LIB$FIBER_CREATE
    LIB$FIBER_START
    LIB$FIBER_STALL
    LIB$FIBER_RESTART
    LIB$FIBER_DESTROY

    or:

    LIB$CO_CREATE
    LIB$CO_START
    LIB$CO_STALL
    LIB$CO_RESTART
    LIB$CO_DESTROY

    ?

    Arne


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Jan 2 03:31:47 2026
    From Newsgroup: comp.os.vms

    On Thu, 1 Jan 2026 20:51:57 -0500, Arne Vajh|+j wrote:

    function test($v) {
    ...

    $ctx = new Fiber('test');

    Showing you what a crummy language PHP is: it doesnrCOt even have the
    concept of function objects, it has to fake it by passing a string
    containing the *name* of the function ... (interpreted in what scope?)
    ...
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Jan 2 03:44:11 2026
    From Newsgroup: comp.os.vms

    On Thu, 1 Jan 2026 20:51:57 -0500, Arne Vajh|+j wrote:

    function test($v) {
    echo "B1 ($v)\n";
    $v = Fiber::suspend(123);
    echo "B2 ($v)\n";
    $v = Fiber::suspend(456);
    echo "B3 ($v)\n";
    return 789;
    }

    echo "A1\n";
    $ctx = new Fiber('test');
    $v = $ctx->start('ABC');
    echo "A2 ($v)\n";
    $v = $ctx->resume('DEF');
    echo "A3 ($v)\n";
    $v = $ctx->resume('GHI');
    if($v === null) $v = $ctx->getReturn();
    echo "A4 ($v)\n";

    Python version (produces same sequence of output values):

    def test(v) :
    print("B1", v)
    v = yield 123
    print("B2", v)
    v = yield 456
    print("B3", v)
    return 789
    #end test

    try :
    print("A1")
    coro = test("ABC")
    v = coro.send(None)
    print("A2", v)
    v = coro.send("DEF")
    print("A3", v)
    v = coro.send("GHI")
    except StopIteration as ret :
    print("A4", ret.value)
    #end try

    Note this doesnrCOt even need a coroutine function (async def); a simple generator will do.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Jan 2 14:45:47 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 10:44 PM, Lawrence DrCOOliveiro wrote:
    On Thu, 1 Jan 2026 20:51:57 -0500, Arne Vajh|+j wrote:

    function test($v) {
    echo "B1 ($v)\n";
    $v = Fiber::suspend(123);
    echo "B2 ($v)\n";
    $v = Fiber::suspend(456);
    echo "B3 ($v)\n";
    return 789;
    }

    echo "A1\n";
    $ctx = new Fiber('test');
    $v = $ctx->start('ABC');
    echo "A2 ($v)\n";
    $v = $ctx->resume('DEF');
    echo "A3 ($v)\n";
    $v = $ctx->resume('GHI');
    if($v === null) $v = $ctx->getReturn();
    echo "A4 ($v)\n";

    Python version (produces same sequence of output values):

    def test(v) :
    print("B1", v)
    v = yield 123
    print("B2", v)
    v = yield 456
    print("B3", v)
    return 789
    #end test

    try :
    print("A1")
    coro = test("ABC")
    v = coro.send(None)
    print("A2", v)
    v = coro.send("DEF")
    print("A3", v)
    v = coro.send("GHI")
    except StopIteration as ret :
    print("A4", ret.value)
    #end try

    Note this doesnrCOt even need a coroutine function (async def); a simple generator will do.

    PHP has generators as well.

    The above could be done as:

    <?php

    function test($v) {
    echo "B1 ($v)\n";
    yield 123;
    echo "B2 ($v)\n";
    yield 456;
    echo "B3 ($v)\n";
    return 789;
    }

    echo "A1\n";
    $ctx = test('ABC');
    $v = $ctx->current();
    echo "A2 ($v)\n";
    $ctx->send('DEF');
    $v = $ctx->current();
    echo "A3 ($v)\n";
    $ctx->send('GHI');
    $v = $ctx->getReturn();
    echo "A4 ($v)\n";



    But fibers/kp is operating at a much lower level
    than generators that are just syntactic sugar for
    an object with methods.

    I am not sure that it matters much for Python or PHP,
    but in C it is an entirely different execution context.

    Arne



    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@arne@vajhoej.dk to comp.os.vms on Fri Jan 2 15:04:21 2026
    From Newsgroup: comp.os.vms

    On 1/1/2026 10:31 PM, Lawrence DrCOOliveiro wrote:
    On Thu, 1 Jan 2026 20:51:57 -0500, Arne Vajh|+j wrote:
    function test($v) {
    ...

    $ctx = new Fiber('test');

    Showing you what a crummy language PHP is: it doesnrCOt even have the
    concept of function objects, it has to fake it by passing a string
    containing the *name* of the function ... (interpreted in what scope?)

    Someone made a decision many years ago that the syntax should be:

    'test'

    instead of:

    test

    to specify the function as argument.

    Very unusual.

    Given that anonymous functions and arrow functions work more normal,
    then I will assume that if the PHP people were to design it today,
    then they would go for the more normal syntax. But they are stuck
    with decisions of the past like everybody else.

    So now we just have to enjoy the extra features provided by this.

    String as function is not limited to arguments, so creative
    developers can have fun.

    This works:

    <?php

    function abc_123() {
    echo "Hi from abc_123\r\n";
    }

    $a = 'abc';
    $n = 123;
    "{$a}_{$n}"();



    Arne

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Jan 2 21:01:45 2026
    From Newsgroup: comp.os.vms

    On Fri, 2 Jan 2026 15:04:21 -0500, Arne Vajh|+j wrote:

    On 1/1/2026 10:31 PM, Lawrence DrCOOliveiro wrote:

    Showing you what a crummy language PHP is: it doesnrCOt even have the
    concept of function objects, it has to fake it by passing a string
    containing the *name* of the function ... (interpreted in what
    scope?)

    Someone made a decision many years ago that the syntax should be:

    'test'

    instead of:

    test

    to specify the function as argument.

    ItrCOs not just some special rCLsyntaxrCY: itrCOs an actual string.

    String as function is not limited to arguments, so creative
    developers can have fun.

    Which is a bloody stupid way to do things. Think of how scoping has to
    work, for example.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Lawrence =?iso-8859-13?q?D=FFOliveiro?=@ldo@nz.invalid to comp.os.vms on Fri Jan 2 21:02:52 2026
    From Newsgroup: comp.os.vms

    On Fri, 2 Jan 2026 14:45:47 -0500, Arne Vajh|+j wrote:

    But fibers/kp is operating at a much lower level
    than generators that are just syntactic sugar for
    an object with methods.

    ThatrCOs just how PHP has to deal with it.
    --- Synchronet 3.21a-Linux NewsLink 1.2