[M3devel] variations of waitpid..?

Jay jay.krell at cornell.edu
Wed Dec 31 20:24:07 CET 2008


You mean, this function is easy to misuse?
 > People who declare their own <*EXTERNAL*>
Like waitpid exposed from m3core?
 
waitpid is already easy to misuse, on a userthread system, leading to possible (though I think rare) deadlock.
It is easy to misuse on pthreads, lead "just" to bad performance, and in fact I believe cm3 is doing this, via sysutils.
This at least guides you between two patterns of use, and fix the perf of cm3/sysutils.
 
On a userthread system, waitpid(pid, flags = 0) waits for the child process, with all parent threads suspended.
Generally I doubt the child depends on parent threads progressing, but, yeah, that could deadlock, like if a parent thread is waiting to a file or stdin of the child, or reading a child's stdout.
 
The various uses do waitpid(pid, flags = nohang) and then sleep and try again.
 
pthreads just uses waitpid(pid, flags = 0) and all threads keep running.
Win32 just uses WaitForSingleObject(process handle, timeout=infinite), and again all threads keep running.
 
Just another problem with user threads, where pthreads and Win32 are fine.
 
> >PROCEDURE Scheduler.DoesWaitProcessYield() : BOOLEAN?
WaitPROCESS always yields.
It is WaitPID that may or may not.
So I renamed the function to DoesWaitPidYield() and moved it to SchedulerPosix.i3.
 
