Commits

Anonymous committed bb4a208

add the -j argument

  • Participants
  • Parent commits 0416d3a

Comments (0)

Files changed (4)

 """scons.Job
 
 This module defines the Serial and Parallel classes that execute tasks to
-complete a build.
+complete a build. The Jobs class provides a higher level interface to start,
+stop, and wait on jobs.
 
 """
 
 __revision__ = "Job.py __REVISION__ __DATE__ __DEVELOPER__"
 
+class Jobs:
+    """An instance of this class initializes N jobs, and provides
+    methods for starting, stopping, and waiting on all N jobs.
+    """
+    
+    def __init__(self, num, taskmaster):
+        """
+        create 'num' jobs using the given taskmaster.
+
+        If 'num' is equal to 0, then a serial job will be used,
+        otherwise 'num' parallel jobs will be used.
+        """
+
+        if num > 1:
+            self.jobs = []
+            for i in range(num):
+                self.jobs.append(Parallel(taskmaster))
+        else:
+            self.jobs = [Serial(taskmaster)]
+
+    def start(self):
+        """start the jobs"""
+
+        for job in self.jobs:
+            job.start()
+
+    def wait(self):
+        """ wait for the jobs started with start() to finish"""
+
+        for job in self.jobs:
+            job.wait()
+
+    def stop(self):
+        """
+        stop the jobs started with start()
+
+        This function does not wait for the jobs to finish.
+        """
+
+        for job in self.jobs:
+            job.stop()
+    
 class Serial:
     """This class is used to execute tasks in series, and is more efficient
     than Parallel, but is only appropriate for non-parallel builds. Only

src/scons/JobTests.py

             raise NoThreadsException()
 
         taskmaster = Taskmaster(num_tasks, self)
-        jobs = []
-        for i in range(num_jobs):
-            jobs.append(scons.Job.Parallel(taskmaster))
-
-        for job in jobs:
-            job.start()
-
-        for job in jobs:
-            job.wait()
+        jobs = scons.Job.Jobs(num_jobs, taskmaster)
+        jobs.start()
+        jobs.wait()
 
         self.failUnless(not taskmaster.tasks_were_serial(),
                         "the tasks were not executed in parallel")
         "test a serial job"
 
         taskmaster = Taskmaster(num_tasks, self)
-        job = scons.Job.Serial(taskmaster)
-        job.start()
+        jobs = scons.Job.Jobs(1, taskmaster)
+        jobs.start()
+        jobs.wait()
+
         self.failUnless(taskmaster.tasks_were_serial(),
                         "the tasks were not executed in series")
         self.failUnless(taskmaster.all_tasks_are_executed(),
+#!/usr/bin/env python
+
+__revision__ = "test/t0001.py __REVISION__ __DATE__ __DEVELOPER__"
+
+from TestCmd import TestCmd
+import string
+import sys
+
+
+try:
+    import threading
+except ImportError:
+    # if threads are not supported, then
+    # there is nothing to test
+    test.pass_test()
+    sys.exit()
+
+
+test = TestCmd(program = 'scons.py',
+               workdir = '',
+               interpreter = 'python')
+
+test.write('build.py', r"""
+import time
+import sys
+file = open(sys.argv[1], 'w')
+file.write(str(time.time()) + '\n')
+time.sleep(1)
+file.write(str(time.time()))
+file.close()
+""")
+
+test.write('SConstruct', """
+MyBuild = Builder(name = "MyBuild",
+		  action = "python build.py %(target)s")
+env = Environment(BUILDERS = [MyBuild])
+env.MyBuild(target = 'f1', source = 'f1.in')
+env.MyBuild(target = 'f2', source = 'f2.in')
+""")
+
+def RunTest(args):
+    test.write('f1.in', 'f1.in')
+    test.write('f2.in', 'f2.in')
+
+    test.run(chdir = '.', arguments = args)
+
+    str = test.read("f1")
+    start1,finish1 = map(float, string.split(str, "\n"))
+
+    str = test.read("f2")
+    start2,finish2 = map(float, string.split(str, "\n"))
+
+    return start2, finish1
+
+start2, finish1 = RunTest('-j 2 f1 f2')
+
+# fail if the second file was not started
+# before the first one was finished
+test.fail_test(not (start2 < finish1))
+
+start2, finish1 = RunTest('f1 f2')
+
+# fail if the second file was started
+# before the first one was finished
+test.fail_test(start2 < finish1)
+
+test.pass_test()
+ 
+#!/usr/bin/env python
+
+__revision__ = "test/t0002.py __REVISION__ __DATE__ __DEVELOPER__"
+
+from TestCmd import TestCmd
+
+test = TestCmd(program = 'scons.py',
+               workdir = '',
+               interpreter = 'python')
+
+test.write('SConstruct', """
+env = Environment()
+env.Program(target = 'f1', source = 'f1.c')
+env.Program(target = 'f2', source = 'f2.c')
+env.Program(target = 'f3', source = 'f3.c')
+env.Program(target = 'f4', source = 'f4.c')
+""")
+
+test.write('f1.c', """
+int
+main(int argc, char *argv[])
+{
+    printf(\"f1.c\n\");
+    exit (0);
+}
+""")
+
+test.write('f2.c', """
+int
+main(int argc, char *argv[])
+{
+    printf(\"f2.c\n\");
+    exit (0);
+}
+""")
+
+
+test.write('f3.c', """
+int
+main(int argc, char *argv[])
+{
+    printf(\"f3.c\n\");
+    exit (0);
+}
+""")
+
+test.write('f4.c', """
+int
+main(int argc, char *argv[])
+{
+    printf(\"f4.c\n\");
+    exit (0);
+}
+""")
+
+
+test.run(chdir = '.', arguments = '-j 3 f1 f2 f3 f4')
+
+test.run(program = test.workpath('f1'))
+test.fail_test(test.stdout() != "f1.c\n")
+
+test.run(program = test.workpath('f2'))
+test.fail_test(test.stdout() != "f2.c\n")
+
+test.run(program = test.workpath('f3'))
+test.fail_test(test.stdout() != "f3.c\n")
+
+test.run(program = test.workpath('f4'))
+test.fail_test(test.stdout() != "f4.c\n")
+
+
+test.pass_test()