]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add thread control classes. (2)
authorwuyizhong <wuyizhong@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 4 Sep 2006 04:50:59 +0000 (04:50 +0000)
committerwuyizhong <wuyizhong@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 4 Sep 2006 04:50:59 +0000 (04:50 +0000)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1434 6f19259b-4bc3-4df7-8a09-765794883524

Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java [new file with mode: 0644]
Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java [new file with mode: 0644]

diff --git a/Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java b/Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java
new file mode 100644 (file)
index 0000000..416ccd1
--- /dev/null
@@ -0,0 +1,217 @@
+/** @file\r
+  This file is for single module thread definition. \r
+\r
+Copyright (c) 2006, Intel Corporation\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+package org.tianocore.build;\r
+\r
+import java.util.Hashtable;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashSet;\r
+import java.util.Set;\r
+import java.util.Vector;\r
+\r
+import org.apache.tools.ant.BuildListener;\r
+import org.apache.tools.ant.Project;\r
+import org.apache.tools.ant.taskdefs.Property;\r
+import org.tianocore.build.GenBuildTask;\r
+import org.tianocore.build.fpd.FpdParserForThread;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+\r
+/**\r
+  Add more comment here. \r
+\r
+  @since GenBuild 1.0\r
+**/\r
+public class GenBuildThread implements Runnable {\r
+\r
+    private ModuleIdentification parentModuleId = null;\r
+\r
+    private ModuleIdentification moduleId = null;\r
+\r
+    private Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();\r
+    \r
+    private int status = FpdParserForThread.STATUS_DEPENDENCY_NOT_READY;\r
+\r
+    private Project project = null;\r
+\r
+    public Object semaphore = new Object();\r
+\r
+    private String arch = null;\r
+\r
+    private boolean highPriority = false;\r
+\r
+    private Thread thread;\r
+\r
+    public GenBuildThread() {\r
+        thread = new Thread(this);\r
+    }\r
+\r
+    public boolean start() {\r
+        if (highPriority) {\r
+            thread.setPriority(Thread.MAX_PRIORITY);\r
+        }\r
+        \r
+        status = FpdParserForThread.STATUS_START_RUN;\r
+        thread.start();\r
+        return true;\r
+    }\r
+\r
+    public void run() {\r
+        \r
+        FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch);\r
+\r
+        //\r
+        // Prepare pass down properties\r
+        // ARCH, MODULE_GUID, MODULE_VERSION, PACKAGE_GUID, PACKAGE_VERSION, PLATFORM_FILE\r
+        //\r
+        Vector<Property> properties = new Vector<Property>();\r
+        Property property = new Property();\r
+        property.setName("ARCH");\r
+        property.setValue(arch);\r
+        properties.add(property);\r
+\r
+        property = new Property();\r
+        property.setName("MODULE_GUID");\r
+        property.setValue(moduleId.getGuid());\r
+        properties.add(property);\r
+\r
+        property = new Property();\r
+        property.setName("MODULE_VERSION");\r
+        if (moduleId.getVersion() == null) {\r
+            property.setValue("");\r
+        } else {\r
+            property.setValue(moduleId.getVersion());\r
+        }\r
+        properties.add(property);\r
+\r
+        property = new Property();\r
+        property.setName("PACKAGE_GUID");\r
+        property.setValue(moduleId.getPackage().getGuid());\r
+        properties.add(property);\r
+\r
+        property = new Property();\r
+        property.setName("PACKAGE_VERSION");\r
+        if (moduleId.getPackage().getVersion() == null) {\r
+            property.setValue("");\r
+        } else {\r
+            property.setValue(moduleId.getPackage().getVersion());\r
+        }\r
+        properties.add(property);\r
+\r
+        //      property = new Property();\r
+        //      property.setName("PLATFORM_FILE");\r
+        //      property.setValue(arch);\r
+        //      properties.add(property);\r
+\r
+        //\r
+        // Build the Module\r
+        //\r
+        GenBuildTask genBuildTask = new GenBuildTask();\r
+\r
+        Project newProject = new Project();\r
+\r
+        Hashtable passdownProperties = project.getProperties();\r
+        Iterator iter = passdownProperties.keySet().iterator();\r
+        while (iter.hasNext()) {\r
+            String item = (String) iter.next();\r
+            newProject.setProperty(item, (String) passdownProperties.get(item));\r
+        }\r
+\r
+        newProject.setInputHandler(project.getInputHandler());\r
+\r
+        Iterator listenerIter = project.getBuildListeners().iterator();\r
+        while (listenerIter.hasNext()) {\r
+            newProject.addBuildListener((BuildListener) listenerIter.next());\r
+        }\r
+\r
+        project.initSubProject(newProject);\r
+\r
+        genBuildTask.setProject(newProject);\r
+\r
+        genBuildTask.setExternalProperties(properties);\r
+\r
+        genBuildTask.parentId = parentModuleId;\r
+\r
+        genBuildTask.perform();\r
+\r
+        status = FpdParserForThread.STATUS_END_RUN;\r
+        \r
+        System.out.println(fpdModuleId + " build finished. ");\r
+        \r
+        //\r
+        // \r
+        //\r
+        synchronized (FpdParserForThread.deamonSemaphore) {\r
+            FpdParserForThread.subCount();\r
+            FpdParserForThread.deamonSemaphore.notifyAll();\r
+        }\r
+    }\r
+\r
+    public void setArch(String arch) {\r
+        this.arch = arch;\r
+    }\r
+\r
+    public void setDependencies(Set<FpdModuleIdentification> dependencies) {\r
+        this.dependencies = dependencies;\r
+    }\r
+\r
+    public void setModuleId(ModuleIdentification moduleId) {\r
+        this.moduleId = moduleId;\r
+    }\r
+\r
+    public void setParentModuleId(ModuleIdentification parentModuleId) {\r
+        this.parentModuleId = parentModuleId;\r
+    }\r
+\r
+    public void setProject(Project project) {\r
+        this.project = project;\r
+    }\r
+\r
+    public void setHighPriority(boolean highPriority) {\r
+        this.highPriority = highPriority;\r
+    }\r
+\r
+\r
+    public Set<FpdModuleIdentification> getDependencies() {\r
+        return dependencies;\r
+    }\r
+\r
+    public ModuleIdentification getModuleId() {\r
+        return moduleId;\r
+    }\r
+\r
+    public int getStatus() {\r
+        //\r
+        // Add code here to judge dependency\r
+        //\r
+        if (status == FpdParserForThread.STATUS_DEPENDENCY_NOT_READY) {\r
+            Iterator<FpdModuleIdentification> iter = dependencies.iterator();\r
+            boolean flag = true;\r
+            while (iter.hasNext()) {\r
+                FpdModuleIdentification item = iter.next();\r
+                if (FpdParserForThread.allThreads.get(item).getStatus() == 1) {\r
+                    flag = false;\r
+                    break ;\r
+                }\r
+            }\r
+            if (flag) {\r
+                status = FpdParserForThread.STATUS_DEPENDENCY_READY;\r
+            }\r
+        }\r
+        return status;\r
+    }\r
+\r
+    public void setStatus(int status) {\r
+        this.status = status;\r
+    }\r
+    \r
+}\r
diff --git a/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java
new file mode 100644 (file)
index 0000000..b16530b
--- /dev/null
@@ -0,0 +1,399 @@
+/** @file\r
+ This file is ANT task FpdParserTask. \r
\r
+ FpdParserTask is used to parse FPD (Framework Platform Description) and generate\r
+ build.out.xml. It is for Package or Platform build use. \r
\r
+ Copyright (c) 2006, Intel Corporation\r
+ All rights reserved. This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution.  The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ **/\r
+package org.tianocore.build.fpd;\r
+\r
+import java.io.File;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.LinkedHashMap;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.apache.tools.ant.BuildException;\r
+import org.apache.tools.ant.taskdefs.Ant;\r
+import org.apache.xmlbeans.XmlObject;\r
+\r
+import org.tianocore.build.global.GlobalData;\r
+import org.tianocore.build.global.OutputManager;\r
+import org.tianocore.build.id.FpdModuleIdentification;\r
+import org.tianocore.build.id.ModuleIdentification;\r
+import org.tianocore.build.FrameworkBuildTask;\r
+import org.tianocore.build.GenBuildThread;\r
+import org.tianocore.common.exception.EdkException;\r
+\r
+/**\r
+  <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework\r
+  Platform Descritpion (FPD) XML file and generating its ANT build script for \r
+  corresponding platform.  \r
+\r
+  <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR\r
+  and BUILD_DIR. </p>\r
+  \r
+  <p>The task generates ${PLATFORM}_build.xml file which will be called by top level\r
+  build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage) \r
+  and flash definition file (File is for Tool FlashMap) if necessary. </p>\r
+  \r
+  <p>FpdParserTask task stores all FPD information to GlobalData. And parse\r
+  tools definition file to set up compiler options for different Target and\r
+  different ToolChainTag. </p>\r
+  \r
+  <p>The method parseFpdFile is also prepared for single module build. </p>\r
+  \r
+  <p>The usage is (take NT32 Platform for example):</p>\r
+\r
+  <pre>\r
+  &lt;FPDParser platformName="Nt32" /&gt;\r
+  </pre>\r
+\r
+  <p>The task will initialize all information through parsing Framework Database, \r
+  SPD, Tool chain configuration files. </p>\r
+\r
+  @since GenBuild 1.0\r
+**/\r
+public class FpdParserForThread extends FpdParserTask {\r
+    \r
+    public static Map<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();\r
+    \r
+    List<String> queueList = new ArrayList<String>();\r
+    \r
+    public static Object deamonSemaphore =  new Object();\r
+    \r
+    static Object countSemaphore =  new Object();\r
+    \r
+    public static int STATUS_DEPENDENCY_NOT_READY = 1;\r
+    \r
+    public static int STATUS_DEPENDENCY_READY = 2;\r
+    \r
+    public static int STATUS_START_RUN = 3;\r
+    \r
+    public static int STATUS_END_RUN = 4;\r
+    \r
+    private int currentQueueCode = 0;\r
+    \r
+    public static int currentRunNumber = 0;\r
+    \r
+    /**\r
+      Public construct method. It is necessary for ANT task.\r
+    **/\r
+    public FpdParserForThread() {\r
+    }\r
+\r
+    /**\r
+     ANT task's entry method. The main steps is described as following: \r
+     \r
+     <ul>\r
+     <li>Initialize global information (Framework DB, SPD files and all MSA files \r
+     listed in SPD). This step will execute only once in whole build process;</li>\r
+     <li>Parse specified FPD file; </li>\r
+     <li>Generate FV.inf files; </li>\r
+     <li>Generate PlatformName_build.xml file for Flatform build; </li>\r
+     <li>Collect PCD information. </li>\r
+     </ul>\r
+     \r
+     @throws BuildException\r
+     Surface area is not valid. \r
+    **/\r
+    public void execute() throws BuildException {\r
+        //\r
+        // Parse FPD file\r
+        //\r
+        parseFpdFile();\r
+\r
+        //\r
+        // Prepare BUILD_DIR\r
+        //\r
+        isUnified = OutputManager.getInstance().prepareBuildDir(getProject());\r
+\r
+        //\r
+        // For every Target and ToolChain\r
+        //\r
+        String[] targetList = GlobalData.getToolChainInfo().getTargets();\r
+        for (int i = 0; i < targetList.length; i++) {\r
+            String[] toolchainList = GlobalData.getToolChainInfo().getTagnames();\r
+            for(int j = 0; j < toolchainList.length; j++) {\r
+                //\r
+                // Prepare FV_DIR\r
+                //\r
+                String ffsCommonDir = getProject().getProperty("BUILD_DIR") + File.separatorChar\r
+                                + targetList[i] + File.separatorChar\r
+                                + toolchainList[j];\r
+                File fvDir = new File(ffsCommonDir + File.separatorChar + "FV");\r
+                fvDir.mkdirs();\r
+                getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/"));\r
+\r
+                //\r
+                // Gen Fv.inf files\r
+                //\r
+                genFvInfFiles(ffsCommonDir);\r
+            }\r
+        }\r
+\r
+        //\r
+        // Gen build.xml\r
+        //\r
+        PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq);\r
+        fileGenerator.genBuildFile();\r
+        \r
+        //\r
+        // Prepare Queue\r
+        //\r
+        queueList.add("libqueue");\r
+        \r
+        String[] validFv = saq.getFpdValidImageNames();\r
+        \r
+        for (int i = 0; i < validFv.length; i++) {\r
+            queueList.add(validFv[i]);\r
+        }\r
+        \r
+        Iterator<String> fvsNameIter = fvs.keySet().iterator();\r
+        \r
+        while (fvsNameIter.hasNext()) {\r
+            String fvName = fvsNameIter.next();\r
+            if (!isContain(validFv, fvName)) {\r
+                queueList.add(fvName);\r
+            }\r
+        }\r
+        \r
+        //\r
+        // Ant call ${PLATFORM}_build.xml\r
+        //\r
+        Ant ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml");\r
+        ant.setTarget("prebuild");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+        \r
+        System.out.println("Task number is " + allThreads.size());\r
+        \r
+        //\r
+        // Waiting for all thread over, or time out\r
+        //\r
+        synchronized (deamonSemaphore) {\r
+            //\r
+            // Initialize BUGBUG\r
+            //\r
+            \r
+            while (true) {\r
+                //\r
+                // If all modules are already built\r
+                //\r
+                if (currentQueueCode >= queueList.size()) {\r
+                    break ;\r
+                }\r
+\r
+                Set<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));\r
+                \r
+                if (currentQueueModules == null) {\r
+                    ++currentQueueCode;\r
+                    continue ;\r
+                }\r
+                Iterator<FpdModuleIdentification> currentIter = currentQueueModules.iterator();\r
+\r
+                GenBuildThread a = null;\r
+\r
+                boolean existNoneReady = false;\r
+\r
+                while (currentIter.hasNext()) {\r
+                    GenBuildThread item = allThreads.get(currentIter.next()); \r
+                    if (item.getStatus() == STATUS_DEPENDENCY_NOT_READY) {\r
+                        existNoneReady = true;\r
+                    } else if (item.getStatus() == STATUS_DEPENDENCY_READY) {\r
+                        a = item;\r
+                        addCount();\r
+                        a.start();\r
+                        if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) {\r
+                            break ;\r
+                        }\r
+                    }\r
+                }\r
+\r
+                if (a != null) {\r
+                    //\r
+                    // Exist ready thread\r
+                    //\r
+                    System.out.println("## Exist ready thread");\r
+\r
+                } else if (existNoneReady && currentRunNumber == 0) {\r
+                    //\r
+                    // No active thread, but still have dependency not read thread\r
+                    //\r
+                    throw new BuildException("Found can't resolve dependencies. ");\r
+                } else if (!existNoneReady && currentRunNumber == 0) {\r
+                    //\r
+                    // Current queue build finish, move to next\r
+                    //\r
+                    System.out.println("## Current queue build finish, move to next");\r
+                    ++currentQueueCode;\r
+                    continue ;\r
+                } else {\r
+                    //\r
+                    // active thread exist, but no ready thread\r
+                    //\r
+                    System.out.println("## active thread exist, but no ready thread" + currentRunNumber);\r
+                }\r
+\r
+                try {\r
+                    deamonSemaphore.wait();\r
+                } catch (InterruptedException e) {\r
+                   e.printStackTrace();\r
+                }\r
+            }\r
+        }\r
+        \r
+        //\r
+        // call fvs, postbuild\r
+        //\r
+        ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml");\r
+        ant.setTarget("fvs");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+        \r
+        ant = new Ant();\r
+        ant.setProject(getProject());\r
+        ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml");\r
+        ant.setTarget("postbuild");\r
+        ant.setInheritAll(true);\r
+        ant.init();\r
+        ant.execute();\r
+        \r
+    }\r
+\r
+    \r
+    /**\r
+      Parse all modules listed in FPD file. \r
+    **/\r
+    void parseModuleSAFiles() throws EdkException{\r
+        \r
+        Map<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();\r
+\r
+        //\r
+        // For every Module lists in FPD file.\r
+        //\r
+        Set<FpdModuleIdentification> keys = moduleSAs.keySet();\r
+        Iterator<FpdModuleIdentification> iter = keys.iterator();\r
+        while (iter.hasNext()) {\r
+            FpdModuleIdentification fpdModuleId = iter.next();\r
+            \r
+            //\r
+            // Generate GenBuildThread\r
+            //\r
+            GenBuildThread genBuildThread = new GenBuildThread();\r
+            genBuildThread.setArch(fpdModuleId.getArch());\r
+            genBuildThread.setParentModuleId(null);\r
+            genBuildThread.setModuleId(fpdModuleId.getModule());\r
+            genBuildThread.setProject(getProject());\r
+            \r
+            Set<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();\r
+            \r
+            GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId));\r
+            \r
+            //\r
+            // Add all dependent Library Instance\r
+            //\r
+            saq.push(GlobalData.getDoc(fpdModuleId));\r
+\r
+            ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch());\r
+            saq.pop();\r
+            \r
+            for (int i = 0; i < libinstances.length; i++) {\r
+                FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch());\r
+                //\r
+                // Add to dependencies\r
+                //\r
+                dependencies.add(libFpdModuleId);\r
+                \r
+                //\r
+                // Create thread for library instances\r
+                //\r
+                GenBuildThread liBuildThread = new GenBuildThread();\r
+                liBuildThread.setArch(fpdModuleId.getArch());\r
+                liBuildThread.setParentModuleId(fpdModuleId.getModule());\r
+                liBuildThread.setModuleId(libinstances[i]);\r
+                liBuildThread.setProject(getProject());\r
+                liBuildThread.setStatus(STATUS_DEPENDENCY_READY);\r
+                liBuildThread.setHighPriority(true);\r
+                allThreads.put(libFpdModuleId, liBuildThread);\r
+                \r
+                updateFvs("libqueue", libFpdModuleId);\r
+            }\r
+            \r
+            genBuildThread.setDependencies(dependencies); \r
+//            if (dependencies.size() == 0) {\r
+                genBuildThread.setStatus(STATUS_DEPENDENCY_READY);\r
+//            }\r
+            \r
+            allThreads.put(fpdModuleId, genBuildThread);\r
+            \r
+            //\r
+            // Put fpdModuleId to the corresponding FV\r
+            //\r
+            saq.push(GlobalData.getDoc(fpdModuleId));\r
+            String fvBinding = saq.getModuleFvBindingKeyword();\r
+\r
+            fpdModuleId.setFvBinding(fvBinding);\r
+            updateFvs(fvBinding, fpdModuleId);\r
+\r
+            //\r
+            // Prepare for out put file name\r
+            //\r
+            ModuleIdentification moduleId = fpdModuleId.getModule();\r
+\r
+            String baseName = saq.getModuleOutputFileBasename();\r
+            \r
+            if (baseName == null) {\r
+                baseName = moduleId.getName();\r
+            }\r
+            outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar\r
+                         + moduleId.getGuid() + "-" + baseName\r
+                         + getSuffix(moduleId.getModuleType()));\r
+\r
+            //\r
+            // parse module build options, if any\r
+            //\r
+            GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false));\r
+            GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true));\r
+            saq.pop();\r
+        }\r
+    }\r
+    \r
+    private boolean isContain(String[] list, String item) {\r
+        for (int i = 0; i < list.length; i++) {\r
+            if (list[i].equalsIgnoreCase(item)) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+    \r
+    public synchronized static void addCount() {\r
+        synchronized (countSemaphore) {\r
+            ++currentRunNumber;\r
+        }\r
+    }\r
+    \r
+    public synchronized static void subCount() {\r
+        synchronized (countSemaphore) {\r
+            --currentRunNumber;\r
+        }\r
+    }\r
+}\r