+FarmerPotato Posted March 14, 2022 Share Posted March 14, 2022 In my idle phone-only time this weekend, I’ve been reading about concurrency in the TI books: Microprocessor Pascal Users Manual (MP351) and anything I can find on the standalone Real-time Executive (or the Pascal RTS.) Reading on a very small screen. (And typing now!) The Bedford UK Microprocessor group published TI’s Software Development Handbook (which I’d never seen until the TI Archive at Southern Methodist U in Dallas TX.) The 1981 2nd edition is in Archive.org and Bitsavers , with much more discussion of concurrency (chapters 5-6.) It’s remarkable for its advocacy of structured programming. In particular, the hierarchy of SYSTEM, Program, Processes (Threads) and subroutines. But it was the era of textbooks by Niklaus Wirth— and Edsgar Dijkstra, with whom TI in Texas associated closely. I bet they hired his graduate students from UT Austin where their Data Systems group was located. (Textbooks cited in every Bibliography in these books!) @Stuart, your 990 website indicates that you have a copy of MP385 the MP Pascal System Manual. Is there any way you could share that? (Is it MP305 or MP385?) I bet it has much more detail on the Real-time API than the Pascal Users Guide. there was also a (lost to time?) Component Software Handbook and TI Realtime Executive manual. Targeted at small systems like the TM990 boards with 16K of RAM. Each manual above says that the Real-time Executive, and the Pascal RTS, provided semaphores, concurrent process priorities, scheduling, and interrupts. Plus shared memory, where shared queues—think mailboxes—are located for IPC (interprocess communication.) They built Mutex (see Pascal Users Manual) on Counting Semaphore (“the most useful kind of semaphore” heh heh.) I Compare and contrast Unix v6, which is built on spinlock and sleeplock. (Source found on internet particularly the teeny v6_riscv) So it has Counting Semaphores, with atomic operations Wait/Signal, queues for waiting, and global Ready queue. There is a simple priority scheduler, which I’m unclear how it interacts with time slices, as it’s principle is that the highest priority process that is Ready gets all the CPU. Maybe these were separate implementations? The Real-time rules are simple. The Ready queue is sorted by priority at all times. If a process WAITs on a semaphore whose count is 0, then it goes to the tail of the semaphore’s Wait queue. Then the scheduler runs the next process at the head of the Ready queue. Otherwise it continues running. If a process SIGNALs a semaphore, and there is a process in that semaphore’s Wait queue, both go to the Ready queue, where the scheduler decides which one gets the CPU (highest priority.) otherwise it increments Count and continues to run. The WAIT and SIGNAL *must* be atomic—they are system calls (XOP 15) and LIMI 0. An example, Make Tea, does a WAIT on a semaphore Kettle_Boiling, then pours the water and DELAYs for five minutes. Presumably, other lower priority processes are allowed to run, like Set Table or Sweep Kitchen. A bigger example is a Mailbox circular buffer, where 2 processes produce or consume Mails. At start, the semaphore Slot_Available is initialized to count 10, the total free slots for mail. A semaphore Mail_Ready is initialized to Count 0. The processes look like this: Producer DO WAIT(slot_available) SIGNAL(mail_ready) REPEAT Consumer DO WAIT(mail_ready) SIGNAL(slot_available) REPEAT I’ve worked out one way to code these concurrency features as these TI books present them. (On my iphone, Working Copy is a very nice code editor and git client! Makes good use of the small screen and miserable touch keyboard.) Like TI says, It uses an XOP for the atomics WAIT and SIGNAL, during which interrupts are disabled. The XOPs test Counts, manipulate queues, then either RTWP to the caller, or save R13-R15 to process record then BLWP into the Scheduler. But I’d like to see the full API to clarify decisions TI made. For example, in the disassembled Make Tea program, it kicks off with the Start Process call, which takes 5 stack parameters. It gets arguments of 1 and a stack size 6. And 3 other parameters -1,0,0. In Stop process the stack is given that “1” variable again like it’s a Pricess ID. I’m not sure what that 1 might accomplish. Perhaps the program is pre-loaded with a PID in that memory location? Also, the Pascal translator makes position independent code! Very Nice. How? On entry, the Pascal program has registers initialized with a stack pointer, code segment pointer (all branch statements are indexed relative to this!) and a data segment pointer for its local variables. The binary comes with a header, starting with relative entry point, and max stack size required. I enjoy researching all this! In my day job, everything is multiprocessor and threaded, so it’s fun to see this simple but adequate model where Pascal accomplishes everything with counting semaphores. In 1981, TI (or at least the MP folks in Bedford) was going in the direction of multiprocessing on 9900s (see E-Bus Systems Guide.) I’ve read @apersson850 posts on his multitasking UCSD/P-Code. Very good to read. Though setting up p-code at home is daunting. (Also I’m not at home!) Ideally, I’d like to find the source to TI’s pascal RTS or RE semaphore implementation. Or at least a bona-fide ROM or disk copy to disassemble! Any leads on this? @jbdigriz 1 1 Quote Link to comment Share on other sites More sharing options...
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.