Phase C: distributed messaging capsule + idle-loop pump
Extract the messaging vocabulary (arenas, MSG-*/CH-*/MBR-* words) out of capsules/hermes/init.4th into a new shared capsules/common/messaging.4th that Hermes and Artemis each load at birth, giving every VM its own private MSG-ARENA/CH-ARENA instead of only Hermes having one. Hermes stays the owner of the one real, canonical COMMON-CH; Artemis subscribes into it via VM-EXEC at her own birth, and Hermes proactively subscribes Hera (idx 0) since Hera always exists first. Hera does NOT get her own copy: register_child_vm_words()'s own doc comment explains why the STADIUM-* primitives common:messaging.4th depends on are deliberately never registered in her dictionary (keeps her dict_hash off item 4.1's baseline). Confirmed live by loading it into her dictionary anyway first -- every colon-definition referencing an unregistered Stadium primitive was silently dropped (MSG-HEAT@/!, CH-HEAT@/!, MSG-COOL-ALL, MSG-TICK all missing after boot). Reverted that path; she orchestrates via BIRTH/VM-EXEC/VM-CALL instead. Added capsule_vm_registry_get_by_index() (capsule_birth.c/.h) for registry enumeration by birth-order position, and a pump in repl.c's existing idle hook that walks every live VM once per idle beat and VM-EXECs MSG-TICK into each one except Hera's own entry. Verified clean (no UNKNOWN WORD / VM-EXEC errors after birth) on all three architectures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019ZGkimpfyh63EZyRkNbkPD
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0ec91b517a
commit
21bca315ff
+92
-91
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-08-28T13:36:29Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-08-28T17:01:08Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
@@ -9,13 +9,14 @@
|
||||
| Capsule | Blocks claimed | xxHash64 | Signed |
|
||||
|---------|----------------|----------|--------|
|
||||
| `ACL.4th` | 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4015 | `0xd781d22148ff171d` | yes |
|
||||
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853 | `0x8ecaf0453f02df27` | yes |
|
||||
| `artemis:init.4th` | 4110, 4111, 4112, 4113, 4122, 4123, 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, 4133, 4134, 4135, 4136, 4137, 4138, 4139, 4140, 4141, 4160, 4161, 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4177, 4178, 4179, 4180, 4181, 4182, 4851, 4852, 4853, 4854 | `0xfe6e570467368153` | yes |
|
||||
| `common:messaging.4th` | 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019, 5020, 5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033, 5034, 5035, 5036, 5037 | `0x3eb5408bc357d1de` | yes |
|
||||
| `common:msg.4th` | 4055 | `0x850a0382344ea6c4` | yes |
|
||||
| `doe-campaign.4th` | 4060, 4061, 4062, 4063, 4064, 4065 | `0x3d4549142d91ec20` | yes |
|
||||
| `doe.4th` | 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107 | `0xf154616d248e861f` | yes |
|
||||
| `fabric.4th` | 4900, 4901, 4902, 4903, 4904, 4905, 4906, 4907, 4908, 4909, 4910, 4911, 4912, 4913, 4914, 4915, 4916, 4917, 4918, 4919, 4920, 4921, 4922, 4923, 4924, 5000, 5001, 5002 | `0x9b1d061339cea98d` | yes |
|
||||
| `font.4th` | 4925, 4926, 4927, 4928, 4929, 4930, 4931, 4932, 4933, 4934, 4935, 4936, 4937, 4938, 4939, 4940, 4941, 4942, 4943, 4944, 4945, 4946, 4947, 4948, 4949, 4950, 4951, 4952, 4953, 4954, 4955, 4956, 4957, 4958, 4959, 4960, 4961, 4962, 4963, 4964, 4965, 4966, 4967, 4968, 4969, 4970, 4971, 4972, 4973, 4974, 4975, 4976, 4977, 4978, 4979, 4980, 4981, 4982, 4983, 4984, 4985 | `0x720792b4fc758156` | yes |
|
||||
| `hermes:init.4th` | 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4114, 4115, 4116, 4117, 4118, 4119, 4120, 4121, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4155, 4156, 4157, 4158, 4159, 4175, 4176, 5116 | `0xc4f09ac30715b659` | yes |
|
||||
| `hermes:init.4th` | 4153, 4855, 5116 | `0x9d6119b69d4113af` | yes |
|
||||
| `init-0.4th` | 2200, 2201 | `0xd0a9550baf786bb3` | yes |
|
||||
| `init-1.4th` | 4406, 4415, 4425, 4435 | `0x63e251adb0a03613` | yes |
|
||||
| `init-2.4th` | 4506, 4515, 4525, 4535, 4545 | `0xf113b3d0bcccae47` | yes |
|
||||
@@ -114,89 +115,52 @@
|
||||
| 4063 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4064 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4065 | `doe-campaign.4th` | `0x3d4549142d91ec20` | ok |
|
||||
| 4100 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4101 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4102 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4103 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4104 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4105 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4106 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4107 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4108 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4109 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4110 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4111 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4112 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4113 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4114 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4115 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4116 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4117 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4118 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4119 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4120 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4121 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4122 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4123 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4124 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4125 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4126 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4127 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4128 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4129 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4130 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4131 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4132 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4133 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4134 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4135 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4136 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4137 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4138 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4139 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4140 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4141 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4142 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4143 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4144 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4145 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4146 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4147 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4148 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4149 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4150 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4151 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4152 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4153 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4154 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4155 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4156 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4157 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4158 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4159 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4160 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4161 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4162 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4163 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4164 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4165 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4166 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4167 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4168 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4169 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4170 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4171 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4172 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4173 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4174 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4175 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4176 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 4177 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4178 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4179 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4180 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4181 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4182 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4110 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4111 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4112 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4113 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4122 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4123 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4124 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4125 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4126 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4127 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4128 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4129 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4130 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4131 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4132 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4133 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4134 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4135 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4136 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4137 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4138 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4139 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4140 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4141 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4153 | `hermes:init.4th` | `0x9d6119b69d4113af` | ok |
|
||||
| 4160 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4161 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4162 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4163 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4164 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4165 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4166 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4167 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4168 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4169 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4170 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4171 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4172 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4173 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4174 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4177 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4178 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4179 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4180 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4181 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4182 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4200 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
| 4201 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
| 4202 | `user-font-demo.4th` | `0xce1fd7d1b581a56d` | ok |
|
||||
@@ -236,9 +200,11 @@
|
||||
| 4840 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4841 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4842 | `init-l8-transition.4th` | `0xbcc1a81976f0a4c9` | ok |
|
||||
| 4851 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4852 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4853 | `artemis:init.4th` | `0x8ecaf0453f02df27` | ok |
|
||||
| 4851 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4852 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4853 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4854 | `artemis:init.4th` | `0xfe6e570467368153` | ok |
|
||||
| 4855 | `hermes:init.4th` | `0x9d6119b69d4113af` | ok |
|
||||
| 4900 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
| 4901 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
| 4902 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
@@ -328,6 +294,41 @@
|
||||
| 5000 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
| 5001 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
| 5002 | `fabric.4th` | `0x9b1d061339cea98d` | ok |
|
||||
| 5003 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5004 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5005 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5006 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5007 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5008 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5009 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5010 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5011 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5012 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5013 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5014 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5015 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5016 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5017 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5018 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5019 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5020 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5021 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5022 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5023 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5024 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5025 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5026 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5027 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5028 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5029 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5030 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5031 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5032 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5033 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5034 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5035 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5036 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5037 | `common:messaging.4th` | `0x3eb5408bc357d1de` | ok |
|
||||
| 5100 | `turtle.4th` | `0x4d470418ca543365` | ok |
|
||||
| 5101 | `turtle.4th` | `0x4d470418ca543365` | ok |
|
||||
| 5102 | `turtle.4th` | `0x4d470418ca543365` | ok |
|
||||
@@ -344,11 +345,11 @@
|
||||
| 5113 | `sdk.4th` | `0x008fdbbb62c94a3a` | ok |
|
||||
| 5114 | `sdk.4th` | `0x008fdbbb62c94a3a` | ok |
|
||||
| 5115 | `sdk.4th` | `0x008fdbbb62c94a3a` | ok |
|
||||
| 5116 | `hermes:init.4th` | `0xc4f09ac30715b659` | ok |
|
||||
| 5116 | `hermes:init.4th` | `0x9d6119b69d4113af` | ok |
|
||||
|
||||
## Conflicts
|
||||
|
||||
None.
|
||||
|
||||
---
|
||||
*31 capsule(s) scanned. Re-run `mkcapsule --manifest <dir>` to refresh.*
|
||||
*32 capsule(s) scanned. Re-run `mkcapsule --manifest <dir>` to refresh.*
|
||||
|
||||
@@ -491,4 +491,11 @@ Block 4853
|
||||
( D.7: CD-INIT ran only via the old self-test; birth needs it. )
|
||||
CD-INIT
|
||||
S" lib.4th" EXEC
|
||||
Block 4854
|
||||
( Phase C 2026-08-28: own messaging vocab + subscribe into )
|
||||
( Hermes's canonical COMMON-CH (idx 2 = Artemis, VM-NAMES- )
|
||||
( INIT). Hermes always exists by Artemis's birth. )
|
||||
S" common:messaging.4th" EXEC
|
||||
MSG-CD-INIT
|
||||
S" 2 COMMON-CH @ CH-ADD-MBR" S" Hermes" VM-EXEC
|
||||
STARTUP-BANNER
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
Block 5003
|
||||
( common:messaging.4th -- generic per-VM messaging vocab. )
|
||||
1 CONSTANT SPAWN-EVENT
|
||||
2 CONSTANT PAUSE-EVENT
|
||||
3 CONSTANT RESUME-EVENT
|
||||
4 CONSTANT KILL-EVENT
|
||||
0 CONSTANT CH-NEGOTIATING
|
||||
1 CONSTANT CH-OPEN
|
||||
2 CONSTANT CH-CLOSING
|
||||
9 CONSTANT MSG-CELLS
|
||||
6 CONSTANT CH-CELLS
|
||||
2 CONSTANT MBR-CELLS
|
||||
32 CONSTANT MSG-MAX
|
||||
16 CONSTANT CH-MAX
|
||||
64 CONSTANT MBR-MAX
|
||||
65208 CONSTANT Q-DECAY
|
||||
255 CONSTANT MSG-DELIVERED
|
||||
Block 5004
|
||||
( StadiumBehaviour tags, match stadium.h's enum )
|
||||
0 CONSTANT SB-MIGRATE
|
||||
1 CONSTANT SB-DELIVER
|
||||
2 CONSTANT SB-EXPIRE
|
||||
3 CONSTANT SB-COOL
|
||||
-1 CONSTANT STADIUM-NONE
|
||||
( per-item admission heat for MSG-SEND/CH-ACCEPT. )
|
||||
( Remaining reservoir after COMMON-CH's Q.1/3 floor, split )
|
||||
( evenly across MSG-MAX messages + non-COMMON CH-MAX-1 slots. )
|
||||
Q.1 Q.1 3 / - MSG-MAX CH-MAX 1- + / CONSTANT Q.SLOT
|
||||
Block 5005
|
||||
( arenas. heat/capacity via Stadium; MBR keeps its own )
|
||||
( free list (not part of heat economy). )
|
||||
CREATE MSG-ARENA MSG-MAX MSG-CELLS * CELLS ALLOT
|
||||
CREATE CH-ARENA CH-MAX CH-CELLS * CELLS ALLOT
|
||||
CREATE MBR-ARENA MBR-MAX MBR-CELLS * CELLS ALLOT
|
||||
VARIABLE MSG-ALLOC-SLOT
|
||||
VARIABLE CH-ALLOC-SLOT
|
||||
VARIABLE MBR-FREE-HEAD
|
||||
VARIABLE MSG-SEQ
|
||||
VARIABLE CH-ACTIVE
|
||||
VARIABLE COMMON-CH
|
||||
Block 5006
|
||||
( VM name routing table -- same fixed table every VM loads, )
|
||||
( so IDX>NAME resolves identically everywhere. )
|
||||
8 CONSTANT VM-MAX
|
||||
CREATE VM-NAME-ADDRS VM-MAX CELLS ALLOT
|
||||
CREATE VM-NAME-LENS VM-MAX CELLS ALLOT
|
||||
: VM-NAME-REG ( addr u idx -- )
|
||||
DUP VM-MAX >= IF DROP 2DROP EXIT THEN
|
||||
>R R@ CELLS VM-NAME-LENS + !
|
||||
R> CELLS VM-NAME-ADDRS + ! ;
|
||||
: VM-NAMES-INIT ( -- )
|
||||
S" Hera" 0 VM-NAME-REG
|
||||
S" Hermes" 1 VM-NAME-REG
|
||||
S" Artemis" 2 VM-NAME-REG ;
|
||||
Block 5007
|
||||
( INIT-FREE. stamps STADIUM-NONE into each slot's stadium- )
|
||||
( cell field (msg off 5, ch off 3). Raw offsets: accessors )
|
||||
( aren't defined yet in file order. )
|
||||
: MSG-INIT-FREE ( -- )
|
||||
MSG-MAX 0 DO
|
||||
STADIUM-NONE I MSG-CELLS * CELLS MSG-ARENA + 5 CELLS + !
|
||||
LOOP ;
|
||||
: CH-INIT-FREE ( -- )
|
||||
CH-MAX 0 DO
|
||||
STADIUM-NONE I CH-CELLS * CELLS CH-ARENA + 3 CELLS + !
|
||||
LOOP ;
|
||||
Block 5008
|
||||
( MBR-INIT-FREE (member free list, untouched) )
|
||||
: MBR-INIT-FREE ( -- )
|
||||
MBR-MAX 1- 0 DO
|
||||
I MBR-CELLS * CELLS MBR-ARENA +
|
||||
I 1+ MBR-CELLS * CELLS MBR-ARENA + SWAP !
|
||||
LOOP
|
||||
0 MBR-MAX 1- MBR-CELLS * CELLS MBR-ARENA + !
|
||||
MBR-ARENA MBR-FREE-HEAD ! ;
|
||||
Block 5009
|
||||
( MSG-ALLOC: finds a free slot (TYPE=0) first, admits into )
|
||||
( Stadium only once confirmed free (no leak). )
|
||||
: MSG-FIND-FREE-SLOT ( -- addr|0 )
|
||||
MSG-ARENA MSG-MAX 0 DO
|
||||
DUP @ 0= IF UNLOOP EXIT THEN
|
||||
MSG-CELLS CELLS +
|
||||
LOOP DROP 0 ;
|
||||
Block 5010
|
||||
( MSG-ALLOC: pulls heat from reservoir first, admits )
|
||||
( (identity=idx, heat=pulled), rolls back on refusal. )
|
||||
: MSG-ALLOC ( heat -- addr|0 )
|
||||
MSG-FIND-FREE-SLOT DUP 0= IF SWAP DROP EXIT THEN
|
||||
MSG-ALLOC-SLOT !
|
||||
STADIUM-RES-PULL
|
||||
MSG-ALLOC-SLOT @ MSG-ARENA - MSG-CELLS CELLS /
|
||||
SWAP DUP >R
|
||||
SB-DELIVER STADIUM-ADMIT
|
||||
DUP STADIUM-NONE = IF
|
||||
DROP R> STADIUM-RES-PUSH 0 EXIT
|
||||
THEN
|
||||
R> DROP
|
||||
MSG-ALLOC-SLOT @ MSG-CELLS CELLS 0 FILL
|
||||
MSG-ALLOC-SLOT @ 5 CELLS + !
|
||||
MSG-ALLOC-SLOT @ ;
|
||||
Block 5011
|
||||
( MSG-FREE-NODE: evict from Stadium, clear field )
|
||||
: MSG-FREE-NODE ( addr -- )
|
||||
DUP 5 CELLS + @ STADIUM-EVICT DROP
|
||||
DUP 5 CELLS + STADIUM-NONE SWAP !
|
||||
DROP ;
|
||||
Block 5012
|
||||
( MBR alloc/free (unchanged; not heat economy) )
|
||||
: MBR-ALLOC ( -- addr|0 )
|
||||
MBR-FREE-HEAD @ DUP 0= IF EXIT THEN
|
||||
DUP @ MBR-FREE-HEAD !
|
||||
DUP MBR-CELLS CELLS 0 FILL ;
|
||||
: MBR-FREE-NODE ( addr -- )
|
||||
MBR-FREE-HEAD @ OVER ! MBR-FREE-HEAD ! ;
|
||||
Block 5013
|
||||
( CH-FIND-FREE-SLOT. No TYPE field, so freeness is )
|
||||
( stadium-cell = STADIUM-NONE. CH-ALLOC -> block 4176. )
|
||||
: CH-FIND-FREE-SLOT ( -- addr|0 )
|
||||
CH-ARENA CH-MAX 0 DO
|
||||
DUP 3 CELLS + @ STADIUM-NONE = IF UNLOOP EXIT THEN
|
||||
CH-CELLS CELLS +
|
||||
LOOP DROP 0 ;
|
||||
Block 5014
|
||||
( CH-ALLOC: pulls heat from reservoir first, admits )
|
||||
( (identity=idx, heat=pulled), rolls back on refusal. )
|
||||
: CH-ALLOC ( heat -- addr|0 )
|
||||
CH-FIND-FREE-SLOT DUP 0= IF SWAP DROP EXIT THEN
|
||||
CH-ALLOC-SLOT !
|
||||
STADIUM-RES-PULL
|
||||
CH-ALLOC-SLOT @ CH-ARENA - CH-CELLS CELLS /
|
||||
SWAP DUP >R
|
||||
SB-COOL STADIUM-ADMIT
|
||||
DUP STADIUM-NONE = IF
|
||||
DROP R> STADIUM-RES-PUSH 0 EXIT
|
||||
THEN
|
||||
R> DROP
|
||||
CH-ALLOC-SLOT @ CH-CELLS CELLS 0 FILL
|
||||
CH-ALLOC-SLOT @ 3 CELLS + !
|
||||
CH-ALLOC-SLOT @ ;
|
||||
Block 5015
|
||||
( CH-FREE-NODE: evict from Stadium, clear field )
|
||||
: CH-FREE-NODE ( addr -- )
|
||||
DUP 3 CELLS + @ STADIUM-EVICT DROP
|
||||
DUP 3 CELLS + STADIUM-NONE SWAP !
|
||||
DROP ;
|
||||
Block 5016
|
||||
( message field accessors )
|
||||
: MSG-TYPE@ ( m -- n ) @ ;
|
||||
: MSG-TYPE! ( n m -- ) ! ;
|
||||
: MSG-FROM@ ( m -- n ) 1 CELLS + @ ;
|
||||
: MSG-FROM! ( n m -- ) 1 CELLS + ! ;
|
||||
: MSG-TO@ ( m -- n ) 2 CELLS + @ ;
|
||||
: MSG-TO! ( n m -- ) 2 CELLS + ! ;
|
||||
: MSG-PADDR@ ( m -- a ) 3 CELLS + @ ;
|
||||
: MSG-PADDR! ( a m -- ) 3 CELLS + ! ;
|
||||
: MSG-PLEN@ ( m -- u ) 4 CELLS + @ ;
|
||||
: MSG-PLEN! ( u m -- ) 4 CELLS + ! ;
|
||||
( offset 5 = Stadium cell idx. MSG-HEAT@/! -> 4154. )
|
||||
: MSG-STADIUM-CELL@ ( m -- cell ) 5 CELLS + @ ;
|
||||
: MSG-STADIUM-CELL! ( cell m -- ) 5 CELLS + ! ;
|
||||
: MSG-SEQ@ ( m -- n ) 6 CELLS + @ ;
|
||||
: MSG-SEQ! ( n m -- ) 6 CELLS + ! ;
|
||||
Block 5017
|
||||
( message accessors: CH@/CH! )
|
||||
: MSG-CH@ ( m -- c ) 7 CELLS + @ ;
|
||||
: MSG-CH! ( c m -- ) 7 CELLS + ! ;
|
||||
: MSG-ORIG-TYPE@ ( m -- n ) 8 CELLS + @ ;
|
||||
: MSG-ORIG-TYPE! ( n m -- ) 8 CELLS + ! ;
|
||||
253 CONSTANT MSG-NACKED
|
||||
Block 5018
|
||||
( channel + member accessors )
|
||||
: CH-ID@ ( c -- n ) @ ;
|
||||
: CH-ID! ( n c -- ) ! ;
|
||||
: CH-OWNER@ ( c -- n ) 1 CELLS + @ ;
|
||||
: CH-OWNER! ( n c -- ) 1 CELLS + ! ;
|
||||
: CH-STATE@ ( c -- n ) 2 CELLS + @ ;
|
||||
: CH-STATE! ( n c -- ) 2 CELLS + ! ;
|
||||
( offset 3 = Stadium cell index. CH-HEAT@/! -> 4154. )
|
||||
: CH-STADIUM-CELL@ ( c -- cell ) 3 CELLS + @ ;
|
||||
: CH-STADIUM-CELL! ( cell c -- ) 3 CELLS + ! ;
|
||||
: CH-MBRS@ ( c -- a ) 4 CELLS + @ ;
|
||||
: CH-MBRS! ( a c -- ) 4 CELLS + ! ;
|
||||
: CH-NEXT@ ( c -- a ) 5 CELLS + @ ;
|
||||
: CH-NEXT! ( a c -- ) 5 CELLS + ! ;
|
||||
: MBR-NEXT@ ( m -- a ) @ ;
|
||||
: MBR-VM@ ( m -- n ) 1 CELLS + @ ;
|
||||
Block 5019
|
||||
( composed MSG/CH-HEAT@/!, same names/stacks, bodies )
|
||||
( routed via Stadium. Callers need no changes. )
|
||||
: MSG-HEAT@ ( m -- q ) MSG-STADIUM-CELL@ STADIUM-HEAT@ ;
|
||||
: MSG-HEAT! ( q m -- ) MSG-STADIUM-CELL@ STADIUM-HEAT! ;
|
||||
: CH-HEAT@ ( c -- q ) CH-STADIUM-CELL@ STADIUM-HEAT@ ;
|
||||
: CH-HEAT! ( q c -- ) CH-STADIUM-CELL@ STADIUM-HEAT! ;
|
||||
Block 5020
|
||||
( deliver )
|
||||
VARIABLE MSG-LAST-MSG
|
||||
: IDX>NAME ( idx -- addr u )
|
||||
DUP VM-MAX >= IF DROP 0 0 EXIT THEN
|
||||
DUP CELLS VM-NAME-ADDRS + @
|
||||
SWAP CELLS VM-NAME-LENS + @ ;
|
||||
: MSG-DELIVER ( m -- )
|
||||
DUP MSG-LAST-MSG !
|
||||
DUP MSG-PADDR@ OVER MSG-PLEN@
|
||||
ROT MSG-TO@ IDX>NAME VM-EXEC ;
|
||||
Block 5021
|
||||
( MSG-SEND. heat -> MSG-ALLOC's admission directly )
|
||||
( (zero-heat would lose eviction-fallback density )
|
||||
( comparisons), not set afterward as before. )
|
||||
: MSG-SEND ( type from to paddr plen ch -- )
|
||||
Q.SLOT MSG-ALLOC DUP 0= IF 2DROP 2DROP 2DROP DROP EXIT THEN
|
||||
>R
|
||||
MSG-SEQ @ 1+ DUP MSG-SEQ ! R@ MSG-SEQ!
|
||||
R@ MSG-CH!
|
||||
R@ MSG-PLEN! R@ MSG-PADDR!
|
||||
R@ MSG-TO! R@ MSG-FROM! DUP R@ MSG-TYPE! R@ MSG-ORIG-TYPE!
|
||||
R> DROP ;
|
||||
Block 5022
|
||||
( MSG-COOL-ONE/ALL: linear decay per tick )
|
||||
VARIABLE MSG-SCAN
|
||||
: MSG-COOL-ONE ( m -- )
|
||||
DUP MSG-HEAT@ Q-DECAY Q.* SWAP MSG-HEAT! ;
|
||||
: MSG-COOL-ALL ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-HEAT@ 0 > IF
|
||||
MSG-SCAN @ MSG-COOL-ONE
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 5023
|
||||
( MSG-TOTAL-HEAT )
|
||||
: MSG-TOTAL-HEAT ( -- q48 )
|
||||
0 MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-SCAN @ MSG-HEAT@ +
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
: MSG-REDELIVER-NACKED ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-NACKED = IF
|
||||
MSG-SCAN @ MSG-ORIG-TYPE@ MSG-SCAN @ MSG-TYPE! THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 5024
|
||||
( MSG-DELIVER-ALL )
|
||||
: MSG-DELIVER-ALL ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <>
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-DELIVERED <> AND
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-NACKED <> AND IF
|
||||
MSG-SCAN @ MSG-DELIVER
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-DELIVERED MSG-SCAN @ MSG-TYPE!
|
||||
THEN
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 5025
|
||||
( message reaping )
|
||||
( K reap only fires at heat=0: freed K contribution is 0. )
|
||||
( Force-reap not yet implemented. If added: explicit )
|
||||
( K redistribution will be required here. )
|
||||
: MSG-REAP ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-HEAT@ 0 = IF
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
0 MSG-SCAN @ MSG-TYPE!
|
||||
MSG-SCAN @ MSG-FREE-NODE
|
||||
THEN
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 5026
|
||||
( channel cooling + heat aggregate )
|
||||
VARIABLE CH-SCAN
|
||||
: CH-COOL-ALL ( -- )
|
||||
CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-HEAT@ Q-DECAY Q.* CH-SCAN @ CH-HEAT!
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
: CH-TOTAL-HEAT ( -- q48 )
|
||||
0 CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-HEAT@ +
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
Block 5027
|
||||
( channel reaping )
|
||||
: CH-REAP-SAFE ( -- )
|
||||
CH-ACTIVE @ CH-SCAN !
|
||||
0 CH-ACTIVE !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-NEXT@
|
||||
CH-SCAN @ CH-HEAT@ 0 =
|
||||
CH-SCAN @ COMMON-CH @ <> AND IF
|
||||
CH-SCAN @ CH-FREE-NODE
|
||||
ELSE
|
||||
CH-ACTIVE @ CH-SCAN @ CH-NEXT!
|
||||
CH-SCAN @ CH-ACTIVE !
|
||||
THEN
|
||||
CH-SCAN !
|
||||
REPEAT ;
|
||||
Block 5028
|
||||
( COMMON + MSG-TICK (was HERMES-TICK -- generic now). )
|
||||
( floor=Q.1/3. COMMON-CH VARIABLE is in block 4101. )
|
||||
: COMMON-INIT ( -- )
|
||||
Q.1 3 / CH-ALLOC DUP COMMON-CH !
|
||||
0 OVER CH-ID! 0 OVER CH-OWNER!
|
||||
CH-OPEN OVER CH-STATE!
|
||||
0 OVER CH-MBRS!
|
||||
CH-ACTIVE @ OVER CH-NEXT!
|
||||
CH-ACTIVE ! ;
|
||||
( floor-refresh is reservoir-constrained, may no-op under )
|
||||
( pressure. )
|
||||
: MSG-TICK ( -- )
|
||||
MSG-DELIVER-ALL MSG-REDELIVER-NACKED
|
||||
MSG-COOL-ALL MSG-REAP
|
||||
CH-COOL-ALL CH-REAP-SAFE
|
||||
Q.1 3 / COMMON-CH @ CH-HEAT! ;
|
||||
Block 5029
|
||||
( MSG-K (was HERMES-K -- generic now). WELCOME stays )
|
||||
( behind in each VM's own init.4th. )
|
||||
: MSG-K ( -- q48 )
|
||||
MSG-TOTAL-HEAT CH-TOTAL-HEAT + STADIUM-RES@ +
|
||||
STADIUM-WORD-HEAT + ;
|
||||
Block 5030
|
||||
( event compat interface. SPAWN/KILL notify-Hera is )
|
||||
( automatic: see vm_physics_init/retire in mama_word_birth. )
|
||||
: EVENT-EMIT ( type -- ) DROP ;
|
||||
: EVENT-WAIT ( -- type )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-SCAN @ MSG-TYPE@ UNLOOP EXIT THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP 0 ;
|
||||
: EVENT-DRAIN ( -- )
|
||||
( no-op: MSG-REAP owns cleanup; drain breaks async ) ;
|
||||
Block 5031
|
||||
( channel negotiation: mint/request )
|
||||
: CH-MINT-ID ( owner -- id )
|
||||
MSG-SEQ @ 1+ DUP MSG-SEQ !
|
||||
SWAP 32 LSHIFT OR ;
|
||||
: CH-REQUEST ( type from to paddr plen -- )
|
||||
COMMON-CH @ CH-STATE@ CH-OPEN = IF
|
||||
COMMON-CH @ MSG-SEND
|
||||
ELSE 2DROP 2DROP DROP THEN ;
|
||||
Block 5032
|
||||
( channel ops: accept confirm close )
|
||||
: CH-ACCEPT ( -- ch|0 )
|
||||
Q.SLOT CH-ALLOC DUP 0= IF EXIT THEN
|
||||
1 CH-MINT-ID OVER CH-ID!
|
||||
1 OVER CH-OWNER!
|
||||
CH-NEGOTIATING OVER CH-STATE!
|
||||
0 OVER CH-MBRS!
|
||||
CH-ACTIVE @ OVER CH-NEXT!
|
||||
DUP CH-ACTIVE ! ;
|
||||
: CH-CONFIRM ( ch -- )
|
||||
DUP CH-STATE@ CH-NEGOTIATING = IF CH-OPEN SWAP CH-STATE!
|
||||
ELSE DROP THEN ;
|
||||
: CH-CLOSE ( ch -- )
|
||||
DUP COMMON-CH @ = IF DROP EXIT THEN
|
||||
CH-CLOSING SWAP CH-STATE! ;
|
||||
Block 5033
|
||||
( MSG-CD-INIT (was CD-INIT -- renamed to avoid colliding )
|
||||
( with Artemis's own unrelated block-subsystem CD-INIT). )
|
||||
( common:msg.4th's HERMES-ACK/NACK indirection is retired: )
|
||||
( every VM now has its own local MSG-ACK-LAST/NACK-LAST. )
|
||||
: MSG-CD-INIT ( -- )
|
||||
MSG-ARENA MSG-MAX MSG-CELLS * CELLS 0 FILL
|
||||
CH-ARENA CH-MAX CH-CELLS * CELLS 0 FILL
|
||||
MBR-ARENA MBR-MAX MBR-CELLS * CELLS 0 FILL
|
||||
MSG-INIT-FREE
|
||||
CH-INIT-FREE
|
||||
MBR-INIT-FREE
|
||||
0 MSG-SEQ !
|
||||
0 MSG-LAST-MSG !
|
||||
0 CH-ACTIVE !
|
||||
COMMON-INIT
|
||||
VM-NAMES-INIT ;
|
||||
Block 5034
|
||||
( ACK/NACK -- now purely local, no VM-EXEC indirection. )
|
||||
: MSG-ACK-LAST ( -- )
|
||||
MSG-LAST-MSG @ DUP 0= IF DROP EXIT THEN
|
||||
0 OVER MSG-TYPE! MSG-FREE-NODE ;
|
||||
: MSG-NACK-LAST ( -- )
|
||||
MSG-LAST-MSG @ DUP 0= IF DROP EXIT THEN
|
||||
DUP MSG-HEAT@ 2 / OVER MSG-HEAT!
|
||||
MSG-NACKED SWAP MSG-TYPE! ;
|
||||
Block 5035
|
||||
( MSG-STATUS (was HERMES-STATUS -- generic now) )
|
||||
: MSG-USED ( -- n )
|
||||
0 MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF 1+ THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
: CH-USED ( -- n )
|
||||
0 CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
1+
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
: MSG-STATUS ( -- )
|
||||
MSG-USED . ." msgs " CH-USED . ." channels" CR ;
|
||||
Block 5036
|
||||
( member management )
|
||||
: MBR-NEXT! ( a m -- ) ! ;
|
||||
: MBR-VM! ( n m -- ) 1 CELLS + ! ;
|
||||
: CH-ADD-MBR ( vm ch -- )
|
||||
MBR-ALLOC DUP 0= IF DROP 2DROP EXIT THEN
|
||||
ROT OVER MBR-VM!
|
||||
OVER CH-MBRS@ OVER MBR-NEXT!
|
||||
SWAP CH-MBRS! ;
|
||||
Block 5037
|
||||
( Phase 2: real multi-member broadcast )
|
||||
VARIABLE BC-TYPE VARIABLE BC-FROM
|
||||
VARIABLE BC-PADDR VARIABLE BC-PLEN
|
||||
VARIABLE BC-CH VARIABLE BC-SCAN
|
||||
: MSG-BROADCAST ( type from paddr plen ch -- )
|
||||
BC-CH ! BC-PLEN ! BC-PADDR ! BC-FROM ! BC-TYPE !
|
||||
BC-CH @ CH-MBRS@ BC-SCAN !
|
||||
BEGIN BC-SCAN @ 0<> WHILE
|
||||
BC-TYPE @ BC-FROM @ BC-SCAN @ MBR-VM@
|
||||
BC-PADDR @ BC-PLEN @ BC-CH @ MSG-SEND
|
||||
BC-SCAN @ MBR-NEXT@ BC-SCAN !
|
||||
REPEAT ;
|
||||
+14
-459
@@ -1,467 +1,22 @@
|
||||
Block 4100
|
||||
( Hermes v1 — constants )
|
||||
1 CONSTANT SPAWN-EVENT
|
||||
2 CONSTANT PAUSE-EVENT
|
||||
3 CONSTANT RESUME-EVENT
|
||||
4 CONSTANT KILL-EVENT
|
||||
0 CONSTANT CH-NEGOTIATING
|
||||
1 CONSTANT CH-OPEN
|
||||
2 CONSTANT CH-CLOSING
|
||||
9 CONSTANT MSG-CELLS
|
||||
6 CONSTANT CH-CELLS
|
||||
2 CONSTANT MBR-CELLS
|
||||
32 CONSTANT MSG-MAX
|
||||
16 CONSTANT CH-MAX
|
||||
64 CONSTANT MBR-MAX
|
||||
65208 CONSTANT Q-DECAY
|
||||
255 CONSTANT MSG-DELIVERED
|
||||
Block 4155
|
||||
( item 4.2 -- StadiumBehaviour tags, match stadium.h's enum )
|
||||
0 CONSTANT SB-MIGRATE
|
||||
1 CONSTANT SB-DELIVER
|
||||
2 CONSTANT SB-EXPIRE
|
||||
3 CONSTANT SB-COOL
|
||||
-1 CONSTANT STADIUM-NONE
|
||||
( item 4.2 -- per-item admission heat for MSG-SEND/CH-ACCEPT. )
|
||||
( Remaining reservoir after COMMON-CH's Q.1/3 floor, split )
|
||||
( evenly across MSG-MAX messages + non-COMMON CH-MAX-1 slots. )
|
||||
Q.1 Q.1 3 / - MSG-MAX CH-MAX 1- + / CONSTANT Q.SLOT
|
||||
Block 4101
|
||||
( Hermes v1 -- arenas. item 4.2: heat/capacity via Stadium; )
|
||||
( MBR keeps its own free list (not part of heat economy). )
|
||||
CREATE MSG-ARENA MSG-MAX MSG-CELLS * CELLS ALLOT
|
||||
CREATE CH-ARENA CH-MAX CH-CELLS * CELLS ALLOT
|
||||
CREATE MBR-ARENA MBR-MAX MBR-CELLS * CELLS ALLOT
|
||||
VARIABLE MSG-ALLOC-SLOT
|
||||
VARIABLE CH-ALLOC-SLOT
|
||||
VARIABLE MBR-FREE-HEAD
|
||||
VARIABLE MSG-SEQ
|
||||
VARIABLE CH-ACTIVE
|
||||
VARIABLE COMMON-CH
|
||||
Block 4142
|
||||
( Hermes v1 — VM name routing table )
|
||||
8 CONSTANT VM-MAX
|
||||
CREATE VM-NAME-ADDRS VM-MAX CELLS ALLOT
|
||||
CREATE VM-NAME-LENS VM-MAX CELLS ALLOT
|
||||
: VM-NAME-REG ( addr u idx -- )
|
||||
DUP VM-MAX >= IF DROP 2DROP EXIT THEN
|
||||
>R R@ CELLS VM-NAME-LENS + !
|
||||
R> CELLS VM-NAME-ADDRS + ! ;
|
||||
: VM-NAMES-INIT ( -- )
|
||||
S" Hera" 0 VM-NAME-REG
|
||||
S" Hermes" 1 VM-NAME-REG
|
||||
S" Artemis" 2 VM-NAME-REG ;
|
||||
Block 4102
|
||||
( Hermes v1 -- INIT-FREE. item 4.2: stamps STADIUM-NONE into )
|
||||
( each slot's stadium-cell field (msg off 5, ch off 3). )
|
||||
( Raw offsets: accessors aren't defined yet in file order. )
|
||||
: MSG-INIT-FREE ( -- )
|
||||
MSG-MAX 0 DO
|
||||
STADIUM-NONE I MSG-CELLS * CELLS MSG-ARENA + 5 CELLS + !
|
||||
LOOP ;
|
||||
: CH-INIT-FREE ( -- )
|
||||
CH-MAX 0 DO
|
||||
STADIUM-NONE I CH-CELLS * CELLS CH-ARENA + 3 CELLS + !
|
||||
LOOP ;
|
||||
Block 4103
|
||||
( Hermes v1 -- MBR-INIT-FREE (member free list, untouched) )
|
||||
: MBR-INIT-FREE ( -- )
|
||||
MBR-MAX 1- 0 DO
|
||||
I MBR-CELLS * CELLS MBR-ARENA +
|
||||
I 1+ MBR-CELLS * CELLS MBR-ARENA + SWAP !
|
||||
LOOP
|
||||
0 MBR-MAX 1- MBR-CELLS * CELLS MBR-ARENA + !
|
||||
MBR-ARENA MBR-FREE-HEAD ! ;
|
||||
Block 4156
|
||||
( item 4.2 -- MSG-ALLOC: finds a free slot (TYPE=0) first, )
|
||||
( admits into Stadium only once confirmed free (no leak). )
|
||||
: MSG-FIND-FREE-SLOT ( -- addr|0 )
|
||||
MSG-ARENA MSG-MAX 0 DO
|
||||
DUP @ 0= IF UNLOOP EXIT THEN
|
||||
MSG-CELLS CELLS +
|
||||
LOOP DROP 0 ;
|
||||
Block 4175
|
||||
( item 4.2 -- MSG-ALLOC: pulls heat from reservoir first, )
|
||||
( admits (identity=idx, heat=pulled), rolls back on refusal. )
|
||||
: MSG-ALLOC ( heat -- addr|0 )
|
||||
MSG-FIND-FREE-SLOT DUP 0= IF SWAP DROP EXIT THEN
|
||||
MSG-ALLOC-SLOT !
|
||||
STADIUM-RES-PULL
|
||||
MSG-ALLOC-SLOT @ MSG-ARENA - MSG-CELLS CELLS /
|
||||
SWAP DUP >R
|
||||
SB-DELIVER STADIUM-ADMIT
|
||||
DUP STADIUM-NONE = IF
|
||||
DROP R> STADIUM-RES-PUSH 0 EXIT
|
||||
THEN
|
||||
R> DROP
|
||||
MSG-ALLOC-SLOT @ MSG-CELLS CELLS 0 FILL
|
||||
MSG-ALLOC-SLOT @ 5 CELLS + !
|
||||
MSG-ALLOC-SLOT @ ;
|
||||
Block 4157
|
||||
( item 4.2 -- MSG-FREE-NODE: evict from Stadium, clear field )
|
||||
: MSG-FREE-NODE ( addr -- )
|
||||
DUP 5 CELLS + @ STADIUM-EVICT DROP
|
||||
DUP 5 CELLS + STADIUM-NONE SWAP !
|
||||
DROP ;
|
||||
Block 4104
|
||||
( Hermes v1 -- MBR alloc/free (unchanged; not heat economy) )
|
||||
: MBR-ALLOC ( -- addr|0 )
|
||||
MBR-FREE-HEAD @ DUP 0= IF EXIT THEN
|
||||
DUP @ MBR-FREE-HEAD !
|
||||
DUP MBR-CELLS CELLS 0 FILL ;
|
||||
: MBR-FREE-NODE ( addr -- )
|
||||
MBR-FREE-HEAD @ OVER ! MBR-FREE-HEAD ! ;
|
||||
Block 4158
|
||||
( item 4.2 -- CH-FIND-FREE-SLOT. No TYPE field, so freeness )
|
||||
( is stadium-cell = STADIUM-NONE. CH-ALLOC -> block 4176. )
|
||||
: CH-FIND-FREE-SLOT ( -- addr|0 )
|
||||
CH-ARENA CH-MAX 0 DO
|
||||
DUP 3 CELLS + @ STADIUM-NONE = IF UNLOOP EXIT THEN
|
||||
CH-CELLS CELLS +
|
||||
LOOP DROP 0 ;
|
||||
Block 4176
|
||||
( item 4.2 -- CH-ALLOC: pulls heat from reservoir first, )
|
||||
( admits (identity=idx, heat=pulled), rolls back on refusal. )
|
||||
: CH-ALLOC ( heat -- addr|0 )
|
||||
CH-FIND-FREE-SLOT DUP 0= IF SWAP DROP EXIT THEN
|
||||
CH-ALLOC-SLOT !
|
||||
STADIUM-RES-PULL
|
||||
CH-ALLOC-SLOT @ CH-ARENA - CH-CELLS CELLS /
|
||||
SWAP DUP >R
|
||||
SB-COOL STADIUM-ADMIT
|
||||
DUP STADIUM-NONE = IF
|
||||
DROP R> STADIUM-RES-PUSH 0 EXIT
|
||||
THEN
|
||||
R> DROP
|
||||
CH-ALLOC-SLOT @ CH-CELLS CELLS 0 FILL
|
||||
CH-ALLOC-SLOT @ 3 CELLS + !
|
||||
CH-ALLOC-SLOT @ ;
|
||||
Block 4159
|
||||
( item 4.2 -- CH-FREE-NODE: evict from Stadium, clear field )
|
||||
: CH-FREE-NODE ( addr -- )
|
||||
DUP 3 CELLS + @ STADIUM-EVICT DROP
|
||||
DUP 3 CELLS + STADIUM-NONE SWAP !
|
||||
DROP ;
|
||||
Block 4105
|
||||
( Hermes v1 — message field accessors )
|
||||
: MSG-TYPE@ ( m -- n ) @ ;
|
||||
: MSG-TYPE! ( n m -- ) ! ;
|
||||
: MSG-FROM@ ( m -- n ) 1 CELLS + @ ;
|
||||
: MSG-FROM! ( n m -- ) 1 CELLS + ! ;
|
||||
: MSG-TO@ ( m -- n ) 2 CELLS + @ ;
|
||||
: MSG-TO! ( n m -- ) 2 CELLS + ! ;
|
||||
: MSG-PADDR@ ( m -- a ) 3 CELLS + @ ;
|
||||
: MSG-PADDR! ( a m -- ) 3 CELLS + ! ;
|
||||
: MSG-PLEN@ ( m -- u ) 4 CELLS + @ ;
|
||||
: MSG-PLEN! ( u m -- ) 4 CELLS + ! ;
|
||||
( item 4.2: offset 5 = Stadium cell idx. MSG-HEAT@/! -> 4154. )
|
||||
: MSG-STADIUM-CELL@ ( m -- cell ) 5 CELLS + @ ;
|
||||
: MSG-STADIUM-CELL! ( cell m -- ) 5 CELLS + ! ;
|
||||
: MSG-SEQ@ ( m -- n ) 6 CELLS + @ ;
|
||||
: MSG-SEQ! ( n m -- ) 6 CELLS + ! ;
|
||||
Block 4143
|
||||
( Hermes v1 — message accessors: CH@/CH! )
|
||||
: MSG-CH@ ( m -- c ) 7 CELLS + @ ;
|
||||
: MSG-CH! ( c m -- ) 7 CELLS + ! ;
|
||||
: MSG-ORIG-TYPE@ ( m -- n ) 8 CELLS + @ ;
|
||||
: MSG-ORIG-TYPE! ( n m -- ) 8 CELLS + ! ;
|
||||
253 CONSTANT MSG-NACKED
|
||||
Block 4106
|
||||
( Hermes v1 — channel + member accessors )
|
||||
: CH-ID@ ( c -- n ) @ ;
|
||||
: CH-ID! ( n c -- ) ! ;
|
||||
: CH-OWNER@ ( c -- n ) 1 CELLS + @ ;
|
||||
: CH-OWNER! ( n c -- ) 1 CELLS + ! ;
|
||||
: CH-STATE@ ( c -- n ) 2 CELLS + @ ;
|
||||
: CH-STATE! ( n c -- ) 2 CELLS + ! ;
|
||||
( item 4.2: offset 3 = Stadium cell index. CH-HEAT@/! -> 4154. )
|
||||
: CH-STADIUM-CELL@ ( c -- cell ) 3 CELLS + @ ;
|
||||
: CH-STADIUM-CELL! ( cell c -- ) 3 CELLS + ! ;
|
||||
: CH-MBRS@ ( c -- a ) 4 CELLS + @ ;
|
||||
: CH-MBRS! ( a c -- ) 4 CELLS + ! ;
|
||||
: CH-NEXT@ ( c -- a ) 5 CELLS + @ ;
|
||||
: CH-NEXT! ( a c -- ) 5 CELLS + ! ;
|
||||
: MBR-NEXT@ ( m -- a ) @ ;
|
||||
: MBR-VM@ ( m -- n ) 1 CELLS + @ ;
|
||||
Block 4154
|
||||
( item 4.2 -- composed MSG/CH-HEAT@/!, same names/stacks, )
|
||||
( new bodies routed via Stadium. Callers need no changes. )
|
||||
: MSG-HEAT@ ( m -- q ) MSG-STADIUM-CELL@ STADIUM-HEAT@ ;
|
||||
: MSG-HEAT! ( q m -- ) MSG-STADIUM-CELL@ STADIUM-HEAT! ;
|
||||
: CH-HEAT@ ( c -- q ) CH-STADIUM-CELL@ STADIUM-HEAT@ ;
|
||||
: CH-HEAT! ( q c -- ) CH-STADIUM-CELL@ STADIUM-HEAT! ;
|
||||
Block 4107
|
||||
( Hermes v1 — deliver )
|
||||
VARIABLE MSG-LAST-MSG
|
||||
: IDX>NAME ( idx -- addr u )
|
||||
DUP VM-MAX >= IF DROP 0 0 EXIT THEN
|
||||
DUP CELLS VM-NAME-ADDRS + @
|
||||
SWAP CELLS VM-NAME-LENS + @ ;
|
||||
: MSG-DELIVER ( m -- )
|
||||
DUP MSG-LAST-MSG !
|
||||
DUP MSG-PADDR@ OVER MSG-PLEN@
|
||||
ROT MSG-TO@ IDX>NAME VM-EXEC ;
|
||||
Block 4144
|
||||
( Hermes v1 -- MSG-SEND. item 4.2: heat -> MSG-ALLOC's )
|
||||
( admission directly (zero-heat would lose eviction-fallback )
|
||||
( density comparisons), not set afterward as before. )
|
||||
: MSG-SEND ( type from to paddr plen ch -- )
|
||||
Q.SLOT MSG-ALLOC DUP 0= IF 2DROP 2DROP 2DROP DROP EXIT THEN
|
||||
>R
|
||||
MSG-SEQ @ 1+ DUP MSG-SEQ ! R@ MSG-SEQ!
|
||||
R@ MSG-CH!
|
||||
R@ MSG-PLEN! R@ MSG-PADDR!
|
||||
R@ MSG-TO! R@ MSG-FROM! DUP R@ MSG-TYPE! R@ MSG-ORIG-TYPE!
|
||||
R> DROP ;
|
||||
Block 4108
|
||||
( Hermes v1 — MSG-COOL-ONE/ALL: linear decay per tick )
|
||||
VARIABLE MSG-SCAN
|
||||
: MSG-COOL-ONE ( m -- )
|
||||
DUP MSG-HEAT@ Q-DECAY Q.* SWAP MSG-HEAT! ;
|
||||
: MSG-COOL-ALL ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-HEAT@ 0 > IF
|
||||
MSG-SCAN @ MSG-COOL-ONE
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 4145
|
||||
( Hermes v1 — MSG-TOTAL-HEAT )
|
||||
: MSG-TOTAL-HEAT ( -- q48 )
|
||||
0 MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-SCAN @ MSG-HEAT@ +
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
: MSG-REDELIVER-NACKED ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-NACKED = IF
|
||||
MSG-SCAN @ MSG-ORIG-TYPE@ MSG-SCAN @ MSG-TYPE! THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 4146
|
||||
( Hermes v1 — MSG-DELIVER-ALL )
|
||||
: MSG-DELIVER-ALL ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <>
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-DELIVERED <> AND
|
||||
MSG-SCAN @ MSG-TYPE@ MSG-NACKED <> AND IF
|
||||
MSG-SCAN @ MSG-DELIVER
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-DELIVERED MSG-SCAN @ MSG-TYPE!
|
||||
THEN
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 4109
|
||||
( Hermes v1 — message reaping )
|
||||
( K reap only fires at heat=0: freed K contribution is 0. )
|
||||
( Force-reap not yet implemented. If added: explicit )
|
||||
( K redistribution will be required here. )
|
||||
: MSG-REAP ( -- )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-HEAT@ 0 = IF
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
0 MSG-SCAN @ MSG-TYPE!
|
||||
MSG-SCAN @ MSG-FREE-NODE
|
||||
THEN
|
||||
THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
Block 4114
|
||||
( Hermes v1 — channel cooling + heat aggregate )
|
||||
VARIABLE CH-SCAN
|
||||
: CH-COOL-ALL ( -- )
|
||||
CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-HEAT@ Q-DECAY Q.* CH-SCAN @ CH-HEAT!
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
: CH-TOTAL-HEAT ( -- q48 )
|
||||
0 CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-HEAT@ +
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
Block 4115
|
||||
( Hermes v1 — channel reaping )
|
||||
: CH-REAP-SAFE ( -- )
|
||||
CH-ACTIVE @ CH-SCAN !
|
||||
0 CH-ACTIVE !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
CH-SCAN @ CH-NEXT@
|
||||
CH-SCAN @ CH-HEAT@ 0 =
|
||||
CH-SCAN @ COMMON-CH @ <> AND IF
|
||||
CH-SCAN @ CH-FREE-NODE
|
||||
ELSE
|
||||
CH-ACTIVE @ CH-SCAN @ CH-NEXT!
|
||||
CH-SCAN @ CH-ACTIVE !
|
||||
THEN
|
||||
CH-SCAN !
|
||||
REPEAT ;
|
||||
Block 4116
|
||||
( Hermes v1 -- COMMON + HERMES-TICK. floor=Q.1/3, VM-COUNT=3 )
|
||||
( COMMON-CH VARIABLE now in block 4101; see CH-REAP-SAFE 4115 )
|
||||
: COMMON-INIT ( -- )
|
||||
Q.1 3 / CH-ALLOC DUP COMMON-CH !
|
||||
0 OVER CH-ID! 0 OVER CH-OWNER!
|
||||
CH-OPEN OVER CH-STATE!
|
||||
0 OVER CH-MBRS!
|
||||
CH-ACTIVE @ OVER CH-NEXT!
|
||||
CH-ACTIVE ! ;
|
||||
( item 4.2: floor-refresh now reservoir-constrained, may no-op )
|
||||
( under pressure (was unconstrained write before). Watch log. )
|
||||
: HERMES-TICK ( -- )
|
||||
MSG-DELIVER-ALL MSG-REDELIVER-NACKED
|
||||
MSG-COOL-ALL MSG-REAP
|
||||
CH-COOL-ALL CH-REAP-SAFE
|
||||
Q.1 3 / COMMON-CH @ CH-HEAT! ;
|
||||
Block 4147
|
||||
( Hermes v1 — HERMES-K + WELCOME )
|
||||
( item 4.2: +STADIUM-WORD-HEAT so word patrons count -- 25.7 )
|
||||
: HERMES-K ( -- q48 )
|
||||
MSG-TOTAL-HEAT CH-TOTAL-HEAT + STADIUM-RES@ +
|
||||
STADIUM-WORD-HEAT + ;
|
||||
Block 4855
|
||||
( Hermes v1 -- WELCOME. Generic messaging vocab moved to )
|
||||
( common:messaging.4th, FABRIC-3.md Phase C 2026-08-28. )
|
||||
: WELCOME ( -- ) LOG-INFO" Hermes: loaded" ;
|
||||
WELCOME
|
||||
Block 4117
|
||||
( Hermes v1 — event compat interface )
|
||||
( SPAWN/KILL notify-Hera is now automatic: see )
|
||||
( vm_physics_init/retire in mama_word_birth/kill )
|
||||
: EVENT-EMIT ( type -- ) DROP ;
|
||||
: EVENT-WAIT ( -- type )
|
||||
MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF
|
||||
MSG-SCAN @ MSG-TYPE@ UNLOOP EXIT THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP 0 ;
|
||||
: EVENT-DRAIN ( -- )
|
||||
( no-op: MSG-REAP owns cleanup; drain breaks async ) ;
|
||||
Block 4118
|
||||
( Hermes v1 -- readiness handshake, Phase 1 )
|
||||
5 CONSTANT READY-EVENT
|
||||
VARIABLE READY-COUNT
|
||||
: NOTE-READY ( -- ) 1 READY-COUNT +! ;
|
||||
: READY-ALL? ( -- flag ) READY-COUNT @ 3 >= ;
|
||||
: ENQUEUE-READY ( from-idx -- )
|
||||
READY-EVENT SWAP 1 S" NOTE-READY" COMMON-CH @ MSG-SEND ;
|
||||
: HERMES-ANNOUNCE-READY ( -- ) 1 ENQUEUE-READY ;
|
||||
: READY-ACK ( -- ) LOG-INFO" Hermes: ready-ack" ;
|
||||
Block 4119
|
||||
( Hermes v1 — channel negotiation: mint/request )
|
||||
: CH-MINT-ID ( owner -- id )
|
||||
MSG-SEQ @ 1+ DUP MSG-SEQ !
|
||||
SWAP 32 LSHIFT OR ;
|
||||
: CH-REQUEST ( type from to paddr plen -- )
|
||||
COMMON-CH @ CH-STATE@ CH-OPEN = IF
|
||||
COMMON-CH @ MSG-SEND
|
||||
ELSE 2DROP 2DROP DROP THEN ;
|
||||
Block 4148
|
||||
( Hermes v1 — channel ops: accept confirm close )
|
||||
: CH-ACCEPT ( -- ch|0 )
|
||||
Q.SLOT CH-ALLOC DUP 0= IF EXIT THEN
|
||||
1 CH-MINT-ID OVER CH-ID!
|
||||
1 OVER CH-OWNER!
|
||||
CH-NEGOTIATING OVER CH-STATE!
|
||||
0 OVER CH-MBRS!
|
||||
CH-ACTIVE @ OVER CH-NEXT!
|
||||
DUP CH-ACTIVE ! ;
|
||||
: CH-CONFIRM ( ch -- )
|
||||
DUP CH-STATE@ CH-NEGOTIATING = IF CH-OPEN SWAP CH-STATE!
|
||||
ELSE DROP THEN ;
|
||||
: CH-CLOSE ( ch -- )
|
||||
DUP COMMON-CH @ = IF DROP EXIT THEN
|
||||
CH-CLOSING SWAP CH-STATE! ;
|
||||
Block 4120
|
||||
( Hermes v1 — CD-INIT )
|
||||
: CD-INIT ( -- )
|
||||
MSG-ARENA MSG-MAX MSG-CELLS * CELLS 0 FILL
|
||||
CH-ARENA CH-MAX CH-CELLS * CELLS 0 FILL
|
||||
MBR-ARENA MBR-MAX MBR-CELLS * CELLS 0 FILL
|
||||
MSG-INIT-FREE
|
||||
CH-INIT-FREE
|
||||
MBR-INIT-FREE
|
||||
0 MSG-SEQ !
|
||||
0 MSG-LAST-MSG !
|
||||
0 CH-ACTIVE !
|
||||
COMMON-INIT
|
||||
VM-NAMES-INIT
|
||||
S" lib.4th" EXEC
|
||||
S" common:msg.4th" EXEC
|
||||
LOG-INFO" Hermes: ready" ;
|
||||
Block 4121
|
||||
( Hermes v1 — ACK/NACK server )
|
||||
: MSG-ACK-LAST ( -- )
|
||||
MSG-LAST-MSG @ DUP 0= IF DROP EXIT THEN
|
||||
0 OVER MSG-TYPE! MSG-FREE-NODE ;
|
||||
: MSG-NACK-LAST ( -- )
|
||||
MSG-LAST-MSG @ DUP 0= IF DROP EXIT THEN
|
||||
DUP MSG-HEAT@ 2 / OVER MSG-HEAT!
|
||||
MSG-NACKED SWAP MSG-TYPE! ;
|
||||
Block 4149
|
||||
( Hermes v1 — HERMES-STATUS )
|
||||
: MSG-USED ( -- n )
|
||||
0 MSG-ARENA MSG-SCAN !
|
||||
MSG-MAX 0 DO
|
||||
MSG-SCAN @ MSG-TYPE@ 0 <> IF 1+ THEN
|
||||
MSG-SCAN @ MSG-CELLS CELLS + MSG-SCAN !
|
||||
LOOP ;
|
||||
: CH-USED ( -- n )
|
||||
0 CH-ACTIVE @ CH-SCAN !
|
||||
BEGIN CH-SCAN @ 0 <> WHILE
|
||||
1+
|
||||
CH-SCAN @ CH-NEXT@ CH-SCAN !
|
||||
REPEAT ;
|
||||
: HERMES-STATUS ( -- )
|
||||
MSG-USED . ." msgs " CH-USED . ." channels" CR ;
|
||||
Block 4150
|
||||
( Hermes v1 — member management )
|
||||
: MBR-NEXT! ( a m -- ) ! ;
|
||||
: MBR-VM! ( n m -- ) 1 CELLS + ! ;
|
||||
: CH-ADD-MBR ( vm ch -- )
|
||||
MBR-ALLOC DUP 0= IF DROP 2DROP EXIT THEN
|
||||
ROT OVER MBR-VM!
|
||||
OVER CH-MBRS@ OVER MBR-NEXT!
|
||||
SWAP CH-MBRS! ;
|
||||
: HERMES-MSG-TEST ( -- flag )
|
||||
SPAWN-EVENT 1 0 0 0 COMMON-CH @ MSG-SEND
|
||||
MSG-USED 0 > ;
|
||||
Block 4151
|
||||
( Hermes v1 -- Phase 2: real multi-member broadcast )
|
||||
VARIABLE BC-TYPE VARIABLE BC-FROM
|
||||
VARIABLE BC-PADDR VARIABLE BC-PLEN
|
||||
VARIABLE BC-CH VARIABLE BC-SCAN
|
||||
: MSG-BROADCAST ( type from paddr plen ch -- )
|
||||
BC-CH ! BC-PLEN ! BC-PADDR ! BC-FROM ! BC-TYPE !
|
||||
BC-CH @ CH-MBRS@ BC-SCAN !
|
||||
BEGIN BC-SCAN @ 0<> WHILE
|
||||
BC-TYPE @ BC-FROM @ BC-SCAN @ MBR-VM@
|
||||
BC-PADDR @ BC-PLEN @ BC-CH @ MSG-SEND
|
||||
BC-SCAN @ MBR-NEXT@ BC-SCAN !
|
||||
REPEAT ;
|
||||
Block 4152
|
||||
( Hermes v1 -- Phase 2: COMMON-CH membership + test )
|
||||
VARIABLE BCAST-GOT
|
||||
: BCAST-RECV ( -- ) 1 BCAST-GOT +! ;
|
||||
: REGISTER-COMMON-MEMBERS ( -- )
|
||||
0 COMMON-CH @ CH-ADD-MBR
|
||||
1 COMMON-CH @ CH-ADD-MBR
|
||||
2 COMMON-CH @ CH-ADD-MBR ;
|
||||
6 CONSTANT BCAST-EVENT
|
||||
: SEND-BROADCAST-TEST ( -- )
|
||||
BCAST-EVENT 1 S" BCAST-RECV" COMMON-CH @ MSG-BROADCAST ;
|
||||
Block 4153
|
||||
( LOAD-DOE: pulls in doe.4th's word-level DOE-WORK )
|
||||
( workload, for doe-campaign.4th's remote VM-EXEC. )
|
||||
: LOAD-DOE ( -- ) S" doe.4th" EXEC ;
|
||||
Block 5116
|
||||
( CD-INIT ran only via the old self-test; birth needs it now. )
|
||||
CD-INIT
|
||||
( Hermes owns the one real, canonical COMMON-CH. Every )
|
||||
( other VM subscribes into it via VM-EXEC (see Artemis's )
|
||||
( and Hera's own init.4th); Hera always exists first, so )
|
||||
( Hermes adds her here rather than Hera subscribing to a )
|
||||
( VM that doesn't exist yet at Hera's own birth. )
|
||||
S" common:messaging.4th" EXEC
|
||||
MSG-CD-INIT
|
||||
S" lib.4th" EXEC
|
||||
1 COMMON-CH @ CH-ADD-MBR
|
||||
0 COMMON-CH @ CH-ADD-MBR
|
||||
LOG-INFO" Hermes: ready"
|
||||
STARTUP-BANNER
|
||||
|
||||
Binary file not shown.
@@ -223,6 +223,19 @@ int capsule_vm_registry_get(VMUuid vm_id, VMRegistryEntry *out);
|
||||
*/
|
||||
uint32_t capsule_vm_registry_count(void);
|
||||
|
||||
/**
|
||||
* capsule_vm_registry_get_by_index - Get registry entry by list position
|
||||
* (birth order, stable within a boot session -- the registry is
|
||||
* append-only). For enumeration (e.g. the idle-loop messaging pump,
|
||||
* FABRIC-3.md Phase C, 2026-08-28), where no vm_id is known up front.
|
||||
* Index range is [0, capsule_vm_registry_count()).
|
||||
*
|
||||
* @param index Zero-based position in birth order
|
||||
* @param out Output: registry entry copy
|
||||
* @return 0 on success, -1 if index is out of range
|
||||
*/
|
||||
int capsule_vm_registry_get_by_index(uint32_t index, VMRegistryEntry *out);
|
||||
|
||||
/**
|
||||
* capsule_vm_find_by_name - Find VM registry entry by symbolic name
|
||||
*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -199,6 +199,18 @@ uint32_t capsule_vm_registry_count(void) {
|
||||
return vm_registry_count;
|
||||
}
|
||||
|
||||
int capsule_vm_registry_get_by_index(uint32_t index, VMRegistryEntry *out) {
|
||||
vm_node_t *node = vm_registry_head;
|
||||
uint32_t i = 0;
|
||||
if (!out) return -1;
|
||||
while (node) {
|
||||
if (i == index) { *out = node->entry; return 0; }
|
||||
node = node->next;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Live population, distinct from vm_registry_count above: vm_registry_count
|
||||
* is monotonic (incremented on every vm_registry_alloc(), never decremented
|
||||
* on death), so it counts every VM ever born, not the outer Stadium's
|
||||
|
||||
@@ -813,6 +813,20 @@ static void kernel_main_deep(BootInfo *boot_info) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase C (2026-08-28): Hera does NOT get her own common:messaging.4th
|
||||
* arena -- register_child_vm_words()'s own doc comment (mama_forth_
|
||||
* words.c) explains why: the eight STADIUM-* FORTH primitives that
|
||||
* word depends on (CH-HEAT@/!, MSG-HEAT@/! etc. all route through
|
||||
* them) are deliberately never added to register_mama_forth_words(),
|
||||
* to avoid moving Hera's dict_hash off item 4.1's baseline. Confirmed
|
||||
* live: loading messaging.4th into Hera's own dictionary silently
|
||||
* dropped every colon-definition that referenced one of those
|
||||
* primitives (MSG-HEAT@/!, CH-HEAT@/!, MSG-COOL-ALL, MSG-TICK all
|
||||
* missing after boot) -- not a timing bug, a real, pre-existing
|
||||
* constraint. Hera orchestrates via BIRTH/VM-EXEC/VM-CALL directly
|
||||
* instead; the idle-loop pump (repl.c) skips her own registry entry
|
||||
* for the same reason. */
|
||||
|
||||
/* Hermes is now a permanent fleet-foundation VM, not self-test
|
||||
* scaffolding -- FABRIC-3.md D.7 (birth-by-message-only, 2026-08-28):
|
||||
* the Tripod legs (Hera/Hermes/Artemis) must be alive session-less so
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
#include "starkernel/xhci_driver.h"
|
||||
#include "starkernel/blkio_usb.h"
|
||||
#include "starkernel/homeblocks_sig.h"
|
||||
#include "starkernel/capsule_birth.h"
|
||||
#include "starkernel/capsule_run.h"
|
||||
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h"
|
||||
#include "block_subsystem.h"
|
||||
#include "word_source/include/keyboard_words.h"
|
||||
#include "word_source/include/block_words.h"
|
||||
@@ -185,6 +188,44 @@ static void sk_repl_idle(VM *active_vm)
|
||||
* write with no UPDATE, followed by an idle wait and an abrupt kill,
|
||||
* did not survive a reboot until this fix. */
|
||||
blk_vm_flush_all(active_vm);
|
||||
|
||||
/* FABRIC-3.md Phase C (2026-08-28): distributed messaging pump. Every
|
||||
* live VM except Hera herself now owns its own MSG-ARENA/CH-ARENA and
|
||||
* MSG-TICK word (see capsules/common/messaging.4th) instead of only
|
||||
* Hermes having one -- "fully distributed, Hera pumps each VM's
|
||||
* drain" was the confirmed design. Hera is excluded: she never loads
|
||||
* common:messaging.4th (kernel_main.c's own comment at the Hermes-
|
||||
* birth call site explains why -- the STADIUM-* primitives it needs
|
||||
* are deliberately never registered in her own dictionary, to keep
|
||||
* her dict_hash off item 4.1's baseline), so MSG-TICK is genuinely
|
||||
* absent there, not just untried. She is the only VM with a
|
||||
* persistent idle tick, so she walks the registry once per idle beat
|
||||
* and VM-EXECs MSG-TICK into every OTHER live VM's own dictionary. */
|
||||
{
|
||||
VM *mama = (VM *)sk_get_mama_vm();
|
||||
uint32_t count = capsule_vm_registry_count();
|
||||
uint32_t i;
|
||||
for (i = 0; i < count; i++) {
|
||||
VMRegistryEntry ent;
|
||||
if (capsule_vm_registry_get_by_index(i, &ent) != 0) continue;
|
||||
if (ent.state != VM_STATE_LIVE) continue;
|
||||
if (ent.vm_ptr == (void *)mama) continue;
|
||||
|
||||
static const char PFX[] = "S\" MSG-TICK\" S\" ";
|
||||
static const char SFX[] = "\" VM-EXEC";
|
||||
char cmd[128];
|
||||
size_t p = 0;
|
||||
size_t name_len = strlen(ent.name);
|
||||
if (name_len > VM_NAME_MAX - 1u) name_len = VM_NAME_MAX - 1u;
|
||||
|
||||
memcpy(cmd + p, PFX, sizeof(PFX) - 1u); p += sizeof(PFX) - 1u;
|
||||
memcpy(cmd + p, ent.name, name_len); p += name_len;
|
||||
memcpy(cmd + p, SFX, sizeof(SFX) - 1u); p += sizeof(SFX) - 1u;
|
||||
cmd[p] = '\0';
|
||||
|
||||
vm_interpret(mama, cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user