+
It sounds very easy, but it has one major drawback: it meaks the pwqfd must be
somehow registered into the eventloop, and it's not very suitable for a
-pthread_workqueue implementation.
-
-in kernel (hack-ish solution)::
- The kernel could voluntarily unpark/unblock a thread with another
- errno that would signal overcommiting. Unlike the pollable proposal,
- this doesn't require hooking in the event loop. Though it requires
- having one such thread, which may not be the case when userland has
- reached the peak number of threads it would ever want to use.
+pthread_workqueue implementation. In other words, if you can plug into the
+event-loop because it's a custom one or one that provides thread regulation
+then it's fine, if you can't (glib, libdispatch, ...) then you need a thread
+that will basically just poll() on this file-descriptor, it's really wasteful.
+
-Is this really a problem? I'm not sure. Especially since when that happens
-userland could pick a victim thread that would call `PWQR_PARK` after each
-processed job, which would allow some kind of poor man's poll.
-+
-The drawback I see in that solution is that we wake up YET ANOTHER thread at a
-moment when we're already overcommiting, which sounds counter productive.
-That's why I didn't implement that.
+NOTE: this has been implemented now, but still it looks "expensive" to hook
+for some users. So if some alternative way to be signalled could exist, it'd
+be really awesome.
in userspace::
Userspace knows how many "running" threads there are, it's easy to
already accounted for. When "waiting" is zero, if "registerd - parked"
is "High" userspace could choose to randomly try to park one thread.
+
-I think `PWQR_PARK` could use `val` to have some "probing" mode, that would
-return `0` if it wouldn't block and `-1/EWOULDBLOCK` if it would in the non
-probing mode. Userspace could maintain some global probing_mode flag, that
-would be a tristate: NONE, SLOW, AGGRESSVE.
+userspace can use non blocking read() to probe if it's overcommiting.
+
It's in NONE when userspace belives it's not necessary to probe (e.g. when the
amount of running + waiting threads isn't that large, say less than 110% of
the concurrency or any kind of similar rule).
+
It's in SLOW mode else. In slow mode each thread does a probe every 32 or 64
-jobs to mitigate the cost of the syscall. If the probe returns EWOULDBLOCK
-then the thread goes to PARK mode, and the probing_mode goes to AGGRESSVE.
+jobs to mitigate the cost of the syscall. If the probe returns '1' then ask
+for down-commiting and stay in SLOW mode, if it returns AGAIN all is fine, if
+it returns more than '1' ask for down-commiting and go to AGGRESSIVE.
+
When AGGRESSVE threads check if they must park more often and in a more
controlled fashion (every 32 or 64 jobs isn't nice because jobs can be very
long), for example based on some poor man's timer (clock_gettime(MONOTONIC)
-sounds fine). As soon as a probe returns 0 or we're in the NONE conditions,
-then the probing_mode goes back to NONE/SLOW.
+sounds fine). State transition works as for SLOW.
+
The issue I have with this is that it sounds to add quite some code in the
fastpath code, hence I dislike it a lot.
the call, as would be returned by `sysconf(_SC_NPROCESSORS_ONLN)`.
`flags`::
- a mask of flags, currently only O_CLOEXEC.
+ a mask of flags among `O_CLOEXEC`, and `O_NONBLOCK`.
+
+Available operations on the pwqr file descriptor are:
+
+`poll`, `epoll` and friends::
+ the PWQR file descriptor can be watched for POLLIN events (not POLLOUT
+ ones as it can not be written to).
+
+`read`::
+ The file returned can be read upon. The read blocks (or fails setting
+ `EAGAIN` if in non blocking mode) until the regulator believes the
+ pool is overcommitting. The buffer passed to read should be able to
+ hold an integer. When `read(3)` is successful, it writes the amount of
+ overcommiting threads (understand: the number of threads to park so
+ that the pool isn't overcommiting anymore).
RETURN VALUE
~~~~~~~~~~~~