various tweaks.
diff --git a/include/fcall.h b/include/fcall.h
index 20ffe38..f85487b 100644
--- a/include/fcall.h
+++ b/include/fcall.h
@@ -1,7 +1,7 @@
 #ifndef _FCALL_H_
 #define _FCALL_H_ 1
-#if defined(__cplusplus)
-extern "C" { 
+#ifdef __cplusplus
+extern "C" {
 #endif
 /*
 #pragma	src	"/sys/src/libc/9sys"
@@ -9,7 +9,6 @@
 */
 
 #define	VERSION9P	"9P2000"
-
 #define	MAXWELEM	16
 
 typedef
@@ -123,7 +122,8 @@
 #pragma	varargck	type	"M"	ulong
 #pragma	varargck	type	"D"	Dir*
 */
-#if defined(__cplusplus)
+
+#ifdef __cplusplus
 }
 #endif
 #endif
diff --git a/include/thread.h b/include/thread.h
index 9c5d2d0..e9dc96e 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -88,6 +88,7 @@
 int		sendp(Channel *c, void *v);
 int		sendul(Channel *c, unsigned long v);
 int		threadcreate(void (*f)(void *arg), void *arg, unsigned int stacksize);
+int		threadcreateidle(void (*f)(void*), void*, unsigned int);
 void**		threaddata(void);
 void		threadexits(char *);
 void		threadexitsall(char *);
diff --git a/src/cmd/9term/9term.c b/src/cmd/9term/9term.c
index 1b65b88..ef51d86 100644
--- a/src/cmd/9term/9term.c
+++ b/src/cmd/9term/9term.c
@@ -318,7 +318,8 @@
 	}
 
 	/* clicked inside previous selection */
