commit - c715a6127a46b8090591972b5c4bb04dfabbca8b
commit + e97ceade5e1bba5787e39429384336fa37797906
blob - 20ffe3861d9174d0d3c00dbcb9ce9311e92e998e
blob + f85487bd7af777d557aab3eaa0a53cb73dbe237d
--- include/fcall.h
+++ include/fcall.h
#ifndef _FCALL_H_
#define _FCALL_H_ 1
-#if defined(__cplusplus)
-extern "C" {
+#ifdef __cplusplus
+extern "C" {
#endif
/*
#pragma src "/sys/src/libc/9sys"
*/
#define VERSION9P "9P2000"
-
#define MAXWELEM 16
typedef
#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
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
}
/* 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
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
<$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
cistrncmp.$O\
cistrstr.$O\
cleanname.$O\
+ convD2M.$O\
+ convM2D.$O\
+ convM2S.$O\
+ convS2M.$O\
create.$O\
ctime.$O\
date.$O\
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
Pqueue _threadpq;
+int _threadmultiproc;
+
static int nextID(void);
/*
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);
}
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
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
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){
{
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;
}
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
int pid; /* process id */
int splhi; /* delay notes */
Thread *thread; /* running thread */
+ Thread *idle; /* idle thread */
int needexec;
Execargs exec; /* exec argument */
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);
void _xinc(long*);
void _threadremove(Proc*, Thread*);
+extern int _threadmultiproc;
extern int _threaddebuglevel;
extern char* _threadexitsallstatus;
extern Pqueue _threadpq;