Path: utzoo!attcan!uunet!crdgw1!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!usc!apple!portal!cup.portal.com!ts From: ts@cup.portal.com (Tim W Smith) Newsgroups: comp.sys.mac.programmer Subject: Re: True lightweight threads for the Mac? Message-ID: <35054@cup.portal.com> Date: 20 Oct 90 03:48:07 GMT References: <1990Oct9.161031.12927@swbatl.sbc.com> Organization: The Portal System (TM) Lines: 72 I don't known about C++ threads (I've never seen them), but I'm putting together a tasking library for the Mac. I'm planning on doing this as part of a generic application development library. The basic idea is that you create tasks within your application. Tasks run and sleep and all the usual things. You do your user interface by associating tasks with certain events. For example, you could create a task to handle updates for certain window, and have this task sleep until an update event for that window. You could handle commands by associating tasks with various sets of menu selections. You are allowed to force a task switch from an interrupt, so you can do premptive stuff if that's the kind of stuff you want to do. You can also do semi-premptive stuff. In semi-premptive mode, an interrupt can cause a task switch to an interrupt handling task, but when that task gives up the CPU, you go back to the preempted task. This really simplifies interrupt routines, because they have a context and they can sleep while they wait for the next interrupt. This lets interrupt routines be written in a much clearer fashion (I've used this approach in a couple of real-time embedded systems, and it really helps development and debugging). I'm working in Think C. The basic task switching stuff works pretty well (task switch time is about 20 microseconds on a Mac II). I'm just getting started on all the high level stuff. Unfortunately, things are real busy at work, and I've got some other stuff at home that is higher priority, so I don't know when this will get done, but when it does, I'll post the code. A discussion on the net about how such a system should work could be quite interesting. I think using tasks to implement the user interface will make it much easier to deal with the Mac interface. What do the rest of you think? What kind of things should a task be able to sleep for? Should it be able to sleep waiting for only a single thing, or should it be able to specify some sort of list of things it wants to wake up for? By the way, one thing to watch out for if you create things with their own stacks, is the stack sniffer. This runs at vertical retrace time, and if it finds the stack pointer is in the heap, you get a bomb. If you are allocating stack space for the tasks in the heap, you've got a problem. And you can't just divide the space between the end of the heap and original application stack into a bunch of chunks and switch between them. At first, this might seem OK, as long as you leave enough room for hardware interrupts on each stack. However, according to DTS, the toolbox thinks that it owns everything between the stack and the heap. In particular, it feels free to use this for temporary storage, so it is never safe to store anything there. So, you have to disable the stack sniffer (you do this by changing a low memory global). However, there is still a problem. Because the tookbox expects to be able to use the space between the stack and the heap as temporary space, it does not like the stack pointer to be in the heap. This means that before calling any Mac traps from a stack, you've got to put the stack pointer back to something "reasonable", do the call, and then put the stack pointer back to the stack for the task. In other words, you are going to end up implementing your own glue for every trap. Yuck! Tim Smith ps: Oh, DTS says you are not supposed to do this sort of thing, so furture compatibility is a risk.