From: adr <adr@SDF.ORG>
To: 9fans <9fans@9fans.net>
Subject: Re: [9fans] syscall silently kill processes
Date: Wed, 29 Jun 2022 13:14:39 +0000 (UTC) [thread overview]
Message-ID: <52572223-75a6-f96f-7cac-f4f89eadfbf@SDF.ORG> (raw)
In-Reply-To: <8d31d18e-d3ca-f8e0-7fb-b231955c77d7@SDF.ORG>
[-- Attachment #1: Type: text/plain, Size: 10258 bytes --]
On Tue, 28 Jun 2022, adr wrote:
> It's just to play with it, note that onnote should be just passed
> once. I'll post another patch if things work ok.
Here it is. I'm doing sysfatal when malloc fails to be coherent
with the rest of libthread, but I don't think that's a good approach.
When those functions fail to make an allocation they should return
an error so the program could take an action depending on the error.
For example, if there is no sufficient memory at a time, the program
could wait until there are enough resources to spawn a new thread.
adr
--- /tmp/main.c
+++ /sys/src/libthread/main.c
@@ -28,6 +28,10 @@
_qlockinit(_threadrendezvous);
_sysfatal = _threadsysfatal;
__assert = _threadassert;
+ onnote = mallocz(PPCHUNK*sizeof(uintptr), 1);
+ if(!onnote)
+ sysfatal("Malloc of size %d failed: %r", PPCHUNK*sizeof(uintptr));
+ onnotesize = PPCHUNK;
notify(_threadnote);
if(mainstacksize == 0)
mainstacksize = 8*1024;
--- /tmp/note.c
+++ /sys/src/libthread/note.c
@@ -5,7 +5,6 @@
int _threadnopasser;
-#define NFN 33
#define ERRLEN 48
typedef struct Note Note;
struct Note
@@ -17,62 +16,157 @@
static Note notes[128];
static Note *enotes = notes+nelem(notes);
-static int (*onnote[NFN])(void*, char*);
-static int onnotepid[NFN];
+Onnote **onnote;
+int onnotesize;
+static int (*onnoteall[NFN])(void*, char*);
static Lock onnotelock;
int
threadnotify(int (*f)(void*, char*), int in)
{
- int i, topid;
- int (*from)(void*, char*), (*to)(void*, char*);
+ int i, j, n;
- if(in){
- from = nil;
- to = f;
- topid = _threadgetproc()->pid;
- }else{
- from = f;
- to = nil;
- topid = 0;
- }
lock(&onnotelock);
- for(i=0; i<NFN; i++)
- if(onnote[i]==from){
- onnote[i] = to;
- onnotepid[i] = topid;
+
+ /* add note for all processes */
+ if(in < -1){
+ n = -1;
+ for(i=0; i<NFN; i++){
+ if(onnoteall[i] == f){
+ unlock(&onnotelock);
+ return 1;
+ }
+ if(onnoteall[i]==nil && n==-1)
+ n = i;
+ }
+ if(n > -1)
+ onnoteall[n] = f;
+ unlock(&onnotelock);
+ return n>-1;
+ }
+
+ /* remove note for all processes */
+ if(in == -1){
+ for(i=0; i<NFN; i++)
+ if(onnoteall[i] == f){
+ onnoteall[i] = nil;
+ break;
+ }
+ unlock(&onnotelock);
+ return i<NFN;
+ }
+
+ /* remove note for current process */
+ if(!in){
+ for(i=0; i<onnotesize; i++){
+ if(onnote[i]!=nil && onnote[i]->pid==_threadgetproc()->pid){
+ for(j=0; j<NFN; j++){
+ if(onnote[i]->fn[j] == f){
+ onnote[i]->fn[j] = 0;
+ break;
+ }
+ }
+ unlock(&onnotelock);
+ return j<NFN;
+ }
+ }
+ unlock(&onnotelock);
+ return 0;
+ }
+
+ /* add note for current process */
+ n = -1;
+ for(i=0; i<onnotesize; i++){
+ /* process has already a slot */
+ if(onnote[i] && onnote[i]->pid==_threadgetproc()->pid){
+ n = -1;
+ for(j=0; j<NFN; j++){
+ if(onnote[i]->fn[j] == f){
+ unlock(&onnotelock);
+ return 1;
+ }
+ if(onnote[i]->fn[j]==nil && n==-1)
+ n = j;
+ }
+ if(n > -1)
+ onnote[i]->fn[n] = f;
+ unlock(&onnotelock);
+ return n>-1;
+ }
+ /* there is a free slot */
+ if(!onnote[i] && n==-1)
+ n = i;
+ }
+ /* there is no free slot */
+ if(n == -1){
+ onnotesize += PPCHUNK;
+ onnote = realloc(onnote, onnotesize*sizeof(uintptr));
+ if(!onnote){
+ unlock(&onnotelock);
+ sysfatal("Malloc of size %d failed: %r", onnotesize*sizeof(uintptr));
+ }
+ memset(onnote+i+1, 0, PPCHUNK-1);
+ n = i;
+ }
+ onnote[n]=mallocz(sizeof(Onnote), 1);
+ if(!onnote[n]){
+ unlock(&onnotelock);
+ sysfatal("Malloc of size %d failed: %r", sizeof(Onnote));
+ }
+ onnote[n]->pid = _threadgetproc()->pid;
+ onnote[n]->fn[0] = f;
+ unlock(&onnotelock);
+ return 1;
+}
+
+void
+threadcancelnotes(int pid)
+{
+ int i;
+
+ lock(&onnotelock);
+ for(i=0; i<onnotesize; i++)
+ if(onnote[i] && onnote[i]->pid==pid){
+ free(onnote[i]);
+ onnote[i] = nil;
break;
}
unlock(&onnotelock);
- return i<NFN;
+ return;
}
static void
delayednotes(Proc *p, void *v)
{
- int i;
+ int i, j, all;
Note *n;
- char s[ERRMAX];
- int (*fn)(void*, char*);
+ int (*f)(void*, char*);
if(!p->pending)
return;
p->pending = 0;
+ all = j = 0;
for(n=notes; n<enotes; n++){
if(n->proc == p){
- strcpy(s, n->s);
- n->proc = nil;
- unlock(&n->inuse);
-
- for(i=0; i<NFN; i++){
- if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
- continue;
- if((*fn)(v, s))
- break;
+ for(i=0; i<NFN; i++)
+ if(f=onnoteall[i])
+ if((*f)(v, n->s)){
+ all = 1;
+ break;
+ }
+ if(!all){
+ for(i=0; i<onnotesize; i++)
+ if(onnote[i] && onnote[i]->pid==p->pid){
+ for(j=0; j<NFN; j++)
+ if(f=onnote[i]->fn[j])
+ if((*f)(v, n->s))
+ break;
+ break;
+ }
}
- if(i==NFN){
- _threaddebug(DBGNOTE, "Unhandled note %s, proc %p", n->s, p);
+ if(!all && (i==onnotesize || j==NFN)){
+ _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
if(v != nil)
noted(NDFLT);
else if(strncmp(n->s, "sys:", 4)==0)
@@ -79,6 +173,8 @@
abort();
threadexitsall(n->s);
}
+ n->proc = nil;
+ unlock(&n->inuse);
}
}
}
@@ -94,7 +190,7 @@
noted(NDFLT);
if(_threadexitsallstatus){
- _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'", _threadexitsallstatus);
+ _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
_exits(_threadexitsallstatus);
}
--- /tmp/sched.c
+++ /sys/src/libthread/sched.c
@@ -157,6 +157,7 @@
t = runthread(p);
if(t == nil){
_threaddebug(DBGSCHED, "all threads gone; exiting");
+ threadcancelnotes(p->pid);
unlinkproc(p);
_schedexit(p); /* frees proc */
}
--- /tmp/thread.h
+++ /sys/include/thread.h
@@ -97,6 +97,7 @@
void threadkillgrp(int); /* kill threads in group */
void threadmain(int argc, char *argv[]);
int threadnotify(int (*f)(void*, char*), int in);
+void threadcancelnotes(int pid);
int threadid(void);
int threadpid(int);
int threadsetgrp(int); /* set thread group, return old */
--- /tmp/threadimpl.h
+++ /sys/src/libthread/threadimpl.h
@@ -192,3 +192,15 @@
#define _threaddebug(flag, ...) if((_threaddebuglevel&(flag))==0){}else _threadprint(__VA_ARGS__)
#define ioproc_arg(io, type) (va_arg((io)->arg, type))
+
+#define PPCHUNK 100
+#define NFN 33
+typedef struct Onnote Onnote;
+struct Onnote
+{
+ int pid;
+ int (*fn[NFN])(void*, char*);
+};
+extern Onnote **onnote;
+extern int onnotesize;
+void _threadnote(void*, char*);
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tfa6823048ad90a21-M0bb660408ef52d611ffd55ab
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-diff; name=thread.patch, Size: 6162 bytes --]
--- /tmp/main.c
+++ /sys/src/libthread/main.c
@@ -28,6 +28,10 @@
_qlockinit(_threadrendezvous);
_sysfatal = _threadsysfatal;
__assert = _threadassert;
+ onnote = mallocz(PPCHUNK*sizeof(uintptr), 1);
+ if(!onnote)
+ sysfatal("Malloc of size %d failed: %r", PPCHUNK*sizeof(uintptr));
+ onnotesize = PPCHUNK;
notify(_threadnote);
if(mainstacksize == 0)
mainstacksize = 8*1024;
--- /tmp/note.c
+++ /sys/src/libthread/note.c
@@ -5,7 +5,6 @@
int _threadnopasser;
-#define NFN 33
#define ERRLEN 48
typedef struct Note Note;
struct Note
@@ -17,62 +16,157 @@
static Note notes[128];
static Note *enotes = notes+nelem(notes);
-static int (*onnote[NFN])(void*, char*);
-static int onnotepid[NFN];
+Onnote **onnote;
+int onnotesize;
+static int (*onnoteall[NFN])(void*, char*);
static Lock onnotelock;
int
threadnotify(int (*f)(void*, char*), int in)
{
- int i, topid;
- int (*from)(void*, char*), (*to)(void*, char*);
+ int i, j, n;
- if(in){
- from = nil;
- to = f;
- topid = _threadgetproc()->pid;
- }else{
- from = f;
- to = nil;
- topid = 0;
- }
lock(&onnotelock);
- for(i=0; i<NFN; i++)
- if(onnote[i]==from){
- onnote[i] = to;
- onnotepid[i] = topid;
+
+ /* add note for all processes */
+ if(in < -1){
+ n = -1;
+ for(i=0; i<NFN; i++){
+ if(onnoteall[i] == f){
+ unlock(&onnotelock);
+ return 1;
+ }
+ if(onnoteall[i]==nil && n==-1)
+ n = i;
+ }
+ if(n > -1)
+ onnoteall[n] = f;
+ unlock(&onnotelock);
+ return n>-1;
+ }
+
+ /* remove note for all processes */
+ if(in == -1){
+ for(i=0; i<NFN; i++)
+ if(onnoteall[i] == f){
+ onnoteall[i] = nil;
+ break;
+ }
+ unlock(&onnotelock);
+ return i<NFN;
+ }
+
+ /* remove note for current process */
+ if(!in){
+ for(i=0; i<onnotesize; i++){
+ if(onnote[i]!=nil && onnote[i]->pid==_threadgetproc()->pid){
+ for(j=0; j<NFN; j++){
+ if(onnote[i]->fn[j] == f){
+ onnote[i]->fn[j] = 0;
+ break;
+ }
+ }
+ unlock(&onnotelock);
+ return j<NFN;
+ }
+ }
+ unlock(&onnotelock);
+ return 0;
+ }
+
+ /* add note for current process */
+ n = -1;
+ for(i=0; i<onnotesize; i++){
+ /* process has already a slot */
+ if(onnote[i] && onnote[i]->pid==_threadgetproc()->pid){
+ n = -1;
+ for(j=0; j<NFN; j++){
+ if(onnote[i]->fn[j] == f){
+ unlock(&onnotelock);
+ return 1;
+ }
+ if(onnote[i]->fn[j]==nil && n==-1)
+ n = j;
+ }
+ if(n > -1)
+ onnote[i]->fn[n] = f;
+ unlock(&onnotelock);
+ return n>-1;
+ }
+ /* there is a free slot */
+ if(!onnote[i] && n==-1)
+ n = i;
+ }
+ /* there is no free slot */
+ if(n == -1){
+ onnotesize += PPCHUNK;
+ onnote = realloc(onnote, onnotesize*sizeof(uintptr));
+ if(!onnote){
+ unlock(&onnotelock);
+ sysfatal("Malloc of size %d failed: %r", onnotesize*sizeof(uintptr));
+ }
+ memset(onnote+i+1, 0, PPCHUNK-1);
+ n = i;
+ }
+ onnote[n]=mallocz(sizeof(Onnote), 1);
+ if(!onnote[n]){
+ unlock(&onnotelock);
+ sysfatal("Malloc of size %d failed: %r", sizeof(Onnote));
+ }
+ onnote[n]->pid = _threadgetproc()->pid;
+ onnote[n]->fn[0] = f;
+ unlock(&onnotelock);
+ return 1;
+}
+
+void
+threadcancelnotes(int pid)
+{
+ int i;
+
+ lock(&onnotelock);
+ for(i=0; i<onnotesize; i++)
+ if(onnote[i] && onnote[i]->pid==pid){
+ free(onnote[i]);
+ onnote[i] = nil;
break;
}
unlock(&onnotelock);
- return i<NFN;
+ return;
}
static void
delayednotes(Proc *p, void *v)
{
- int i;
+ int i, j, all;
Note *n;
- char s[ERRMAX];
- int (*fn)(void*, char*);
+ int (*f)(void*, char*);
if(!p->pending)
return;
p->pending = 0;
+ all = j = 0;
for(n=notes; n<enotes; n++){
if(n->proc == p){
- strcpy(s, n->s);
- n->proc = nil;
- unlock(&n->inuse);
-
- for(i=0; i<NFN; i++){
- if(onnotepid[i]!=p->pid || (fn = onnote[i])==nil)
- continue;
- if((*fn)(v, s))
- break;
+ for(i=0; i<NFN; i++)
+ if(f=onnoteall[i])
+ if((*f)(v, n->s)){
+ all = 1;
+ break;
+ }
+ if(!all){
+ for(i=0; i<onnotesize; i++)
+ if(onnote[i] && onnote[i]->pid==p->pid){
+ for(j=0; j<NFN; j++)
+ if(f=onnote[i]->fn[j])
+ if((*f)(v, n->s))
+ break;
+ break;
+ }
}
- if(i==NFN){
- _threaddebug(DBGNOTE, "Unhandled note %s, proc %p", n->s, p);
+ if(!all && (i==onnotesize || j==NFN)){
+ _threaddebug(DBGNOTE, "Unhandled note %s, proc %p\n", n->s, p);
if(v != nil)
noted(NDFLT);
else if(strncmp(n->s, "sys:", 4)==0)
@@ -79,6 +173,8 @@
abort();
threadexitsall(n->s);
}
+ n->proc = nil;
+ unlock(&n->inuse);
}
}
}
@@ -94,7 +190,7 @@
noted(NDFLT);
if(_threadexitsallstatus){
- _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'", _threadexitsallstatus);
+ _threaddebug(DBGNOTE, "Threadexitsallstatus = '%s'\n", _threadexitsallstatus);
_exits(_threadexitsallstatus);
}
--- /tmp/sched.c
+++ /sys/src/libthread/sched.c
@@ -157,6 +157,7 @@
t = runthread(p);
if(t == nil){
_threaddebug(DBGSCHED, "all threads gone; exiting");
+ threadcancelnotes(p->pid);
unlinkproc(p);
_schedexit(p); /* frees proc */
}
--- /tmp/thread.h
+++ /sys/include/thread.h
@@ -97,6 +97,7 @@
void threadkillgrp(int); /* kill threads in group */
void threadmain(int argc, char *argv[]);
int threadnotify(int (*f)(void*, char*), int in);
+void threadcancelnotes(int pid);
int threadid(void);
int threadpid(int);
int threadsetgrp(int); /* set thread group, return old */
--- /tmp/threadimpl.h
+++ /sys/src/libthread/threadimpl.h
@@ -192,3 +192,15 @@
#define _threaddebug(flag, ...) if((_threaddebuglevel&(flag))==0){}else _threadprint(__VA_ARGS__)
#define ioproc_arg(io, type) (va_arg((io)->arg, type))
+
+#define PPCHUNK 100
+#define NFN 33
+typedef struct Onnote Onnote;
+struct Onnote
+{
+ int pid;
+ int (*fn[NFN])(void*, char*);
+};
+extern Onnote **onnote;
+extern int onnotesize;
+void _threadnote(void*, char*);
next prev parent reply other threads:[~2022-06-29 13:15 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-17 9:37 andrey100100100
2022-06-17 13:46 ` Thaddeus Woskowiak
2022-06-17 14:11 ` Jacob Moody
2022-06-17 14:39 ` Thaddeus Woskowiak
2022-06-17 15:06 ` andrey100100100
2022-06-17 16:08 ` Skip Tavakkolian
2022-06-17 16:11 ` Skip Tavakkolian
2022-06-17 16:16 ` Skip Tavakkolian
2022-06-17 17:42 ` adr
2022-06-17 16:11 ` Jacob Moody
2022-06-17 18:48 ` andrey100100100
2022-06-17 19:28 ` Jacob Moody
2022-06-17 21:15 ` adr
2022-06-18 6:40 ` andrey100100100
2022-06-18 8:37 ` adr
2022-06-18 9:22 ` adr
2022-06-18 12:53 ` Jacob Moody
2022-06-18 22:03 ` andrey100100100
2022-06-19 5:54 ` adr
2022-06-19 6:13 ` Jacob Moody
2022-06-18 22:22 ` andrey100100100
2022-06-18 16:57 ` andrey100100100
2022-06-19 2:40 ` adr
2022-06-19 5:01 ` adr
2022-06-19 8:52 ` andrey100100100
2022-06-19 10:32 ` adr
2022-06-19 11:40 ` andrey100100100
2022-06-19 12:01 ` andrey100100100
2022-06-19 15:10 ` andrey100100100
2022-06-19 16:41 ` adr
2022-06-19 21:22 ` andrey100100100
2022-06-19 21:26 ` andrey100100100
2022-06-20 4:41 ` adr
2022-06-20 5:39 ` andrey100100100
2022-06-20 5:59 ` adr
2022-06-20 15:56 ` andrey100100100
2022-06-20 22:29 ` Skip Tavakkolian
2022-06-21 7:07 ` andrey100100100
2022-06-21 11:26 ` adr
2022-06-21 13:03 ` andrey100100100
2022-06-21 13:22 ` adr
2022-06-28 15:28 ` adr
2022-06-28 16:43 ` ori
2022-06-28 18:19 ` adr
2022-06-28 18:28 ` adr
2022-06-28 19:09 ` andrey100100100
2022-06-28 19:42 ` adr
2022-06-29 13:14 ` adr [this message]
2022-06-21 13:47 ` andrey100100100
2022-06-21 7:22 ` adr
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=52572223-75a6-f96f-7cac-f4f89eadfbf@SDF.ORG \
--to=adr@sdf.org \
--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).