Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!att!cbnewsk!ech From: ech@cbnewsk.att.com (ned.horvath) Newsgroups: comp.sys.mac.programmer Subject: Re: VBL tasks Message-ID: <1991May15.162658.25040@cbnewsk.att.com> Date: 15 May 91 16:26:58 GMT References: <1991May15.081149.4579@neon.Stanford.EDU> Organization: AT&T Bell Laboratories Lines: 71 From article <1991May15.081149.4579@neon.Stanford.EDU>, by cheshire@neon.Stanford.EDU (Stuart David Cheshire): > Sample code follows: > > /* define a structure which is a VBLTask queue element with four bytes to > stash A5, our application global pointer, appended to the end */ > > typedef struct { VBLTask task; long *regA5; } ex_VBLTask; > local ex_VBLTask *task_qelem; > > /* define a 'jump instruction' structure to put on the system heap. It is > six bytes -- a two byte opcode and a four byte absolute address. The code > that address points to must already be in memory and we must not call > UnLoadSeg or it will vanish under us. */ > > typedef struct { short jmp_opcode; void (*codeptr)(void); } jumpcode; > local jumpcode *task_code; > > /* code starts here*/ > > { > /* allocate structures in System Heap */ > task_qelem = (ex_VBLTask*) NewPtrSysClear(sizeof(ex_VBLTask)); > task_code = (jumpcode *) NewPtrSysClear(sizeof(jumpcode)); > > /* fill in opcode for jump and the address to jump to */ > task_code->jmp_opcode = 0x4EF9; > task_code->codeptr = &MacTick; > > /* set up the queue element and install it */ > task_qelem->task.qType = vType; > task_qelem->task.vblAddr = (ProcPtr)task_code; > task_qelem->task.vblCount = 1; > task_qelem->regA5 = Application_A5; > VInstall(task_qelem); > } > > local void MacTick(void) > { > asm { move.l a5, -(sp) > move.l OFFSET(ex_VBLTask,regA5)(a0), a5 > } > > /* do stuff here. Globals may be accessed if required. */ > > asm { move.l (sp)+, a5 } > } Perhaps you didn't receive my email on this subject. While your code will work, and work correctly, it will create problems on a Mac running under VM: there is no guarantee that your MacTick() routine, or your below-A5 (globals) area will be in memory. If they aren't, you are going to page-swap at VBL-interrupt time (not cool). I haven't given the VM section of IM-VI a careful reading, but I'd guess that what you propose will WORK. However, it's quite possible that the jerkiness it introduces will be perceptible to the user... A way to avoid the problem is to check for VM enabled (using Gestalt) and make the appropriate locking calls to keep your routine and the vars it needs in memory. Another way is to load the MacTick code, and the variables it needs, into the System heap (which doesn't swap). Your app, since it does the allocation, can continue to access the vars needed by the VBL task. Finally, as always with a VBL task, remember that you are running at interrupt time: all the memory-moving traps are off limits, and you should do the minimum possible processing in the VBL itself. -- =Ned Horvath= ehorvath@attmail.com