Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jul 2000 15:27:50 -0700 (PDT)
From:      lawlopez@cisco.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/20016: pthreads: Cannot set scheduling timer/Cannot set virtual timer
Message-ID:  <20000718222750.0210537B6CF@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         20016
>Category:       kern
>Synopsis:       pthreads: Cannot set scheduling timer/Cannot set virtual timer
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 18 15:30:01 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Lawrence D. Lopez
>Release:        3.4
>Organization:
Cisco Systems
>Environment:
FreeBSD nptestbed2.dtdtools.cisco.com 3.4-RELEASE FreeBSD 3.4-RELEASE #0: Fri Jul 14 17:24:47 EDT 2000     lawlopez@nptestbed2.dtdtools.cisco.com:/usr/src/sys/compile/NPTESTBED2X  i386

>Description:
The threads library is terminating because setitimer is being
called with a negative number of microseconds.  This is occuring
because timeout function is taking so long that all of the
timecounter elements are used.

This is occuring because the system call gettimeofday is returning
a negative number of microseconds to _thread_kern_sched() in
/usr/src/lib/libc_r_g/uthread/uthread_kern.c

This is occuring because the microtime() function called
by the system call gettimeofday in
/usr/src/sys/kern/kern_clock.c is returning a negative number
of microseconds.

This is occurring because the inline function tco_delta()
is returning the a negative time.

This is occurring because the timecounter structure used
by microtime and given to tco_delta is being modified
while tco_delta is using it.

Specifically tcl_delta() is calling tc->tc_get_timecount(tc)
and is storing the value in a register.

A timer interrupt occurs at this point which then calls
a timeout function which does not mask off
timer interrupts but which processes for a period of time
long enough so that the original timecounter element used
by microtime is reused.

At this point sync_other_counter() resets tc->tc_offset_count
and tc_delta returns a very large number.

static __inline unsigned 
tco_delta(struct timecounter *tc)
{

        return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) &
            tc->tc_counter_mask);
}


>How-To-Repeat:
It is difficult to reproduce the problem.

I think if you start up a timeout function which
spins for 100 ms and then call gettimeofday()
you may get lucky.


>Fix:
Add to the kernel configuration file:

options         "NTIMECOUNTER=100"

This would allow for timeout functions of up to 1000 milli seconds.

The comments in LINT while they may be correct should be more
specific.

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000718222750.0210537B6CF>