*BSD News Article 36681


Return to BSD News archive

Newsgroups: comp.os.386bsd.misc
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msuinfo!agate!howland.reston.ans.net!EU.net!Germany.EU.net!netmbx.de!unlisys!geminix.in-berlin.de!luthien.in-berlin.de!wagner
From: wagner@luthien.in-berlin.de (Olaf Wagner)
Subject: Last problem of M3 port to FreeBSD
X-Newsreader: Tin 1.1 PL4
Organization: 'Holistic Computing Services'
Message-ID: <CxA0vv.Ius@luthien.in-berlin.de>
Date: Fri, 7 Oct 1994 00:19:04 GMT
Lines: 173

[ Article crossposted from comp.lang.modula3 ]
[ Author was Olaf Wagner ]
[ Posted on Fri, 7 Oct 1994 00:14:34 GMT ]


Hello all,

I am looking for help concerning the last (I hope so ;-) problem of the
SRC M3 port to FreeBSD 1.1.5:

As with most ports, it seems, the problem is in the thread interface.
The threads are running, and I am quite sure I have got the size of 
the jump_buf right, the values in Target.m3 are correct for FreeBSD
and the signal interface is ok. The last vexing problem that I haven't
been able to track down during the last few days is that threads preempted 
by SIGVTALARM will raise floating point exceptions now and then. It seems
as if the delivery of the signal during the execution of a floating point
operation will cause this operation to fail. Here is a simple program that
will invariably fail due to floating point exceptions:


(* Test: threads and floating point operations*)

MODULE Main;

IMPORT Fmt, Wr, Thread, Stdio;
<*FATAL ANY*>

TYPE
  T = Thread.Closure BRANDED "T" OBJECT
        inc: INTEGER; END;

VAR 
  task1, task2, task3, task4, task5, task6: T;
  t1, t2, t3, t4, t5, t6: Thread.T;

PROCEDURE task (self: T) : REFANY RAISES {} =
   VAR n, m : INTEGER;
   VAR a, b, c : REAL;
BEGIN
 n := 0;
 a := 1.001;
 b := 1.002;
 WHILE n < 1000000 DO
    IF ABS(b) < 0.000001 THEN
       b := 2000.0;
    END;
    c := a / b;
    (*
    m := 23400 * 50 + (123 * 40 DIV 8);
    *)
    INC(n);
    a := b;
    b := c;
 END;
 RETURN NIL;
END task;


BEGIN

task1 := NEW (T, apply := task, inc := 1);
task2 := NEW (T, apply := task, inc := 2);
task3 := NEW (T, apply := task, inc := 3);
task4 := NEW (T, apply := task, inc := 4);
task5 := NEW (T, apply := task, inc := 5);
task6 := NEW (T, apply := task, inc := 6);


t1 := Thread.Fork (task1);
t2 := Thread.Fork (task2);
t3 := Thread.Fork (task3);
t4 := Thread.Fork (task4);
t5 := Thread.Fork (task5);
t6 := Thread.Fork (task6);

EVAL Thread.Join (t1);
EVAL Thread.Join (t2);
EVAL Thread.Join (t3);
EVAL Thread.Join (t4);
EVAL Thread.Join (t5);
EVAL Thread.Join (t6);

END Main.

You even don't need six threads, two are enough. Everything will work fine
if you just use integer arithmetic. The program works fine on the Linux
machine I used to crosscompile the M3-compiler, though the implementation of
threads is not very different (stdio took me considerably longer).
I have looked at everything I could think of and am somewhat at a loss:
Can it really be that the floating point status is not saved correctly
by setjmp/longjmp? Is there a subtle problem in ThreadPosix I haven't found?
I had a look at libpthread, but there setjmp/longjmp seem to be used in 
a very similar way. Is my hardware broken (though everything else works
fine (I've got an 486 33 MHz with 16 MB RAM))?

By the way, here is the implementation of setjmp/longjmp in libc of 
FreeBSD 1.1.5:

/*
 * C library -- _setjmp, _longjmp
 *
 *	_longjmp(a,v)
 * will generate a "return(v)" from the last call to
 *	_setjmp(a)
 * by restoring registers from the environment 'a'.
 * The previous signal state is NOT restored.
 */

#include "DEFS.h"

ENTRY(_setjmp)
	movl	4(%esp),%eax
	movl	0(%esp),%edx
	movl	%edx, 0(%eax)		/* rta */
	movl	%ebx, 4(%eax)
	movl	%esp, 8(%eax)
	movl	%ebp,12(%eax)
	movl	%esi,16(%eax)
	movl	%edi,20(%eax)
	fnstcw	28(%eax)
	xorl	%eax,%eax
	ret

ENTRY(_longjmp)
	movl	4(%esp),%edx
	movl	8(%esp),%eax
	movl	0(%edx),%ecx
	movl	4(%edx),%ebx
	movl	8(%edx),%esp
	movl	12(%edx),%ebp
	movl	16(%edx),%esi
	movl	20(%edx),%edi
	fninit
	fldcw	28(%edx)
	testl	%eax,%eax
	jnz	1f
	incl	%eax
1:	movl	%ecx,0(%esp)
	ret

The X applications (Puzzle, Plaid, fisheye, cube) all run fine if I
start them with @M3nopreemption (which disables the SIGVTALARM), but
they invariably crash at some random point with a floating point
exception if they are started without this option.

I would appreciate every hint or opinion you might want to express.

Thanks for your interest

Olaf

/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
|| Olaf Wagner           | wagner@luthien.in-berlin.de (private) | 
|| Hobrechtstrasse 80    | olaf@logware.de (work)                |
|| 12043 Berlin 44       | phone: 49 30  624 99 48               |
|| Germany / Deutschland | please don't call before 9 o'clock    |
\/////////////////////////////////////////////////////////////////

-- 
/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
|| Olaf Wagner           | wagner@luthien.in-berlin.de (private) | 
|| Hobrechtstrasse 80    | olaf@logware.de (work)                |
|| 12043 Berlin 44       | phone: 49 30  624 99 48               |
|| Germany / Deutschland | please don't call before 9 o'clock    |
\/////////////////////////////////////////////////////////////////
-- 
/\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 
|| Olaf Wagner           | wagner@luthien.in-berlin.de (private) | 
|| Hobrechtstrasse 80    | olaf@logware.de (work)                |
|| 12043 Berlin 44       | phone: 49 30  624 99 48               |
|| Germany / Deutschland | please don't call before 9 o'clock    |
\/////////////////////////////////////////////////////////////////