Mail Archives: djgpp/2000/12/19/07:54:53
On Tue, 19 Dec 2000 13:19:41 +0200 (IST), Eli Zaretskii
<eliz AT is DOT elta DOT co DOT il> wrote:
>First, please post a SYMIFY'ed traceback, both from Windows and from
>plain DOS. If the traceback points into code that isn't included in
>what you posted, please show that code as well.
OK, I will do that when I get to my own PC... but I think I should
first try to figure out exactly how this code is supposed to work
myself, before bothering newsgroup readers with possibly small
problem.
I was hoping to find 'plug and play' threading package to get quickly
started in porting my 16-bit application that uses CTASK multitasking
library and MSC 6.0 to 32 bit world. Clearly LWP is more 'plug and
pray'...
>This doesn't show where the control is returned to user code (I assume
>that the SIGILL handler acts as a scheduler, so it must jump to
>application's code at some point). It is important to see where it
>does so.
>I also don't see any code which saves the registers of the interrupted
>thread and restores the registers of the thread about to be run.
>Where is it?
Sorry, it is here: (SIGILL handler makes a 'jmpl _lwpYield')
.align 4
_lwpYield:
pushl %ds
.byte 0x2e
movw ___djgpp_ds_alias, %ds
movl $1, lwpInterruptPending
popl %ds
pushal
pushl %ds
pushl %es
pushl %fs
pushl %gs
pushfl
subl $108, %esp
fwait
fnsave (%esp) /* FPU pushal ;) */
fwait
.byte 0x2e
movw ___djgpp_ds_alias, %ds
movl __lwpCur, %esi
movl %esp, 12(%esi)
yl1: movl 4(%esi), %esi /* Find next ACTIVE thread */
cmpl $0, 24(%esi)
je yl1
movl 12(%esi), %esp
movl %esi, __lwpCur
fwait
frstor (%esp) /* FPU popal ;) */
fwait
addl $108, %esp
popfl
popl %gs
popl %fs
popl %es
popl %ds
popal
pushl %ds
.byte 0x2e
movw ___djgpp_ds_alias, %ds
movl $0, lwpInterruptPending
popl %ds
ret
>This doesn't show the code which locks the interrupt handler's code
>and data. Is it there, anywhere? If so, let's see it.
Here: (_lwpasmStart and _lwpasmEnd are labels at start and at the end
of interrupt handler code)
static int _lwpLockMemory()
{
if(!_lwpLockCode(&_lwpasmStart, (long) &_lwpasmEnd - (long)
_lwpasmStart))
{
return(FALSE);
}
if(!_lwpLockData((void *) &_lwpEnable, 4))
{
return(FALSE);
}
return(TRUE);
}
static int _lwpLockData( void *lockaddr, unsigned long locksize )
{
unsigned long baseaddr;
__dpmi_meminfo memregion;
if( __dpmi_get_segment_base_address( _my_ds(), &baseaddr) == -1 )
{
return(FALSE);
}
memset( &memregion, 0, sizeof(memregion) );
memregion.address = baseaddr + (unsigned long) lockaddr;
memregion.size = locksize;
if( __dpmi_lock_linear_region( &memregion ) == -1 )
{
return(FALSE);
}
return(TRUE);
}
static int _lwpLockCode( void *lockaddr, unsigned long locksize )
{
unsigned long baseaddr;
__dpmi_meminfo memregion;
if( __dpmi_get_segment_base_address( _my_cs(), &baseaddr) == -1 )
{
return(FALSE);
}
memset( &memregion, 0, sizeof(memregion) );
memregion.address = baseaddr + (unsigned long) lockaddr;
memregion.size = locksize;
if( __dpmi_lock_linear_region( &memregion ) == -1 )
{
return(FALSE);
}
return(TRUE);
}
>I see that LWP also has something to say about the FPU exceptions.
>Does the example which crashes actually use FP code? If so, it's
>possible that the SIGFPE handler is also involved in this; you didn't
>show it.
There is no FP involved, yet.
>> I suspect that the registers are pushed to stack on incorrect order,
>
>What registers? I don't see any registers being pushed in the code
>you posted.
They are pushed and popped in lwpYield routine I accidentally left out
in my previous post.
>If you become desperate and want to make sure old DJGPP versions
>indeed work with LWP, you can always install an old djdevNNN.zip and
>try compiling and linking with it. Personally, I don't think this has
>anything to do with DJGPP versions, unless some code you omitted will
>demonstrate otherwise.
That is one possibility, thanks. But I also begin to think the problem
is within my copy of LWP. Either the initial task stack created is
incorrect or then the task switching code is bad. Here is the task
creation fragment where initial stack frame then yielded is created -
sorry for long post. Probably some important stuff is again left out
but I dont want to post all of LWP in this newsgroup since
jtlwp20s.zip can be found in
ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2tk
tmpLwpPtr->stack[(stackLength/4) - 1] = (long) param;
tmpLwpPtr->stack[(stackLength/4) - 2] = (long) _lwpDeadYield;
tmpLwpPtr->stack[(stackLength/4) - 3] = (long) proc;
tmpLwpPtr->stack[(stackLength/4) - 4] = 0; /* eax */
tmpLwpPtr->stack[(stackLength/4) - 5] = 0; /* ebx */
tmpLwpPtr->stack[(stackLength/4) - 6] = 0; /* ecx */
tmpLwpPtr->stack[(stackLength/4) - 7] = 0; /* edx */
tmpLwpPtr->stack[(stackLength/4) - 8] = 0; /* ebp */
tmpLwpPtr->stack[(stackLength/4) - 9] = 0; /* esp, discarded by
popal */
tmpLwpPtr->stack[(stackLength/4) -10 ] = 0; /* esi */
tmpLwpPtr->stack[(stackLength/4) -11] = 0; /* edi */
tmpLwpPtr->stack[(stackLength/4) -12] = (long) _my_ds(); /* ds */
tmpLwpPtr->stack[(stackLength/4) -13] = (long) _my_ds(); /* es */
tmpLwpPtr->stack[(stackLength/4) -14] = (long) _my_ds(); /* fs */
tmpLwpPtr->stack[(stackLength/4) -15] = (long) _my_ds(); /* gs */
tmpLwpPtr->stack[(stackLength/4) -16] = (long) _lwpFlags; /* flags
*/
/* copy initial FPU state to stack */
memcpy(tmpLwpPtr->stack + (stackLength/4) - 43, _lwpFpuState, 108);
tmpLwpPtr->stack = tmpLwpPtr->stack + (stackLength/4) - 43;
tmpLwpPtr->priority = priority;
tmpLwpPtr->pcount = priority;
tmpLwpPtr->active = active;
tmpLwpPtr->lwpid = ++_lwpPidCount;
tmpLwpPtr->next = _lwpCur->next;
_lwpCur->next = tmpLwpPtr;
_lwpCount++;
_lwpEnable = tmpCriticalSection;
return(tmpLwpPtr->lwpid);
>Does the LWP docs say exactly on what platform(s) the DJGPP version was
>tested to work?
Unfortunately no, the only clue is in file dates 12/1997.
thanks for help
Tuukka
- Raw text -