~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/jobserver-exec

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/usr/bin/env python3
  2 # SPDX-License-Identifier: GPL-2.0+
  3 #
  4 # This determines how many parallel tasks "make" is expecting, as it is
  5 # not exposed via an special variables, reserves them all, runs a subprocess
  6 # with PARALLELISM environment variable set, and releases the jobs back again.
  7 #
  8 # https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html#POSIX-Jobserver
  9 from __future__ import print_function
 10 import os, sys, errno
 11 import subprocess
 12 
 13 # Extract and prepare jobserver file descriptors from environment.
 14 claim = 0
 15 jobs = b""
 16 try:
 17         # Fetch the make environment options.
 18         flags = os.environ['MAKEFLAGS']
 19 
 20         # Look for "--jobserver=R,W"
 21         # Note that GNU Make has used --jobserver-fds and --jobserver-auth
 22         # so this handles all of them.
 23         opts = [x for x in flags.split(" ") if x.startswith("--jobserver")]
 24 
 25         # Parse out R,W file descriptor numbers and set them nonblocking.
 26         # If the MAKEFLAGS variable contains multiple instances of the
 27         # --jobserver-auth= option, the last one is relevant.
 28         fds = opts[-1].split("=", 1)[1]
 29 
 30         # Starting with GNU Make 4.4, named pipes are used for reader and writer.
 31         # Example argument: --jobserver-auth=fifo:/tmp/GMfifo8134
 32         _, _, path = fds.partition('fifo:')
 33 
 34         if path:
 35                 reader = os.open(path, os.O_RDONLY | os.O_NONBLOCK)
 36                 writer = os.open(path, os.O_WRONLY)
 37         else:
 38                 reader, writer = [int(x) for x in fds.split(",", 1)]
 39                 # Open a private copy of reader to avoid setting nonblocking
 40                 # on an unexpecting process with the same reader fd.
 41                 reader = os.open("/proc/self/fd/%d" % (reader),
 42                                  os.O_RDONLY | os.O_NONBLOCK)
 43 
 44         # Read out as many jobserver slots as possible.
 45         while True:
 46                 try:
 47                         slot = os.read(reader, 8)
 48                         jobs += slot
 49                 except (OSError, IOError) as e:
 50                         if e.errno == errno.EWOULDBLOCK:
 51                                 # Stop at the end of the jobserver queue.
 52                                 break
 53                         # If something went wrong, give back the jobs.
 54                         if len(jobs):
 55                                 os.write(writer, jobs)
 56                         raise e
 57         # Add a bump for our caller's reserveration, since we're just going
 58         # to sit here blocked on our child.
 59         claim = len(jobs) + 1
 60 except (KeyError, IndexError, ValueError, OSError, IOError) as e:
 61         # Any missing environment strings or bad fds should result in just
 62         # not being parallel.
 63         pass
 64 
 65 # We can only claim parallelism if there was a jobserver (i.e. a top-level
 66 # "-jN" argument) and there were no other failures. Otherwise leave out the
 67 # environment variable and let the child figure out what is best.
 68 if claim > 0:
 69         os.environ['PARALLELISM'] = '%d' % (claim)
 70 
 71 rc = subprocess.call(sys.argv[1:])
 72 
 73 # Return all the reserved slots.
 74 if len(jobs):
 75         os.write(writer, jobs)
 76 
 77 sys.exit(rc)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php