On 7/10/2023 1:47 PM, Mark Berryman wrote:co-routines.
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
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?
#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
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
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.
function test($v) {
...
$ctx = new Fiber('test');
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";
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.
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?)
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.
String as function is not limited to arguments, so creative
developers can have fun.
But fibers/kp is operating at a much lower level
than generators that are just syntactic sugar for
an object with methods.
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 54 |
| Nodes: | 6 (1 / 5) |
| Uptime: | 24:22:56 |
| Calls: | 742 |
| Files: | 1,218 |
| D/L today: |
7 files (8,805K bytes) |
| Messages: | 187,121 |
| Posted today: | 1 |