-	if(oldq0 <= newq0 && newq0 < oldq1){
+	/* the "<=" in newq0 <= oldq1 allows us to click the right edge */
+	if(oldq0 <= newq0 && newq0 <= oldq1){
 		*q0 = oldq0;
 		*q1 = oldq1;
 		return 0;
diff --git a/src/cmd/dict/dict.c b/src/cmd/dict/dict.c
index 00534ea..dccd303 100644
--- a/src/cmd/dict/dict.c
+++ b/src/cmd/dict/dict.c
@@ -230,7 +230,6 @@
 	if(debug && doall && cmd == 'a')
 		Bprint(bout, "%d entries, cur=%d\n", dot->n, cur+1);
 	for(;;){
-print("execcmd dot->n %d\n", dot->n);
 		if(cur >= dot->n)
 			break;
 		if(doall) {
diff --git a/src/cmd/mkfile b/src/cmd/mkfile
index b8a63c5..8450d94 100644
--- a/src/cmd/mkfile
+++ b/src/cmd/mkfile
@@ -2,7 +2,7 @@
 <$PLAN9/src/mkhdr
 
 TARG=`ls *.c | sed 's/\.c//'`
-LDFLAGS=$LDFLAGS -lsec -lregexp9 -l9 -lbio -lfmt -lutf
+LDFLAGS=$LDFLAGS -lthread -lsec -lfs -lmux -lregexp9 -l9 -lbio -lfmt -lutf
 
 <$PLAN9/src/mkmany
 
diff --git a/src/lib9/mkfile b/src/lib9/mkfile
index 3dbd6b4..14d8c0e 100644
--- a/src/lib9/mkfile
+++ b/src/lib9/mkfile
@@ -17,6 +17,10 @@
 	cistrncmp.$O\
 	cistrstr.$O\
 	cleanname.$O\
+	convD2M.$O\
+	convM2D.$O\
+	convM2S.$O\
+	convS2M.$O\
 	create.$O\
 	ctime.$O\
 	date.$O\
@@ -31,6 +35,7 @@
 	encodefmt.$O\
 	errstr.$O\
 	exec.$O\
+	fcallfmt.$O\
 	ffork-$SYSNAME.$O\
 	getcallerpc-$OBJTYPE.$O\
 	getenv.$O\
diff --git a/src/libthread/create.c b/src/libthread/create.c
index 6a44c24..55f6c60 100644
--- a/src/libthread/create.c
+++ b/src/libthread/create.c
@@ -2,6 +2,8 @@
 
 Pqueue _threadpq;
 
+int _threadmultiproc;
+
 static int nextID(void);
 
 /*
@@ -81,6 +83,14 @@
 int
 proccreate(void (*f)(void*), void *arg, uint stacksize)
 {
+	Proc *p;
+
+	p = _threadgetproc();
+	if(p->idle){
+		werrstr("cannot create procs once there is an idle thread");
+		return -1;
+	}
+	_threadmultiproc = 1;
 	return procrfork(f, arg, stacksize, 0);
 }
 
@@ -110,6 +120,20 @@
 	return newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
 }
 
+int
+threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
+{
+	int id;
+
+	if(_threadmultiproc){
+		werrstr("cannot have idle thread in multi-proc program");
+		return -1;
+	}
+	id = newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
+	_threadidle();
+	return id;
+}
+
 /*
  * Create and initialize a new Proc structure with a single Thread
  * running inside it.  Add the Proc to the global process list.
diff --git a/src/libthread/exit.c b/src/libthread/exit.c
index 511e5bc..4cda307 100644
--- a/src/libthread/exit.c
+++ b/src/libthread/exit.c
@@ -12,6 +12,8 @@
 
 	p = _threadgetproc();
 	t = p->thread;
+	if(t == p->idle)
+		p->idle = nil;
 	t->moribund = 1;
 	_threaddebug(DBGSCHED, "threadexits %s", exitstr);
 	if(exitstr==nil)
diff --git a/src/libthread/sched.c b/src/libthread/sched.c
index 293e330..d6af1c7 100644
--- a/src/libthread/sched.c
+++ b/src/libthread/sched.c
@@ -93,12 +93,21 @@
 	Thread *t;
 	Tqueue *q;
 
-	if(p->nthreads==0)
+	if(p->nthreads==0 || (p->nthreads==1 && p->idle))
 		return nil;
 	q = &p->ready;
 	lock(&p->readylock);
 	if(q->head == nil){
 		q->asleep = 1;
+		if(p->idle){
+			if(p->idle->state != Ready){
+				fprint(2, "everyone is asleep\n");
+				exits("everyone is asleep");
+			}
+			unlock(&p->readylock);
+			return p->idle;
+		}
+
 		_threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
 		unlock(&p->readylock);
 		while(rendezvous((ulong)q, 0) == ~0){
@@ -167,6 +176,9 @@
 {
 	Tqueue *q;
 
+	if(t == t->proc->idle)
+		return;
+
 	assert(t->state == Ready);
 	_threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id);
 	q = &t->proc->ready;
@@ -191,6 +203,25 @@
 }
 
 void
+_threadidle(void)
+{
+	Tqueue *q;
+	Thread *t;
+	Proc *p;
+
+	p = _threadgetproc();
+	q = &p->ready;
+	lock(&p->readylock);
+	assert(q->head);
+	t = q->head;
+	q->head = t->next;
+	if(q->tail == t)
+		q->tail = nil;
+	p->idle = t;
+	unlock(&p->readylock);
+}
+
+void
 yield(void)
 {
 	_sched();
diff --git a/src/libthread/threadimpl.h b/src/libthread/threadimpl.h
index d9b2240..aa69845 100644
--- a/src/libthread/threadimpl.h
+++ b/src/libthread/threadimpl.h
@@ -115,6 +115,7 @@
 	int		pid;			/* process id */
 	int		splhi;		/* delay notes */
 	Thread	*thread;		/* running thread */
+	Thread	*idle;			/* idle thread */
 
 	int		needexec;
 	Execargs	exec;		/* exec argument */
@@ -185,6 +186,7 @@
 void*	_threadmalloc(long, int);
 void		_threadnote(void*, char*);
 void		_threadready(Thread*);
+void		_threadidle(void);
 ulong	_threadrendezvous(ulong, ulong);
 void		_threadsignal(void);
 void		_threadsysfatal(char*, va_list);
@@ -192,6 +194,7 @@
 void		_xinc(long*);
 void		_threadremove(Proc*, Thread*);
 
+extern int	_threadmultiproc;
 extern int			_threaddebuglevel;
 extern char*		_threadexitsallstatus;
 extern Pqueue		_threadpq;