Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Oct 1998 04:42:34 -0500 (EST)
From:      HighWind Software Information <info@highwind.com>
To:        current@FreeBSD.ORG
Subject:   Thread Scheduler bug
Message-ID:  <199810290942.EAA21626@highwind.com>

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


I'm worried about the thread scheduler. Here is a disturbing test
program out for folks to try.

As you can probably guess, we are now battling the scheduler because
some of our application's threads are getting seriously starved by
other threads.

I'm compiling on 3.0 with the latest libc_r.

This program works fine on IRIX, Solaris, and (gasp..) Linux.

Isn't FreeBSD supposed to handle this without the explicit yield() call?

-Rob

----

/*****************************************************************************
File:     schedBug.C
Contents: FreeBSD Scheduling Bug Illustrator

This program SHOULD print "Marking Time : 1", etc. However, the thread
scheduler appears to NOT schedule the markTimeThread because the
ioThread is so busy.

If you uncomment the "::pthread_yield()" it works a little
better. Ideally, you should get a print every second.

g++ -o schedBug -D_REENTRANT -D_THREAD_SAFE -g -Wall schedBug.C -pthread 

*****************************************************************************/

#include <assert.h>
#include <fcntl.h>
#include <memory.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

unsigned int LENGTH = 1024 * 1024;

void *ioThread(void *)
{
    char *data = new char[LENGTH];
    ::memset(data, 0, LENGTH);

    while (true) {
	int file = ::open("scrap", O_CREAT | O_TRUNC | O_WRONLY, 0666);
	assert(file != -1);
	assert(::write(file, data, LENGTH) == static_cast<ssize_t>(LENGTH));
	//
	// Uncomment the next line to make things a bit better
	//
	// ::pthread_yield();
	//
	assert(!::close(file));
    }
}

void *markTimeThread(void *)
{
    time_t start = ::time(0);
    while (true) {
	timeval timeout;
	timeout.tv_sec = 1;
	timeout.tv_usec = 0;
	::select(0, 0, 0, 0, &timeout); 

	::printf("Marking Time: %lu\n", ::time(0) - start);
    }
}

int main(int, char **)
{
    // Set up Thread Arguments
    pthread_t tid;
    pthread_attr_t attr;
    assert(!::pthread_attr_init(&attr));
    assert(!::pthread_attr_setdetachstate(&attr,
					  PTHREAD_CREATE_DETACHED));

    // Spawn markTimeThread
    assert(!::pthread_create(&tid, &attr, markTimeThread, 0));
    // Spawn ioThread
    assert(!::pthread_create(&tid, &attr, ioThread, 0));

    // main() goes away for a long time
    timeval timeout;
    timeout.tv_sec = 3600;
    timeout.tv_usec = 0;
    ::select(0, 0, 0, 0, &timeout); 

    return EXIT_SUCCESS;
}

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



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