2023-06-11 07:52:22 : 0= 1 u< ; 2023-06-11 08:29:21 : 0= not ; 2023-06-11 08:29:59 Well, forget that. Caffeine hasn't kicked. 2023-06-11 08:30:01 :-( 2023-06-11 08:30:35 That moment when you really wish there was a "delete." :-) 2023-06-11 08:40:26 :-) 2023-06-11 08:46:48 Anyway, my own 0= is a primitive. 2023-06-11 08:47:34 I think it's neat how many things can be written "in Forth" and don't require primitives. But if you go that way in every single case, you are impacting performance to some degree. 2023-06-11 08:47:57 If the primitive is very short and straightforward (and this one is), I usually go that way. 2023-06-11 08:48:34 I am trying to rig up this layer of "portability macros" to keep that from amplifying the amount of work a port would require to at least some degree. 2023-06-11 08:49:04 so I'm trying to have my cake and eat it too to some degree. 2023-06-11 08:49:07 We'll see how it goes. 2023-06-11 08:52:52 Of course, there is also 2023-06-11 08:52:59 : 0= 0 = ; 2023-06-11 08:53:01 :-) 2023-06-11 08:53:14 Which one might argue is a bit more "obvious." 2023-06-11 09:07:08 So, thoughts on how one might implement multiple console interfaces in a multi-threaded system? 2023-06-11 09:07:21 I.e., what if I want two threads running both of which offer me a console interface? 2023-06-11 09:07:53 In a perfect world this would feel like having multiple bash sessions using screen. 2023-06-11 09:13:08 The only way I really see to do it is to have a threads output to the screen go into some disk buffer, and when I connect to that thread a system layer uses the tail of that buffer to draw the screen for me. 2023-06-11 09:20:48 If I maximize one of my terminator panels, I get a 191x53 screen. That's 10123 characters. So three blocks would hold that, with some left over for color and attribute changes. So I guess in a system along these lines a "console" would have a block number associated with it which was the base of its display data. The only way I see to make it fast enough on full display re-paints would be to have it be 2023-06-11 09:20:50 EXACTLY the data required to recreate the screen, so that I could just find the right place to start in it (number of lines back equal to my screen height) and just TYPE it in one shot. 2023-06-11 09:21:49 Or two - it would likely be a rotating buffer, so you might start somewhere in the middle, go to the end, and then start at the beginning and go to the latest data. 2023-06-11 09:23:12 So the thread creating the output would just stick it in that buffer and that would be that - there would be some other thread that would move that to hte actual display, if the physical console was connected to that item. 2023-06-11 10:00:13 Actually probably simplifies things to let that output buffer be large enough to not require any wrapping. Once I'm far enough into it, I'd just discard the oldest stuff and move everything back toward lower RAM. That way the "latest" would always be the highest address stuff. 2023-06-11 10:00:33 And just a single TYPE of a sufficiently large part of the most recent stuff would refresh the screen. 2023-06-11 10:08:37 Looks like most of the time it takes me 30 usec or so to TYPE a full screenful of stuff. 2023-06-11 10:09:37 So if I set this up so that switching to another console just TYPES a big chunk of recent history to gen the screen, that's going to be "snappy." 2023-06-11 10:10:27 Not that that will be TYPE anymore - TYPE will just concatenate its string to the current output buffer. 2023-06-11 10:10:48 A background thread will see that new data and send it to the real screen. 2023-06-11 10:35:08 How about input? There are options - I could "stream" that too in a similar way, or I could just have a thread block on "ownership" of the keyboard before it actually calls KEY. 2023-06-11 12:10:26 Ok, I think I worked out a reasonable way to pursue that. Once you have the notion of threads in play, it's all pretty straightforward. 2023-06-11 12:52:20 Oh, wow - you can now edit / delete Google chats. 2023-06-11 12:52:32 That's the main way I stay in touch with family, so that's a nice improvement. 2023-06-11 12:53:12 services that google has killed; services that google has yet to kill 2023-06-11 12:53:15 Hey, did anyone think of any other "sort of standard" user variables? 2023-06-11 12:53:31 So far I've listed sp0, rp0, and "onerr." 2023-06-11 12:54:02 If a thread wants to do console i/o it needs stuff for that, but that can be optional. 2023-06-11 12:54:46 nope, i don't care about language standards (unless it's C) 2023-06-11 12:56:17 I didn't really mean "standard" in that way - I just meant t hings that any thread would need, regardless of what it was doing. 2023-06-11 12:56:38 They've got to know where there stacks are, and need to know how to behave in response to errors. 2023-06-11 12:57:03 I normally don't have much interest in "formal" standards either. 2023-06-11 13:49:37 The thing is, a lot of things declared by typical Forth programs probably ought to be user vars instead of having the value in the dictionary. Unless they're deliberately intended to be used by multipled threads, for sync or whatever. A variable just there to hold a value for a brief period needs to be unique to its thread. 2023-06-11 13:50:47 So if it's just a variable used to help deal with stack overload, it likely needs to be a user variable. 2023-06-11 13:51:11 I'm consiering making VARIABLE do that - use some other name for defining "system" variables. 2023-06-11 13:53:16 will your threads share a global dictionary? rather than having a thread-specific dictionary granted to each? 2023-06-11 13:54:52 Well, if I give a thread access to the console, then I might want to be able to define words from multiple threads - I'd give them each their own vocabulary. But I'm more interested in threads EXECUTING stuff - I imagine most of the time I'll build the dictionary from one thread and the others will just use that stuff. 2023-06-11 13:55:10 I would likely say "multi-user" if I wanted that level of operation. 2023-06-11 14:07:04 As far as those multiple consoles go, I do want it to work a lot like using screen for multiple bash sessions. I might be doing totally different sorts of work in those threads. 2023-06-11 14:08:27 I did have some ideas the other day for potential ways to be able to load some code, use it, and unload it. Basically I'd grow "permanent" parts of the dictionary up from the bottom in the usual way, but also have dynamically allocated blocks higher up where I could put stuff I intended to unload in some reasonable period of time. 2023-06-11 14:08:55 It would reqiure some careful coding, but I don't see any reason it wouldn't work. 2023-06-11 14:10:05 That would be heap-like, and yes, it would court fragmentation. But since none of those things would stay long term, it would eventually have opportunities to "clean up." 2023-06-11 14:10:29 I'd have to actually try it to see how well it worked out. 2023-06-11 14:12:02 I don't think Jim has covered the Fragmentation Court yet 2023-06-11 14:13:22 Yeah, that one doesn't ring a bell. 2023-06-11 14:14:50 Those table-based CFAs and PFAs complicate it, because they'd need such "heaped" sections too. The thing that really drove me to that was wanting to be able to have 16-bit xts. And I've questioned that lately - any way you slice it is an eventual "limitation." If I reverted to 32-bit xts, then there's really no reason to do the tables. 2023-06-11 14:16:08 I could have flavors of tasks. 1) tasks that just execute already compiled code. The most minimal ones. 2) tasks that can work a console so I can interact with them. And 3) tasks that can extend the dictionary in a private way. All of those could be supported with just a "task block" of RAM - its size and layout would depend on the flavor. 2023-06-11 14:18:35 The third type needs full dictionary handling support, which implies that PATH and CURRENT should also be user vars in that case. 2023-06-11 14:19:17 And each one would automatically get a private vocabulary to work in. 2023-06-11 14:20:47 I'd like for the flavor 1 threads to be extremely minimal - hopefully just a few hundred bytes total overhead. 2023-06-11 14:21:03 And easy to spin up / shut down. 2023-06-11 14:53:36 What I don't really see wanting to do, though, is have additional threads (that will be children of the "root" thread) that themselves have FURTHER children that modify the dictionary. So I might restrict that to the root and children of the root. 2023-06-11 14:54:48 Actually I'm not sure I'd even call those root children - more like more root level. Root siblings. 2023-06-11 14:55:26 But I would want the root to be able to compile source and have some of that, at least, inherited by other tasks. 2023-06-11 14:55:59 I'm not quite sure how to split that - I imagine some code I loaded would be "system use only," whereas some of it would be "finishing out the standard dictionary." 2023-06-11 15:10:59 That bottom level system will carry all of the "standard stuff" that I want to be able to use anywhere, but also will contain stuff for thread management, memory management, ipc, and so on. "OS" level stuff. 2023-06-11 15:11:06 File system, when I get around to having one. 2023-06-11 15:11:18 Kernel stuff, I suppose. 2023-06-11 15:19:10 Another thing that would be useful would be an ability to load a vocabulary, use it to compile stuff into whatever dictionary zone I was working on, and then unload those tools I'd just used. Assembler is a good example. 2023-06-11 15:19:24 Load it, use it, dump it, and use the results.