Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Feb 2000 18:16:41 -0800 (PST)
From:      John Polstra <jdp@polstra.com>
To:        current@freebsd.org
Subject:   pthread_{suspend,resume}_np broken?
Message-ID:  <XFMail.000229181641.jdp@polstra.com>

next in thread | raw e-mail | index | archive | help
This message is in MIME format
--_=XFMail.1.3.p0.FreeBSD:000229181641:60681=_
Content-Type: text/plain; charset=us-ascii

Either pthread_suspend_np() and pthread_resume_np() are broken in
-current or I don't understand them.  The attached program (cc
-pthread suspend.c) starts two background threads.  Each thread loops
outputting a character ('1' or '2' according to which thread it is)
and then sleeping for a second.  Meanwhile, the main thread reads
keypresses from the standard input.  On each keypress it toggles
background thread 1 between suspended and resumed.

If it worked properly I would expect the output to resemble this:

    12121-S-222222-R-121212-S-222-R-212121212 and so on.

Instead I get this:

    121-S-212-R-12121-S-212121-R-12121-S-212121

I.e., the thread doesn't get suspended.  Am I misunderstanding what
these functions are supposed to do?

Also, the code in "src/lib/libc_r/uthread/uthread_resume_np.c" looks
wrong:

int
pthread_resume_np(pthread_t thread)
{
        int ret;

        /* Find the thread in the list of active threads: */
        if ((ret = _find_thread(thread)) == 0) {
                /* The thread exists. Is it suspended? */
                if (thread->state != PS_SUSPENDED) {
                        /*
                         * Defer signals to protect the scheduling queues
                         * from access by the signal handler:
                         */
                        _thread_kern_sig_defer();

                        /* Allow the thread to run. */ 
                        PTHREAD_NEW_STATE(thread,PS_RUNNING);
                  
                        /*
                         * Undefer and handle pending signals, yielding if
                         * necessary:
                         */
                        _thread_kern_sig_undefer();
                }   
        }
        return(ret);
}

Shouldn't the test against PS_SUSPENDED be "==" instead of "!="?  I
would think we'd want to do something if the thread was suspended, and
skip it if the thread wasn't suspended -- exactly the opposite of what
the current code does.

John
---
  John Polstra                                               jdp@polstra.com
  John D. Polstra & Co., Inc.                        Seattle, Washington USA
  "Disappointment is a good sign of basic intelligence."  -- Chögyam Trungpa


--_=XFMail.1.3.p0.FreeBSD:000229181641:60681=_
Content-Disposition: attachment; filename="suspend.c"
Content-Transfer-Encoding: 7bit
Content-Description: suspend.c
Content-Type: text/plain; charset=us-ascii; name=suspend.c; SizeOnDisk=1208

#include <err.h>
#include <pthread.h>
#include <pthread_np.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>

#define SLEEP	1000000		/* 1 second */

pthread_t bg1;
pthread_t bg2;

static void *
bgfunc(void *arg)
{
    char ch = *(char *)arg;

    for ( ; ; ) {
	putchar(ch);
	usleep(SLEEP);
    }
}

int
main(int argc, char **argv)
{
    struct termios t;
    int ret;

    /* Set up stdin and stdout to deliver characters immediately. */
    setbuf(stdout, NULL);
    tcgetattr(fileno(stdin), &t);
    t.c_lflag &= ~(ECHO | ICANON);
    t.c_cc[VMIN] = 1;
    t.c_cc[VTIME] = 0;
    tcsetattr(fileno(stdin), TCSAFLUSH, &t);

    /* Start two background threads. */
    pthread_create(&bg1, NULL, bgfunc, "1");
    usleep(SLEEP / 2);
    pthread_create(&bg2, NULL, bgfunc, "2");

    /*
     * On each keystroke, toggle background thread 1 between suspended
     * and running.
     */
    for ( ; ; ) {
	getchar();
	fputs("-S-", stdout);
	if ((ret = pthread_suspend_np(bg1)) != 0)
	    errc(1, ret, "pthread_suspend_np failed");
	getchar();
	fputs("-R-", stdout);
	if ((ret = pthread_resume_np(bg1)) != 0)
	    errc(1, ret, "pthread_resume_np failed");
    }
    return 0;
}

--_=XFMail.1.3.p0.FreeBSD:000229181641:60681=_--
End of MIME message


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?XFMail.000229181641.jdp>