ok?
 
 - Jay> To: jay.krell at cornell.edu> CC: m3devel at elegosoft.com> Subject: Re: [M3devel] variations of waitpid..? > Date: Tue, 30 Dec 2008 23:22:41 -0800> From: mika at async.caltech.edu> > > I don't think it should be possible to stop other threads if the> runtime could even conceivably support an environment where that's> not necessary. You're introducing dependencies that will lead to> (undetectable) deadlocks. People who declare their own <*EXTERNAL*>> things are, as usual, on their own.> > Mika> > Jay writes:> >> >Hm. How about:> > > >PROCEDURE Scheduler.DoesWaitProcessYield() : BOOLEAN?> > > >?> >true for pthreads/win32/cygwin> >false for userthreads> > > >duplicated privately in sysutils to avoid depending on newer m3core> > like I did for the portable C-wrapped waitpid> > > >?> > > >That way..the other code can do whatever it already is doing,> >no need to come up with abstractions for looping with nohang,> >vs. that plus the status loophole.> > > >The older fix I put it can be shrunk.> > > >The name of this is debatable, but I think the minimal level of abstraction is> > goodness.> > > >The name is actually perhaps too..complicated..like, what does it mean?> >Who uses it? What do they do with it?> > > >It means that waiting on a process to end allows threads in the waiting proces> >s to run.> >Perhaps it is too low level.> > > > > > - Jay> >> >> >> >----------------------------------------> >> From: jay.krell at cornell.edu> >> To: m3devel at elegosoft.com> >> Date: Wed, 31 Dec 2008 05:33:22 +0000> >> Subject: [M3devel] variations of waitpid..?> >>> >>> >> variations of waitpid..> >>> >> Hey, we already have, that I put in on my initiative, months ago:> >>> >> C:\dev2\cm3.2\m3-libs\m3core\src\thread\POSIX\ThreadPosix.m3> >>> >> PROCEDURE WaitProcess (pid: int): int => >> (* ThreadPThread.m3 and ThreadPosix.m3 are the same here except ThreadPosix.> >m3 calls Pause(). *)> >> VAR> >> result: int;> >> statusM3: Uwaitpid.waitpid_status_t;> >> CONST Delay = 0.1D0;> >> BEGIN> >> LOOP> >> result := Uwaitpid.waitpid(pid, statusM3, Uwaitpid.WNOHANG);> >> IF result # 0 THEN EXIT END;> >> Pause(Delay);> >> END;> >> 0 *>> >> RETURN statusM3.w_Loophole;> >> END WaitProcess;> >>> >> pthreads and cygwin:> >>> >> C:\dev2\cm3.2\m3-libs\m3core\src\thread\WIN32\WaitProcessCygwin.m3> >> and> >> C:\dev2\cm3.2\m3-libs\m3core\src\thread\PTHREAD\ThreadPThread.m3> >>> >> PROCEDURE WaitProcess (pid: int): int => >> (* ThreadPThread.m3 and ThreadPosix.m3 are very similar. *)> >> VAR> >> statusM3: Uwaitpid.waitpid_status_t;> >> BEGIN> >> LOOP> >> WITH r = Uwaitpid.waitpid(pid, statusM3) DO> >> IF r> 0 THEN> >> RETURN statusM3.w_Loophole;> >> END;> >> < 0*>> >> END;> >>> >> END;> >> END WaitProcess;> >>> >> win32:> >> PROCEDURE WaitProcess (pid: int): int => >> BEGIN> >>> >> RETURN 0;> >> END WaitProcess;> >>> >> ThreadPThread and WaitProcessCygwin should share code, but that's not the po> >int.> >>> >> However, now, to fix sysutils, we need something LIKE:> >>> >> UNSAFE INTERFACE SystemPosixWaitPid;> >> FROM Ctypes IMPORT int;> >> FROM Sysutils_Uwaitpid IMPORT waitpid_status_t;> >> FROM Utypes IMPORT pid_t;> >>> >> PROCEDURE WaitPid(pid: pid_t; VAR status: waitpid_status_t): int;> >>> >> BEGIN> >> END SystemPosixWaitPid.> >>> >> pthreads:> >>> >> UNSAFE MODULE SystemPosixWaitPidEfficient EXPORTS SystemPosixWaitPid;> >>> >> FROM Ctypes IMPORT int;> >> FROM Sysutils_Uwaitpid IMPORT waitpid_status_t, waitpid;> >> FROM Utypes IMPORT pid_t;> >>> >> PROCEDURE WaitPid(pid: pid_t; VAR status: waitpid_status_t): int => >> BEGIN> >> RETURN waitpid(pid, status, 0);> >> END WaitPid;> >>> >> BEGIN> >> END SystemPosixWaitPidEfficient.> >>> >> user threads:> >>> >> UNSAFE MODULE SystemPosixWaitPidPause EXPORTS SystemPosixWaitPid;> >>> >> FROM Ctypes IMPORT int;> >> FROM Sysutils_Uwaitpid IMPORT waitpid_status_t, waitpid;> >> FROM Utypes IMPORT pid_t;> >>> >> PROCEDURE WaitPid(pid: pid_t; VAR status: waitpid_status_t): int => >> VAR result: int;> >> CONST Delay = 0.1D0;> >> BEGIN> >> LOOP> >> result := waitpid(pid, status, Sysutils_Uwaitpid.WNOHANG);> >> IF result # 0 THEN> >> EXIT> >> END;> >> Thread.Pause(Delay)> >> END;> >> END WaitPid;> >>> >> BEGIN> >> END SystemPosixWaitPidPause.> >>> >> questions:> >>> >> Aside: Where do I put "unsafe"?> >>> >> Relevant: Sysutils has to implement this itself, right?> >> Due to bootstrapping concerns.> >>> >> But we should still put /something/ in m3core, right?> >>> >> So then the big question, what to call it?> >>> >> Probably, the existing WaitProcess that does more than this WaitPid, should > >be scaled> >> back and only do what WaitPid does?> >>> >> I will likely commit exactly what is shown above.> >> The new interface and modules are in sysutils. The interface is private.> >>> >> The unfinished part is putting something in m3core, that sysutils could use,> > if> >> not for boostrapping issuers, that it could use in the future.> >>> >> I kind of thing something a bit more is needed.> >> You know, the Win32 implementation that asserts(false) is suspicious.> >> At the very least, it should be removed.> >>> >> I suspect I am missing something though, as suggested by Win32 having an ass> >ert(false) implementation.> >> Either that needs to be removed, or somehow the code can be unified, using j> >ust the existing m3core/libm3> >> interfaces?> >>> >> I also suspect part of the problem is that sysutils implements to a large ex> >tent> >> the same abstractions as m3core and/or libm3, but with variations, causing i> >t to be unable> >> to build on what is there, but having to reinvent..which suggests the m3core> >/libm3 abstractions> >> maybe are not general/featureful enough.> >>> >> (Btw, unstated above, is that sysutils/m3makefile will have the same sort of> > switch as m3core does, wrt if it builds for user/alaram threads or kernel/pth> >reads.)> >>> >>> >> ??> >>> >> - Jay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20081231/0e85dde8/attachment-0002.html>


More information about the M3devel mailing list