Commit Diff


commit - c715a6127a46b8090591972b5c4bb04dfabbca8b
commit + e97ceade5e1bba5787e39429384336fa37797906
blob - 20ffe3861d9174d0d3c00dbcb9ce9311e92e998e
blob + f85487bd7af777d557aab3eaa0a53cb73dbe237d
--- include/fcall.h
+++ 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 @@ extern "C" { 
 */
 
 #define	VERSION9P	"9P2000"
-
 #define	MAXWELEM	16
 
 typedef
@@ -123,7 +122,8 @@ int	read9pmsg(int, void*, uint);
 #pragma	varargck	type	"M"	ulong
 #pragma	varargck	type	"D"	Dir*
 */
-#if defined(__cplusplus)
+
+#ifdef __cplusplus
 }
 #endif
 #endif
blob - 9c5d2d0925978dc58da2b480dc6ffd3779ad7875
blob + e9dc96e031bc83452a1ba63890272997a0a4a26f
--- include/thread.h
+++ include/thread.h
@@ -88,6 +88,7 @@ int		send(Channel *c, void *v);
 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 *);
blob - 1b65b88c13f193099276b0d0494e91336ceaaa95
blob + ef51d864b35a4acabeaf6aeb2ecc7ffe8f184d2c
--- src/cmd/9term/9term.c
+++ src/cmd/9term/9term.c
@@ -318,7 +318,8 @@ aselect(uint *q0, uint *q1, Image *color)
 	}
 
 	/* 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;
blob - 00534ea0afe4eb8856f3bb278149f2816eb64855
blob + dccd3037022755943512cee76eadb33c3947a592
--- src/cmd/dict/dict.c
+++ src/cmd/dict/dict.c
@@ -230,7 +230,6 @@ execcmd(int cmd)
 	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) {
blob - b8a63c5714c8f854c690acba69126db45aea059b
blob + 8450d94bf5833cd02b3a0b0c36ba7c9494d503f7
--- src/cmd/mkfile
+++ src/cmd/mkfile
@@ -2,7 +2,7 @@ PLAN9=../..
 <$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
 
blob - 3dbd6b4a731d4c2919d802b908b79aa9f306f73c
blob + 14d8c0e080846b16b1a2c6870df2eec872cfb99d
--- src/lib9/mkfile
+++ src/lib9/mkfile
@@ -17,6 +17,10 @@ OFILES=\
 	cistrncmp.$O\
 	cistrstr.$O\
 	cleanname.$O\
+	convD2M.$O\
+	convM2D.$O\
+	convM2S.$O\
+	convS2M.$O\
 	create.$O\
 	ctime.$O\
 	date.$O\
@@ -31,6 +35,7 @@ OFILES=\
 	encodefmt.$O\
 	errstr.$O\
 	exec.$O\
+	fcallfmt.$O\
 	ffork-$SYSNAME.$O\
 	getcallerpc-$OBJTYPE.$O\
 	getenv.$O\
blob - 6a44c2437647054f0f81b504cd869b2e28aa5380
blob + 55f6c60cfb1ae78885bd52ace003667003cdfea8
--- src/libthread/create.c
+++ src/libthread/create.c
@@ -2,6 +2,8 @@
 
 Pqueue _threadpq;
 
+int _threadmultiproc;
+
 static int nextID(void);
 
 /*
@@ -81,6 +83,14 @@ procrfork(void (*f)(void *), void *arg, uint stacksize
 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 @@ threadcreate(void (*f)(void *arg), void *arg, uint sta
 	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.
blob - 511e5bcaf9dbd746ccf05356f2cf07953ae9da91
blob + 4cda307e1b0331afe942bf93735a9f718e78192f
--- src/libthread/exit.c
+++ src/libthread/exit.c
@@ -12,6 +12,8 @@ threadexits(char *exitstr)
 
 	p = _threadgetproc();
 	t = p->thread;
+	if(t == p->idle)
+		p->idle = nil;
 	t->moribund = 1;
 	_threaddebug(DBGSCHED, "threadexits %s", exitstr);
 	if(exitstr==nil)
blob - 293e330626d6eb6fdb0d8636a94a72cef04e30b3
blob + d6af1c7c0a9977e243f2fad904acaeaa751648ed
--- src/libthread/sched.c
+++ src/libthread/sched.c
@@ -93,12 +93,21 @@ runthread(Proc *p)
 	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 @@ _threadready(Thread *t)
 {
 	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 @@ _threadready(Thread *t)
 }
 
 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();
blob - d9b22403225d987151c09bdf0f71bb099683270d
blob + aa69845cda2fc43adc2afa964b6be25538b9e2f6
--- src/libthread/threadimpl.h
+++ src/libthread/threadimpl.h
@@ -115,6 +115,7 @@ struct Proc
 	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		_threadinitstack(Thread*, void(*)(void*), void*)
 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 @@ long		_xdec(long*);
 void		_xinc(long*);
 void		_threadremove(Proc*, Thread*);
 
+extern int	_threadmultiproc;
 extern int			_threaddebuglevel;
 extern char*		_threadexitsallstatus;
 extern Pqueue		_threadpq;