From b2cc4eb103ed1e67f4d91f953cdfddbb369774bd Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 10:07:17 -0500 Subject: [PATCH 01/15] Start to document kernel procedures --- actor_abi.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/actor_abi.md b/actor_abi.md index 79ea30c..b825310 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -288,3 +288,50 @@ The actor behavior may use the pre-loaded state in registers, but must write back to the actor block (through ip, which is offset +0x08) to update the persistent actor state. + +## Kernel Procedures + +### Control + +#### complete + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | event | actor | stack | -- | +| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | event' | actor' | stack | -- | + +Signal actor behavior completion. +Release completed `event` block, +and call dispatcher. +Note: This is often used as a no-op actor and/or behavior. + +#### reserve + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | block | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Reserve (allocate) a `block` (32 bytes) of memory. + +#### release + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | block | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Release (free) a `block` for allocation by `reserve`. + +### Events + +#### enqueue + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | event | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Add an `event` to the dispatch queue. + +### Actors From c6bd951e2a0362831df81c1050345a7eda4c16a0 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 10:49:34 -0500 Subject: [PATCH 02/15] Document create helpers --- actor_abi.md | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index b825310..ff49bc2 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -251,7 +251,7 @@ while jumping to the actual behavior code. +-------+-------+-------+-------+ 0x00 | mov ip, pc | +-------------------------------+ - 0x04 | ldmia ip,{r4-r7,lr,pc}| + 0x04 | ldmia ip,{r4-r8,pc} | +-------------------------------+ 0x08 | value for r4 | +-------------------------------+ @@ -261,7 +261,7 @@ while jumping to the actual behavior code. +-------------------------------+ 0x14 | value for r7 | +-------------------------------+ - 0x18 | value for lr | + 0x18 | value for r8 | +-------------------------------+ 0x1c | address of actor behavior | +-------+-------+-------+-------+ @@ -335,3 +335,87 @@ Release (free) a `block` for allocation by `reserve`. Add an `event` to the dispatch queue. ### Actors + +#### create + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Create an actor from `example_3`. +The actor behavior (offset 0x1c) is set from r0. +The default actor state is all zeros. +On entry to the actor behavior, +fp points to the event, +[fp] points to the actor, +and ip points to the actor + 0x08. +Actor state is loaded in registers as follows: +0x08:r4, 0x0c:r5, 0x10:r6, 0x14:r7, 0x18:r8. + +#### create_0 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Create an actor from `example_1`. +The actor behavior (offset 0x04) is set from r0. +On entry to the actor behavior, +fp points to the event +and ip points to the actor. + +#### create_1 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | behavior | r4 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Create a single-parameter actor. +The actor behavior (offset 0x0c) is set from r0. +Intial value for r4 (offset 0x08) is set from r1. +On entry to the actor behavior, +fp points to the event, +[fp] points to the actor, +and ip points to the actor + 0x08. +Actor state is loaded in registers as follows: +0x08:r4. + +#### create_2 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | behavior | r4 | r5 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Create a two-parameter actor. +The actor behavior (offset 0x10) is set from r0. +Intial value for r4 (offset 0x08) is set from r1. +Intial value for r5 (offset 0x0c) is set from r2. +On entry to the actor behavior, +fp points to the event, +[fp] points to the actor, +and ip points to the actor + 0x08. +Actor state is loaded in registers as follows: +0x08:r4, 0x0c:r5. + +#### create_3x + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | -- | -- | -- | -- | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | actor | xx | xx | xx | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | stack | link | + +Create a three-parameter actor. +The actor behavior (offset 0x14) is set from r7. +Intial value for r4 (offset 0x08) is set from r4. +Intial value for r5 (offset 0x0c) is set from r5. +Intial value for r6 (offset 0x10) is set from r6. +On entry to the actor behavior, +fp points to the event, +[fp] points to the actor, +and ip points to the actor + 0x08. +Actor state is loaded in registers as follows: +0x08:r4, 0x0c:r5, 0x10:r6. From 4bdd2e97b4a0e8209d645004ed88a4fd485d54dc Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 11:18:56 -0500 Subject: [PATCH 03/15] Document send helpers --- actor_abi.md | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++- mycelia.s | 2 +- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index ff49bc2..b898db2 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -330,9 +330,69 @@ Release (free) a `block` for allocation by `reserve`. | Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | |-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| | In | event | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | Add an `event` to the dispatch queue. +Note that an event must have the target actor at [r0] (offset 0x00). +The `event` address is returned in r0. + +#### send + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | target | 0x04 | 0x08 | 0x0c | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | stack | link | + +Send a message. +Registers r0-r7 are arranged +exactly like the event structure, +starting with the `target` actor in r0. +The message data is in r1-r7. +An event block is created, initialized, and enqueued. + +#### send_0 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | target | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Send an empty message to `target`. +An event block is created, initialized, and enqueued. + +#### send_1 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | target | 0x04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Send a one-word message to `target`. +The message data is in r1. +An event block is created, initialized, and enqueued. + +#### send_2 + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | target | 0x04 | 0x08 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | + +Send a two-word message to `target`. +The message data is in r1 and r2. +An event block is created, initialized, and enqueued. + +#### send_3x + +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| +| In | -- | -- | -- | -- | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | stack | link | +| Out | event | xx | xx | xx | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | stack | link | + +Send a three-word message to `target`. +The target actor is in r4. +The message data is in r5-r7. +An event block is created, initialized, and enqueued. ### Actors diff --git a/mycelia.s b/mycelia.s index eb7a4ff..54c5a26 100644 --- a/mycelia.s +++ b/mycelia.s @@ -371,7 +371,7 @@ create_3x: @ create 3 parameter actor (r4-r6=state, r7=behavior) .text .align 2 @ align to machine word .global send -send: @ send 1 parameter message (r0=target, r1-r7=message) +send: @ send a message (r0=target, r1-r7=message) stmdb sp!, {r4-r8,lr} @ preserve in-use registers stmdb sp!, {r0-r7} @ preserve event data bl reserve @ allocate event block From 6b9839f5f3740b29d860ae755b524c522c605fbb Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 11:24:12 -0500 Subject: [PATCH 04/15] Prune sp and lr from register tables --- actor_abi.md | 112 +++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index b898db2..181a052 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -295,10 +295,10 @@ to update the persistent actor state. #### complete -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | event | actor | stack | -- | -| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | event' | actor' | stack | -- | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | event | actor | +| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | event' | actor' | Signal actor behavior completion. Release completed `event` block, @@ -307,19 +307,19 @@ Note: This is often used as a no-op actor and/or behavior. #### reserve -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | block | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | block | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Reserve (allocate) a `block` (32 bytes) of memory. #### release -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | block | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | block | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | xx | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Release (free) a `block` for allocation by `reserve`. @@ -327,10 +327,10 @@ Release (free) a `block` for allocation by `reserve`. #### enqueue -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | event | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | event | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Add an `event` to the dispatch queue. Note that an event must have the target actor at [r0] (offset 0x00). @@ -338,10 +338,10 @@ The `event` address is returned in r0. #### send -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | target | 0x04 | 0x08 | 0x0c | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | target | 0x04 | 0x08 | 0x0c | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | 0x10 | 0x14 | 0x18 | 0x1c | -- | -- | -- | sponsor | -- | -- | Send a message. Registers r0-r7 are arranged @@ -352,20 +352,20 @@ An event block is created, initialized, and enqueued. #### send_0 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | target | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | target | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Send an empty message to `target`. An event block is created, initialized, and enqueued. #### send_1 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | target | 0x04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | target | 0x04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Send a one-word message to `target`. The message data is in r1. @@ -373,10 +373,10 @@ An event block is created, initialized, and enqueued. #### send_2 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | target | 0x04 | 0x08 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | target | 0x04 | 0x08 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Send a two-word message to `target`. The message data is in r1 and r2. @@ -384,10 +384,10 @@ An event block is created, initialized, and enqueued. #### send_3x -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | -- | -- | -- | -- | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | event | xx | xx | xx | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | -- | -- | -- | -- | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | +| Out | event | xx | xx | xx | target | 0x04 | 0x08 | 0x10 | -- | -- | -- | sponsor | -- | -- | Send a three-word message to `target`. The target actor is in r4. @@ -398,10 +398,10 @@ An event block is created, initialized, and enqueued. #### create -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Create an actor from `example_3`. The actor behavior (offset 0x1c) is set from r0. @@ -415,10 +415,10 @@ Actor state is loaded in registers as follows: #### create_0 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | behavior | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Create an actor from `example_1`. The actor behavior (offset 0x04) is set from r0. @@ -428,10 +428,10 @@ and ip points to the actor. #### create_1 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | behavior | r4 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | behavior | r4 | -- | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Create a single-parameter actor. The actor behavior (offset 0x0c) is set from r0. @@ -445,10 +445,10 @@ Actor state is loaded in registers as follows: #### create_2 -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | behavior | r4 | r5 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | behavior | r4 | r5 | -- | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | +| Out | actor | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Create a two-parameter actor. The actor behavior (offset 0x10) is set from r0. @@ -463,10 +463,10 @@ Actor state is loaded in registers as follows: #### create_3x -| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | sp | lr | -|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----|----|----| -| In | -- | -- | -- | -- | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | stack | link | -| Out | actor | xx | xx | xx | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | stack | link | +| Reg | r0 | r1 | r2 | r3 | r4 | r5 | r6 | r7 | r8 | r9 | r10 | sl | fp | ip | +|-----|----|----|----|----|----|----|----|----|----|----|-----|----|----|----| +| In | -- | -- | -- | -- | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | +| Out | actor | xx | xx | xx | r4 | r5 | r6 | behavior | -- | -- | -- | sponsor | -- | -- | Create a three-parameter actor. The actor behavior (offset 0x14) is set from r7. From c1bcf3c69f4cae6f09564c1a9fcd32a0f8e264cf Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 11:27:34 -0500 Subject: [PATCH 05/15] Escape square brackets --- actor_abi.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index 181a052..b3d1126 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -333,7 +333,7 @@ Release (free) a `block` for allocation by `reserve`. | Out | event | xx | xx | xx | -- | -- | -- | -- | -- | -- | -- | sponsor | -- | -- | Add an `event` to the dispatch queue. -Note that an event must have the target actor at [r0] (offset 0x00). +Note that an event must have the target actor at \[r0\] (offset 0x00). The `event` address is returned in r0. #### send @@ -408,7 +408,7 @@ The actor behavior (offset 0x1c) is set from r0. The default actor state is all zeros. On entry to the actor behavior, fp points to the event, -[fp] points to the actor, +\[fp\] points to the actor, and ip points to the actor + 0x08. Actor state is loaded in registers as follows: 0x08:r4, 0x0c:r5, 0x10:r6, 0x14:r7, 0x18:r8. @@ -438,7 +438,7 @@ The actor behavior (offset 0x0c) is set from r0. Intial value for r4 (offset 0x08) is set from r1. On entry to the actor behavior, fp points to the event, -[fp] points to the actor, +\[fp\] points to the actor, and ip points to the actor + 0x08. Actor state is loaded in registers as follows: 0x08:r4. @@ -456,7 +456,7 @@ Intial value for r4 (offset 0x08) is set from r1. Intial value for r5 (offset 0x0c) is set from r2. On entry to the actor behavior, fp points to the event, -[fp] points to the actor, +\[fp\] points to the actor, and ip points to the actor + 0x08. Actor state is loaded in registers as follows: 0x08:r4, 0x0c:r5. @@ -475,7 +475,7 @@ Intial value for r5 (offset 0x0c) is set from r5. Intial value for r6 (offset 0x10) is set from r6. On entry to the actor behavior, fp points to the event, -[fp] points to the actor, +\[fp\] points to the actor, and ip points to the actor + 0x08. Actor state is loaded in registers as follows: 0x08:r4, 0x0c:r5, 0x10:r6. From 2a17b9fb49c8af967dfad3dcc2bad8bf03e1c2a0 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 13:43:03 -0500 Subject: [PATCH 06/15] Start documenting built-in actors --- actor_abi.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/actor_abi.md b/actor_abi.md index b3d1126..e6f627d 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -1,5 +1,6 @@ # Actor ABI + ## Memory Memory is managed in cache-line-aligned blocks of 32 bytes (8x32-bit words). @@ -10,6 +11,7 @@ Blocks may be chained in order to extend the available storage as needed. + ## Registers On entry to an actor behavior, @@ -54,6 +56,7 @@ will expect r10 (sl) to remain stable, pointing to the sponsor. Note that actors should consider the sponsor opaque. + ## Event Structure An event block begins with the address of the actor @@ -87,6 +90,7 @@ The ok customer (at offset 0x04) for success/true results, and the fail customer (at offet 0x08) for failure/false results. Additional parameters may follow starting at offset 0x0c. + ## Actor Structure The target actor may be accessed through the event block (offset 0x00), @@ -289,6 +293,7 @@ but must write back to the actor block (through ip, which is offset +0x08) to update the persistent actor state. + ## Kernel Procedures ### Control @@ -479,3 +484,77 @@ fp points to the event, and ip points to the actor + 0x08. Actor state is loaded in registers as follows: 0x08:r4, 0x0c:r5, 0x10:r6. + +## Actor/Behavior Library + +### Built-In Actors + +#### a_ignore + +Ignore all messages. + +| Offset | Actor Field | +|--------|-------| +| 0x00 | code | +| 0x04 | -- | +| 0x08 | -- | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | -> a_ignore +| 0x04 | msg_1 | +| 0x08 | msg_2 | +| 0x0c | msg_3 | +| 0x10 | msg_4 | +| 0x14 | msg_5 | +| 0x18 | msg_6 | +| 0x1c | msg_7 | + +Note: This actor is not usually needed, +since `complete` can be referenced directly +(as if it were an actor). + +#### a_forward + +Foward message to `delegate`. + +| Offset | Actor Field | +|--------|-------| +| 0x00 | code | +| 0x04 | code | +| 0x08 | code | +| 0x0c | code | +| 0x10 | code | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | delegate | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target = a_forward | +| 0x04 | msg_1 | +| 0x08 | msg_2 | +| 0x0c | msg_3 | +| 0x10 | msg_4 | +| 0x14 | msg_5 | +| 0x18 | msg_6 | +| 0x1c | msg_7 | + +Note: This actor is used in the implementation of `a_oneshot`. + +#### a_oneshot + +#### a_fork + +### Built-In Behaviors + +#### b_label + +#### b_tag + +#### b_join From 9c6a0099c6929ac028abf795f93a3721abea5ef3 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 14:20:05 -0500 Subject: [PATCH 07/15] Document a_fork --- actor_abi.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++-- idiom.s | 22 +++++++-------- 2 files changed, 85 insertions(+), 14 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index e6f627d..b54d3aa 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -27,7 +27,7 @@ Consistent special meanings are given to r10-r15. | Register | Kernel Usage | Actor Usage | |----------|-----------------|-----------------| -| r0 | arg_0 / return | block address | +| r0 | arg_0 / result | block address | | r1 | arg_1 / tmp_1 | target / answer | | r2 | arg_2 / tmp_2 | base address | | r3 | arg_3 / tmp_3 | working data | @@ -506,7 +506,7 @@ Ignore all messages. | Offset | Event Field | |--------|-------| -| 0x00 | target | -> a_ignore +| 0x00 | target = a_ignore | | 0x04 | msg_1 | | 0x08 | msg_2 | | 0x0c | msg_3 | @@ -522,6 +522,8 @@ since `complete` can be referenced directly #### a_forward Foward message to `delegate`. +**WARNING**: _Do not use `a_forward` directly. +Clone it, then change the `delegate` in your copy._ | Offset | Actor Field | |--------|-------| @@ -532,7 +534,7 @@ Foward message to `delegate`. | 0x10 | code | | 0x14 | -- | | 0x18 | -- | -| 0x1c | delegate | +| 0x1c | delegate = a_ignore | | Offset | Event Field | |--------|-------| @@ -549,8 +551,77 @@ Note: This actor is used in the implementation of `a_oneshot`. #### a_oneshot +Forward first message to `delegate`, +then ignore all subsequent messages. +**WARNING**: _Do not use `a_oneshot` directly. +Clone it, then change the `delegate` in your copy._ + +| Offset | Actor Field | +|--------|-------| +| 0x00 | code | +| 0x04 | code | +| 0x08 | code | +| 0x0c | code | +| 0x10 | -- | +| 0x14 | next behavior | +| 0x18 | current behavior | +| 0x1c | delegate = a_ignore | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target = a_oneshot | +| 0x04 | msg_1 | +| 0x08 | msg_2 | +| 0x0c | msg_3 | +| 0x10 | msg_4 | +| 0x14 | msg_5 | +| 0x18 | msg_6 | +| 0x1c | msg_7 | + +This actor uses the behavior of `a_forward` +to forward the first message it receives. +It then modifies the `current behavior` field +to ignore all subsequent messages. + #### a_fork +Initiate two concurrent service-events. + +| Offset | Event Field | +|--------|-------| +| 0x00 | target = a_fork | +| 0x04 | customer | +| 0x08 | event_0 | +| 0x0c | event_1 | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +This actor is a factory for a group of actors +that collaborate to execute overlapping events. +The `event_0` and `event_1` parameters are events, +prepared by not enqueued, +with appropriate targets and parameters. +The targets for `event_0` and `event_1` must be _services_. +This is, they must be actors which expect a single `customer` +as their first message parameter. +Note that the `customer` in each event will be overwritten +with a factory-generated proxy customer. +The results from both events will be combined into a single message +and sent to the original `customer`, like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | target = customer | +| 0x04 | event_0 result 0x04 | +| 0x08 | event_1 result 0x04 | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + ### Built-In Behaviors #### b_label diff --git a/idiom.s b/idiom.s index eb2138c..011f77c 100644 --- a/idiom.s +++ b/idiom.s @@ -124,37 +124,37 @@ b_tag: @ label one message with actor identity (r4=customer) .align 5 @ align to cache-line .global b_join b_join: @ combine results of concurrent computation - @ (r4=customer, r5=event/answer_0, r6=event/answer_1) - @ message = (tag, answer) + @ (r4=customer, r5=event/result_0, r6=event/result_1) + @ message = (tag, result) ldr r0, [fp, #0x04] @ get tag cmp r0, r5 bne 1f @ if tag == event_0 - ldr r5, [fp, #0x08] @ remember answer_0 - ldr r9, =_join_0 @ wait for answer_1 + ldr r5, [fp, #0x08] @ remember result_0 + ldr r9, =_join_0 @ wait for result_1 b 3f 1: cmp r0, r6 bne complete @ if tag == event_1 - ldr r6, [fp, #0x08] @ remember answer_1 - ldr r9, =_join_1 @ wait for answer_0 + ldr r6, [fp, #0x08] @ remember result_1 + ldr r9, =_join_1 @ wait for result_0 b 3f .align 5 @ align to cache-line -_join_0: @ wait for answer_1 +_join_0: @ wait for result_1 ldr r0, [fp, #0x04] @ get tag cmp r0, r6 @ if tag == event_1 - ldreq r6, [fp, #0x08] @ get answer_1 + ldreq r6, [fp, #0x08] @ get result_1 beq 2f @ else b complete @ ignore message .align 5 @ align to cache-line -_join_1: @ wait for answer_0 +_join_1: @ wait for result_0 ldr r0, [fp, #0x04] @ get tag cmp r0, r5 @ if tag == event_0 - ldreq r5, [fp, #0x08] @ get answer_0 + ldreq r5, [fp, #0x08] @ get result_0 beq 2f @ else b complete @ ignore message 2: bl reserve @ allocate event block - stmia r0, {r4-r6} @ set (customer, answer_0, answer_1) + stmia r0, {r4-r6} @ set (customer, result_0, result_1) bl enqueue @ add event to queue ldr r9, =complete @ ignore future messages 3: From 41ab3ae32a9258b93bab0fcf0aec1c4b22a0ed26 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 16:35:35 -0500 Subject: [PATCH 08/15] Document b_label and b_tag --- actor_abi.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++----- idiom.s | 10 ++--- 2 files changed, 100 insertions(+), 15 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index b54d3aa..84bb43f 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -495,7 +495,7 @@ Ignore all messages. | Offset | Actor Field | |--------|-------| -| 0x00 | code | +| 0x00 | _code_ | | 0x04 | -- | | 0x08 | -- | | 0x0c | -- | @@ -522,16 +522,17 @@ since `complete` can be referenced directly #### a_forward Foward message to `delegate`. + **WARNING**: _Do not use `a_forward` directly. Clone it, then change the `delegate` in your copy._ | Offset | Actor Field | |--------|-------| -| 0x00 | code | -| 0x04 | code | -| 0x08 | code | -| 0x0c | code | -| 0x10 | code | +| 0x00 | _code_ | +| 0x04 | _code_ | +| 0x08 | _code_ | +| 0x0c | _code_ | +| 0x10 | _code_ | | 0x14 | -- | | 0x18 | -- | | 0x1c | delegate = a_ignore | @@ -553,15 +554,16 @@ Note: This actor is used in the implementation of `a_oneshot`. Forward first message to `delegate`, then ignore all subsequent messages. + **WARNING**: _Do not use `a_oneshot` directly. Clone it, then change the `delegate` in your copy._ | Offset | Actor Field | |--------|-------| -| 0x00 | code | -| 0x04 | code | -| 0x08 | code | -| 0x0c | code | +| 0x00 | _code_ | +| 0x04 | _code_ | +| 0x08 | _code_ | +| 0x0c | _code_ | | 0x10 | -- | | 0x14 | next behavior | | 0x18 | current behavior | @@ -626,6 +628,89 @@ and sent to the original `customer`, like this: #### b_label +Add `label` to message and forward to `delegate`. + +| Offset | Actor Field | +|--------|-------| +| 0x00 | _code_ | +| 0x04 | _code_ | +| 0x08 | r4: delegate | +| 0x0c | r5: label | +| 0x10 | behavior = b_label | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | msg_1 | +| 0x08 | msg_2 | +| 0x0c | msg_3 | +| 0x10 | msg_4 | +| 0x14 | msg_5 | +| 0x18 | msg_6 | +| 0x1c | -- | + +Note that the data at offset 0x1c in the inbound message +is not copied because we have to make room for the label. +After adding the label, the generated event looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | delegate | +| 0x04 | label | +| 0x08 | msg_1 | +| 0x0c | msg_2 | +| 0x10 | msg_3 | +| 0x14 | msg_4 | +| 0x18 | msg_5 | +| 0x1c | msg_6 | + #### b_tag +Label message with actor identity and forward to `delegate`. +Tag actors are often created as proxy customers +when we want to identify the source of a particular response. + +| Offset | Actor Field | +|--------|-------| +| 0x00 | _code_ | +| 0x04 | _code_ | +| 0x08 | r4: delegate | +| 0x0c | behavior = b_tag | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | msg_1 | +| 0x08 | msg_2 | +| 0x0c | msg_3 | +| 0x10 | msg_4 | +| 0x14 | msg_5 | +| 0x18 | msg_6 | +| 0x1c | -- | + +Note that the data at offset 0x1c in the inbound message +is dropped because we have to make room for the label. +This behavior modifies the inbound event, +adding it's own identity as a label, +and re-dispatches it without going through the event queue. +The modified event looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | delegate | +| 0x04 | target | +| 0x08 | msg_1 | +| 0x0c | msg_2 | +| 0x10 | msg_3 | +| 0x14 | msg_4 | +| 0x18 | msg_5 | +| 0x1c | msg_6 | + #### b_join diff --git a/idiom.s b/idiom.s index 011f77c..49f7c19 100644 --- a/idiom.s +++ b/idiom.s @@ -101,9 +101,9 @@ _fork_0: @ create tag actor .text .align 5 @ align to cache-line .global b_label -b_label: @ add label to message (r4=customer, r5=label) +b_label: @ add label to message (r4=delegate, r5=label) bl reserve @ allocate event block - str r4, [fp] @ replace target with customer + str r4, [fp] @ replace target with delegate mov r3, r5 @ move label into position ldmia fp, {r2,r4-r9} @ copy request (drop last word) stmia r0, {r2-r9} @ write new event @@ -113,12 +113,12 @@ b_label: @ add label to message (r4=customer, r5=label) .text .align 5 @ align to cache-line .global b_tag -b_tag: @ label one message with actor identity (r4=customer) - mov r2, r4 @ move customer into position +b_tag: @ label message with actor identity (r4=delegate) + mov r2, r4 @ move delegate into position ldmia fp, {r3-r9} @ copy request (drop last word, r3=label) stmia fp, {r2-r9} @ overwrite event mov ip, r2 @ get target actor address - bx ip @ jump to customer behavior + bx ip @ jump to delegate behavior .text .align 5 @ align to cache-line From 601ec92e0f5d35b7334cb5f408caf2d41fe5a2ef Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 16:50:29 -0500 Subject: [PATCH 09/15] Document b_join --- actor_abi.md | 42 ++++++++++++++++++++++++++++++++++++++++++ idiom.s | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/actor_abi.md b/actor_abi.md index 84bb43f..7e250ba 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -714,3 +714,45 @@ The modified event looks like this: | 0x1c | msg_6 | #### b_join + +Combine results of concurrent computation. +Join actors are automatically generated by `a_fork` +to capture the results of concurrent event processing. +Results are expected to come through proxy customers with `b_tag` behavior, +so `b_join` can distinguish between the two results. + +| Offset | Actor Field | +|--------|-------| +| 0x00 | _code_ | +| 0x04 | _code_ | +| 0x08 | r4: customer | +| 0x0c | r5: tag/result_0 | +| 0x10 | r6: tag/result_1 | +| 0x14 | behavior = b_join | +| 0x18 | -- | +| 0x1c | -- | + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | tag | +| 0x08 | result | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +After both results have arrived, +a combined result event is generated: + +| Offset | Event Field | +|--------|-------| +| 0x00 | customer | +| 0x04 | result_0 | +| 0x08 | result_1 | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | diff --git a/idiom.s b/idiom.s index 49f7c19..63c70b9 100644 --- a/idiom.s +++ b/idiom.s @@ -124,7 +124,7 @@ b_tag: @ label message with actor identity (r4=delegate) .align 5 @ align to cache-line .global b_join b_join: @ combine results of concurrent computation - @ (r4=customer, r5=event/result_0, r6=event/result_1) + @ (r4=customer, r5=tag/result_0, r6=tag/result_1) @ message = (tag, result) ldr r0, [fp, #0x04] @ get tag cmp r0, r5 From 1ac433a7e1808cdb55d829c0fee557ee89f0c004 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 18:23:43 -0500 Subject: [PATCH 10/15] Document b_literal Beginning to design actor capabilities --- actor_abi.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ idiom.s | 14 +++++++++ 2 files changed, 95 insertions(+) diff --git a/actor_abi.md b/actor_abi.md index 7e250ba..701c3f4 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -756,3 +756,84 @@ a combined result event is generated: | 0x14 | -- | | 0x18 | -- | | 0x1c | -- | + +### Actor Capabilities + +A typical view of object (and actors) +is that they have an "interface", +or vocabulary of message types they understand. +In practice, +this means that a message-event +must contain a "selector" +(usually a "name", but sometimes a "signature") +that identifies what kind of message it is. +The object/actor uses the selector +to (polymorphically) dispatch the message +to the proper implementation code. + +Instead, we will consider each actor reference +to be a _capability_ that already knows what operation is expected. +An interface, then, consists of a collection of capabilities +that access and/or operate on some hidden shared state. +This is similar to the concept of "facets" +in some object-oriented systems. +It also provides fine-grained access control +by limiting the availability of certain capabilities. +The access-graph becomes the authority-graph. + +In addition, we will generalize the idea of "return value" +(for services with a call-response protocol) +by introducing a pair of _customers_ called "ok" and "fail". +The _ok_ customer will be the capability +to whom a successful result should be delivered. +The _fail_ customer will be the capability +to whom a failure notification may be send. +This transforms exception handling into simple message-flow. + +#### Evaluation + +A critical capability for general computation +is _evaluation_ in the context of an _environment_. +Evaluation produces a _value_, +but cannot cause any _effects_. +The protocol for evaluation involves +sending a request and receiving a response. +The request looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | ok | +| 0x08 | fail | +| 0x0c | environment | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +If the request is "successful", +a response is sent to `ok` +that looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | ok | +| 0x04 | result | +| 0x08 | -- | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +If the request is "unsuccessful", +the original event is immediately delivered to `fail` +_without going through the event queue_. +Note that this means the `target` +will **not** be the `fail` actor. + +#### b_literal + +The _evaluation_ capability for a _literal_ +simply responds with the identity of the target. + diff --git a/idiom.s b/idiom.s index 63c70b9..9e8642b 100644 --- a/idiom.s +++ b/idiom.s @@ -161,6 +161,20 @@ _join_1: @ wait for result_0 stmia ip,{r4-r9} @ copy state and behavior b complete @ return to dispatch loop +@ +@ actor capabilities +@ + + .text + .align 5 @ align to cache-line + .global b_literal +b_literal: @ a literal evaluates to itself + @ message = (ok, fail, environment) + ldr r0, [fp, #0x04] @ get ok customer + ldr r1, [fp] @ get target (self) + bl send_1 @ send self to customer + b complete @ return to dispatch loop + @ @ unit test actors and behaviors @ From 0be868d601babbdfb20379517527fff43a5948df Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 18:33:00 -0500 Subject: [PATCH 11/15] Document b_constant --- actor_abi.md | 7 ++++++- idiom.s | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/actor_abi.md b/actor_abi.md index 701c3f4..b8aebb9 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -835,5 +835,10 @@ will **not** be the `fail` actor. #### b_literal The _evaluation_ capability for a _literal_ -simply responds with the identity of the target. +always responds with the identity of the target. +#### b_constant + +The _evaluation_ capability for a _constant_ +responds with a consistent _value_ +regardless of the _environment_ in which it is evaluated. diff --git a/idiom.s b/idiom.s index 9e8642b..06ea1de 100644 --- a/idiom.s +++ b/idiom.s @@ -175,6 +175,17 @@ b_literal: @ a literal evaluates to itself bl send_1 @ send self to customer b complete @ return to dispatch loop + .text + .align 5 @ align to cache-line + .global b_constant +b_constant: @ a constant evaluates to a consistent value + @ (0x08: r4=value) + @ message = (ok, fail, environment) + ldr r0, [fp, #0x04] @ get ok customer + mov r1, r4 @ get constant value + bl send_1 @ send value to customer + b complete @ return to dispatch loop + @ @ unit test actors and behaviors @ From 5c5cb04150c92c20f21e5c1d4a3cce7d27240bf3 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 19:01:19 -0500 Subject: [PATCH 12/15] Implement b_load / b_store --- actor_abi.md | 9 +++++++++ idiom.s | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index b8aebb9..9d0e715 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -842,3 +842,12 @@ always responds with the identity of the target. The _evaluation_ capability for a _constant_ responds with a consistent _value_ regardless of the _environment_ in which it is evaluated. + +#### b_load / b_store + +A primitive mutable value supports two capabilities, +_load_ and _store_. +The _load_ capability retrieves the currently stored value, +and responds with that value. +The _store_ capability replaces the stored value, +and responds with the value stored. diff --git a/idiom.s b/idiom.s index 06ea1de..c0057e7 100644 --- a/idiom.s +++ b/idiom.s @@ -172,7 +172,7 @@ b_literal: @ a literal evaluates to itself @ message = (ok, fail, environment) ldr r0, [fp, #0x04] @ get ok customer ldr r1, [fp] @ get target (self) - bl send_1 @ send self to customer + bl send_1 @ send self to ok b complete @ return to dispatch loop .text @@ -183,7 +183,35 @@ b_constant: @ a constant evaluates to a consistent value @ message = (ok, fail, environment) ldr r0, [fp, #0x04] @ get ok customer mov r1, r4 @ get constant value - bl send_1 @ send value to customer + bl send_1 @ send value to ok + b complete @ return to dispatch loop + + .text + .align 5 @ align to cache-line + .global b_load +b_load: @ retrieve the currently stored value + @ (0x08: r4=value) + @ message = (ok, fail, environment) + ldr r0, [fp, #0x04] @ get ok customer + mov r1, r4 @ get constant value + bl send_1 @ send value to ok + b complete @ return to dispatch loop + + .text + .align 5 @ align to cache-line + .global b_store +b_store: @ store a replacement value + @ (0x08: r4=load_cap) + @ message = (ok, fail, value) + ldr r0, [r4, #0x0c] @ get load_cap behavior + ldr r1, =b_load @ get b_load behavior + cmp r0, r1 @ if load_cap is not a b_load actor + ldrne ip, [fp, #0x08] @ ip = fail customer + bxne ip @ dispatch to fail + ldr r1, [fp, #0x0c] @ get replacement value + str r1, [r4, #0x08] @ store replacement value + ldr r0, [fp, #0x04] @ get ok customer + bl send_1 @ send response b complete @ return to dispatch loop @ From fb68acb603fe8dc8214081fae88679bdd90d3a70 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Wed, 30 Jul 2014 22:00:41 -0500 Subject: [PATCH 13/15] Document a_undefined and b_arrow --- actor_abi.md | 40 ++++++++++++++++++++++++++++++++++++++++ idiom.s | 4 ++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index 9d0e715..fda95d8 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -851,3 +851,43 @@ The _load_ capability retrieves the currently stored value, and responds with that value. The _store_ capability replaces the stored value, and responds with the value stored. +The protocol for _store_ is not _evaluation_, +but is very similar. +Instead of receiving an _environment_, +there is a generic _parameter_ +(the new value to store, in this case). + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | ok | +| 0x08 | fail | +| 0x0c | parameter | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +#### a_undefined / b_arrow + +A primitive generalization of partial functions +can be expressed with `a_undefined` and `b_arrow`. +The protocol is the same as `b_store`, +taking a _parameter_ and returning a _result_. + +The actor `a_undefined` is the root/failure case. +It immediately calls `fail`. +It can be used to terminate a search-chain, +or provide a default. + +The `b_arrow` behavior demonstrates an explicit finite-mapping, +with each actor instance providing a _result_ +for a particular _parameter_ value. +The resulting structure +is a linear-search dictionary +of "name/value" pairs +terminated by `a_undefined`. + +Note that a variety of alternative implementations are possible, +consistent with the same _parameter_/_result_-or-fail protocol. +Functional algorithms, including recursion, can be easily supported. diff --git a/idiom.s b/idiom.s index c0057e7..8f435dd 100644 --- a/idiom.s +++ b/idiom.s @@ -208,8 +208,8 @@ b_store: @ store a replacement value cmp r0, r1 @ if load_cap is not a b_load actor ldrne ip, [fp, #0x08] @ ip = fail customer bxne ip @ dispatch to fail - ldr r1, [fp, #0x0c] @ get replacement value - str r1, [r4, #0x08] @ store replacement value + ldr r1, [fp, #0x0c] @ get parameter value + str r1, [r4, #0x08] @ replace stored value ldr r0, [fp, #0x04] @ get ok customer bl send_1 @ send response b complete @ return to dispatch loop From 8d0cee943268065b6bca37fa68a644a047e2f385 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Thu, 31 Jul 2014 06:52:02 -0500 Subject: [PATCH 14/15] Implement a_undefined and b_arrow --- idiom.s | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/idiom.s b/idiom.s index 8f435dd..1b13890 100644 --- a/idiom.s +++ b/idiom.s @@ -214,6 +214,38 @@ b_store: @ store a replacement value bl send_1 @ send response b complete @ return to dispatch loop + .text + .align 5 @ align to cache-line + .global a_undefined +a_undefined: @ this actor immediately calls `fail` + @ message = (ok, fail, parameter) + ldr ip, [fp, #0x08] @ ip = fail customer + bx ip @ dispatch to fail + .int 0 @ 0x08: -- + .int 0 @ 0x0c: -- + .int 0 @ 0x10: -- + .int 0 @ 0x14: -- + .int 0 @ 0x18: -- + .int 0 @ 0x1c: -- + + .text + .align 5 @ align to cache-line + .global b_arrow +b_arrow: @ explicit mapping (chain of "name/value" pairs) + @ (r4=name, r5=value, r6=next) + @ message = (ok, fail, parameter) + bl reserve @ allocate event block + mov r7, r0 @ remember block address + ldmia fp, {r0-r3} @ (r0:target, r1:ok, r2:fail, r3:parameter) + cmp r3, r4 @ if parameter == name + streq r2, [r7] @ target: ok + streq r5, [r7, #0x04] @ result: value + movne r0, r6 @ else + stmneia r7, {r0-r3} @ forward to next + mov r0, r7 @ prepare event + bl enqueue @ add event to queue + b complete @ return to dispatch loop + @ @ unit test actors and behaviors @ From bbf97ebc5f82fe7816447949e554169557cbb972 Mon Sep 17 00:00:00 2001 From: Dale Schumacher Date: Thu, 31 Jul 2014 08:18:16 -0500 Subject: [PATCH 15/15] Document streams, implement a_end --- actor_abi.md | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++-- idiom.s | 18 +++++++++-- 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/actor_abi.md b/actor_abi.md index fda95d8..cebf6d4 100644 --- a/actor_abi.md +++ b/actor_abi.md @@ -757,7 +757,8 @@ a combined result event is generated: | 0x18 | -- | | 0x1c | -- | -### Actor Capabilities + +## Actor Capabilities A typical view of object (and actors) is that they have an "interface", @@ -790,7 +791,7 @@ The _fail_ customer will be the capability to whom a failure notification may be send. This transforms exception handling into simple message-flow. -#### Evaluation +### Evaluation A critical capability for general computation is _evaluation_ in the context of an _environment_. @@ -875,7 +876,7 @@ can be expressed with `a_undefined` and `b_arrow`. The protocol is the same as `b_store`, taking a _parameter_ and returning a _result_. -The actor `a_undefined` is the root/failure case. +The actor `a_undefined` is the base/failure case. It immediately calls `fail`. It can be used to terminate a search-chain, or provide a default. @@ -891,3 +892,85 @@ terminated by `a_undefined`. Note that a variety of alternative implementations are possible, consistent with the same _parameter_/_result_-or-fail protocol. Functional algorithms, including recursion, can be easily supported. + +### Streams + +Streams are a primitive abstraction of seqential access patterns. +A _read_ capability consumes an element from the stream. +A _write_ capability produces an element to the stream. + +A _read_ request looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | ok | +| 0x08 | fail | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +If the request is "successful", +a response is sent to `ok` +that looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | ok | +| 0x04 | element | +| 0x08 | next | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +The `next` field in a _read_ response +is the _read_ capability for subsequent requests. +Each _read_ capability can be thought of +as a "cursor position" in the stream. + +A _write_ request looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | target | +| 0x04 | ok | +| 0x08 | fail | +| 0x0c | element | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +If the request is "successful", +a response is sent to `ok` +that looks like this: + +| Offset | Event Field | +|--------|-------| +| 0x00 | ok | +| 0x04 | next | +| 0x08 | -- | +| 0x0c | -- | +| 0x10 | -- | +| 0x14 | -- | +| 0x18 | -- | +| 0x1c | -- | + +The `next` field in a _write_ response +is the _write_ capability for subsequent requests. +Each _write_ capability can be thought of +as a "cursor position" in the stream. + +#### a_end + +The actor `a_end` immediately calls `fail`. +As a _read_ capability it represents the base/empty case. +As a _write_ capability it represents the final/full case. +The call to `fail` can often be avoided +by comparing your _read_/_write_ capability +(such as the value of `next`) +to `a_end` before using it. diff --git a/idiom.s b/idiom.s index 1b13890..f4c9405 100644 --- a/idiom.s +++ b/idiom.s @@ -200,7 +200,7 @@ b_load: @ retrieve the currently stored value .text .align 5 @ align to cache-line .global b_store -b_store: @ store a replacement value +b_store: @ assign a replacement value @ (0x08: r4=load_cap) @ message = (ok, fail, value) ldr r0, [r4, #0x0c] @ get load_cap behavior @@ -217,7 +217,7 @@ b_store: @ store a replacement value .text .align 5 @ align to cache-line .global a_undefined -a_undefined: @ this actor immediately calls `fail` +a_undefined: @ undefined mapping, immediately calls `fail` @ message = (ok, fail, parameter) ldr ip, [fp, #0x08] @ ip = fail customer bx ip @ dispatch to fail @@ -246,6 +246,20 @@ b_arrow: @ explicit mapping (chain of "name/value" pairs) bl enqueue @ add event to queue b complete @ return to dispatch loop + .text + .align 5 @ align to cache-line + .global a_undefined +a_end: @ end of stream, immediately calls `fail` + @ message = (ok, fail, parameter) + ldr ip, [fp, #0x08] @ ip = fail customer + bx ip @ dispatch to fail + .int 0 @ 0x08: -- + .int 0 @ 0x0c: -- + .int 0 @ 0x10: -- + .int 0 @ 0x14: -- + .int 0 @ 0x18: -- + .int 0 @ 0x1c: -- + @ @ unit test actors and behaviors @