9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: erik quanstrom <quanstro@quanstro.net>
To: 9fans@9fans.net
Subject: Re: [9fans] problem with building from source on vx32 solved
Date: Tue, 31 Aug 2010 08:54:49 -0400	[thread overview]
Message-ID: <4fdbe45db39b4c9d8bb6f360e12dde9c@brasstown.quanstro.net> (raw)
In-Reply-To: <AANLkTikVuCtt-CJH5C30L_1iUw=ioDpuUaWu4-jNjH9N@mail.gmail.com>

> A simple change:
> pid = getpid();

shouldn't you just fix it so _tos->pid is set?

also, the comments in the new nsec.c don't
match the code.  the code looks something like this

	do{
		...
		tries = 0;
	}while(tries++ == 0);	/* retry once */

of course either this should be

	/* just retry for ever */
	for(;;){
		...
	}
or
	/* retry once */
	for(tries = 0; tries < 2; tries++)

also, there's nothing stoping the race between
- two procs allocating the same element of the pid array
- two procs opening the global fd twice

both cases have the potential to leak an unlimited amount
of file descriptors.  i've added a proposed change.

- erik

----
#include <u.h>
#include <libc.h>
#include <tos.h>

static uvlong order = 0x0001020304050607ULL;

static void
be2vlong(vlong *to, uchar *f)
{
	uchar *t, *o;
	int i;

	t = (uchar*)to;
	o = (uchar*)&order;
	for(i = 0; i < sizeof order; i++)
		t[o[i]] = f[i];
}

static Lock nseclk;
static Lock fdlk;
static int fd = -1;
static struct {
	int	pid;
	int	fd;
} fds[64];

vlong
nsec(void)
{
	uchar b[8];
	vlong t;
	int pid, i, *f, tries;

	/*
	 * Threaded programs may have multiple procs
	 * with different fd tables, so we may need to open
	 * /dev/bintime on a per-pid basis
	 */
	pid = _tos->pid;
	f = nil;
	for(i = 0; i < nelem(fds); i++)
		if(fds[i].pid == pid){
			f = &fds[i].fd;
			break;
		}
	if(i == nelem(fds)){
		lock(&nseclk);
		for(i = 0; i < nelem(fds); i++)
			if(fds[i].pid == 0){
				fds[i].pid = pid;
				fds[i].fd = -1;
				f = &fds[i].fd;
				break;
			}
		unlock(&nseclk);
	}
	if(f == nil)
		f = &fd;
	for(tries = 0; tries < 2; tries++){
		if(*f < 0){
			if(f == &fd)
				lock(&fdlk);
			if((*f = open("/dev/bintime", OREAD|OCEXEC)) < 0)
				break;
			fd = *f;
			if(f == &fd)
				unlock(&fdlk);
		}
		if(pread(*f, b, sizeof b, 0) == sizeof b){
			be2vlong(&t, b);
			return t;
		}
		close(*f);
		*f = -1;
	}
	if(i < nelem(fds))
		fds[i].pid = 0;	/* unlocked release */
	return 0;
}



  reply	other threads:[~2010-08-31 12:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-31  6:00 ron minnich
2010-08-31 12:54 ` erik quanstrom [this message]
2010-08-31 14:59   ` ron minnich
2010-08-31 15:25     ` erik quanstrom
2010-09-02  6:35       ` ron minnich
2010-09-02 11:57         ` erik quanstrom
2010-09-02 15:05           ` ron minnich
2010-09-03  5:59             ` ron minnich
2010-09-03  8:21               ` Charles Forsyth
2010-09-03 14:56                 ` ron minnich
2010-09-03 14:57               ` Philippe Anel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4fdbe45db39b4c9d8bb6f360e12dde9c@brasstown.quanstro.net \
    --to=quanstro@quanstro.net \
    --cc=9fans@9fans.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).