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>
index | next in thread | raw e-mail
[-- Attachment #1 --]
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
[-- Attachment #2 --]
#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;
}
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.000229181641.jdp>
