From: tuukka DOT kalliokoski AT nokia DOT com (Tuukka Kalliokoski) Newsgroups: comp.os.msdos.djgpp Subject: Re: Problems with LWP 2.0 / djgpp 2.03 Organization: Nokia PMR Message-ID: <3a3dd511.1814705398@news.europe.nokia.com> References: X-Newsreader: Forte Free Agent 1.21/32.243 Lines: 126 Date: Mon, 18 Dec 2000 09:27:37 GMT NNTP-Posting-Host: 172.22.117.117 X-Complaints-To: newsmaster AT nokia DOT com X-Trace: news2.nokia.com 977131657 172.22.117.117 (Mon, 18 Dec 2000 11:27:37 EET) NNTP-Posting-Date: Mon, 18 Dec 2000 11:27:37 EET To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com On Mon, 18 Dec 2000 09:47:52 +0200 (IST), Eli Zaretskii wrote: >If you can post the relevant fragments from LWP here, perhaps we could >give you some directions for untangling this riddle. That would be great. Here is the timer interrupt routine, that raises the SIGILL scheduling signal: __lwpPmIrq8TimerHook: pushl %eax pushl %ds .byte 0x2E /* CS: */ movw ___djgpp_ds_alias, %ds cmp $0, lwpInterruptPending jne L2 movl $1, lwpInterruptPending cmp $1, __lwpEnable jne L1 movb $0x99,%al call ___djgpp_hw_exception jmp L2 L1: movl $0, lwpInterruptPending L2: popl %ds popl %eax ljmp %cs:__lwpOldIrq8Handler And here is main part of the SIGILL handler: .align 4 __lwpScheduler: movl $1, lwpInterruptPending movl ___djgpp_exception_state_ptr, %edi cmpl $0, %edi /* SIGILL was raise()'d, not by interrupt */ je raised cmpl $0x99, 56(%edi) /* our exception or real exception? */ jne raised movl 0(%edi), %eax pushl %eax movl 4(%edi), %ebx movl 8(%edi), %ecx movl 12(%edi), %edx movl 16(%edi), %esi movl 24(%edi), %ebp movl 28(%edi), %eax movl %eax, tmp1 /* esp */ movl 32(%edi), %eax movl %eax, tmp2 /* eip */ movl 36(%edi), %eax movl %eax, tmp3 /* eflags */ movl 20(%edi), %eax /* edi */ movw 44(%edi), %es movw 46(%edi), %fs movw 48(%edi), %gs movw 42(%edi), %ds movl %eax, %edi popl %eax .byte 0x2e movl tmp1, %esp /* stack switched to exception state stack */ .byte 0x2e pushl tmp2 /* push exeception state ret address */ .byte 0x2e pushl tmp3 /* eflags */ popfl /* now it's setup to look just like a yield happened in the code */ /* This little bit is what does the priorities */ pushl %eax pushl %esi pushl %ds pushfl .byte 0x2e movw ___djgpp_ds_alias, %ds movl __lwpCur, %esi decl 20(%esi) /* pcount */ jnz noYld /* pcount == 0 ? */ movl 16(%esi), %eax /* yes, pcount = priority */ movl %eax, 20(%esi) popfl popl %ds popl %esi popl %eax jmpl _lwpYield noYld: popfl popl %ds popl %esi popl %eax raised: pushl %ds .byte 0x2e movw ___djgpp_ds_alias, %ds movl $0, lwpInterruptPending popl %ds ret Here is the C fragment that vectors the IRQ and signal handlers: /* SIGILL is raised when an unhandled exception is raised */ _lwpOldHandler = signal(SIGILL,_lwpScheduler); _lwpOldFpuHandler = signal(SIGFPE, _lwpFpuHandler); irq8.offset32 = (int)_lwpPmIrq8TimerHook; irq8.selector = _my_cs(); __dpmi_get_protected_mode_interrupt_vector(IRQ8,&_lwpOldIrq8Handler); __dpmi_set_protected_mode_interrupt_vector(IRQ8, &irq8); I suspect that the registers are pushed to stack on incorrect order, or something is missing from SIGILL handler. I am quite sure that this code has worked with older gcc version. Tuukka