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