From abce9cbd99ef521ec601e2525bc3c92113567c3c Mon Sep 17 00:00:00 2001 From: wuyizhong Date: Mon, 4 Sep 2006 04:50:59 +0000 Subject: [PATCH] Add thread control classes. (2) git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1434 6f19259b-4bc3-4df7-8a09-765794883524 --- .../org/tianocore/build/GenBuildThread.java | 217 ++++++++++ .../build/fpd/FpdParserForThread.java | 399 ++++++++++++++++++ 2 files changed, 616 insertions(+) create mode 100644 Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java create mode 100644 Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java diff --git a/Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java b/Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java new file mode 100644 index 0000000000..416ccd1183 --- /dev/null +++ b/Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java @@ -0,0 +1,217 @@ +/** @file + This file is for single module thread definition. + +Copyright (c) 2006, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ +package org.tianocore.build; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.Vector; + +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Property; +import org.tianocore.build.GenBuildTask; +import org.tianocore.build.fpd.FpdParserForThread; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; + +/** + Add more comment here. + + @since GenBuild 1.0 +**/ +public class GenBuildThread implements Runnable { + + private ModuleIdentification parentModuleId = null; + + private ModuleIdentification moduleId = null; + + private Set dependencies = new LinkedHashSet(); + + private int status = FpdParserForThread.STATUS_DEPENDENCY_NOT_READY; + + private Project project = null; + + public Object semaphore = new Object(); + + private String arch = null; + + private boolean highPriority = false; + + private Thread thread; + + public GenBuildThread() { + thread = new Thread(this); + } + + public boolean start() { + if (highPriority) { + thread.setPriority(Thread.MAX_PRIORITY); + } + + status = FpdParserForThread.STATUS_START_RUN; + thread.start(); + return true; + } + + public void run() { + + FpdModuleIdentification fpdModuleId = new FpdModuleIdentification(moduleId, arch); + + // + // Prepare pass down properties + // ARCH, MODULE_GUID, MODULE_VERSION, PACKAGE_GUID, PACKAGE_VERSION, PLATFORM_FILE + // + Vector properties = new Vector(); + Property property = new Property(); + property.setName("ARCH"); + property.setValue(arch); + properties.add(property); + + property = new Property(); + property.setName("MODULE_GUID"); + property.setValue(moduleId.getGuid()); + properties.add(property); + + property = new Property(); + property.setName("MODULE_VERSION"); + if (moduleId.getVersion() == null) { + property.setValue(""); + } else { + property.setValue(moduleId.getVersion()); + } + properties.add(property); + + property = new Property(); + property.setName("PACKAGE_GUID"); + property.setValue(moduleId.getPackage().getGuid()); + properties.add(property); + + property = new Property(); + property.setName("PACKAGE_VERSION"); + if (moduleId.getPackage().getVersion() == null) { + property.setValue(""); + } else { + property.setValue(moduleId.getPackage().getVersion()); + } + properties.add(property); + + // property = new Property(); + // property.setName("PLATFORM_FILE"); + // property.setValue(arch); + // properties.add(property); + + // + // Build the Module + // + GenBuildTask genBuildTask = new GenBuildTask(); + + Project newProject = new Project(); + + Hashtable passdownProperties = project.getProperties(); + Iterator iter = passdownProperties.keySet().iterator(); + while (iter.hasNext()) { + String item = (String) iter.next(); + newProject.setProperty(item, (String) passdownProperties.get(item)); + } + + newProject.setInputHandler(project.getInputHandler()); + + Iterator listenerIter = project.getBuildListeners().iterator(); + while (listenerIter.hasNext()) { + newProject.addBuildListener((BuildListener) listenerIter.next()); + } + + project.initSubProject(newProject); + + genBuildTask.setProject(newProject); + + genBuildTask.setExternalProperties(properties); + + genBuildTask.parentId = parentModuleId; + + genBuildTask.perform(); + + status = FpdParserForThread.STATUS_END_RUN; + + System.out.println(fpdModuleId + " build finished. "); + + // + // + // + synchronized (FpdParserForThread.deamonSemaphore) { + FpdParserForThread.subCount(); + FpdParserForThread.deamonSemaphore.notifyAll(); + } + } + + public void setArch(String arch) { + this.arch = arch; + } + + public void setDependencies(Set dependencies) { + this.dependencies = dependencies; + } + + public void setModuleId(ModuleIdentification moduleId) { + this.moduleId = moduleId; + } + + public void setParentModuleId(ModuleIdentification parentModuleId) { + this.parentModuleId = parentModuleId; + } + + public void setProject(Project project) { + this.project = project; + } + + public void setHighPriority(boolean highPriority) { + this.highPriority = highPriority; + } + + + public Set getDependencies() { + return dependencies; + } + + public ModuleIdentification getModuleId() { + return moduleId; + } + + public int getStatus() { + // + // Add code here to judge dependency + // + if (status == FpdParserForThread.STATUS_DEPENDENCY_NOT_READY) { + Iterator iter = dependencies.iterator(); + boolean flag = true; + while (iter.hasNext()) { + FpdModuleIdentification item = iter.next(); + if (FpdParserForThread.allThreads.get(item).getStatus() == 1) { + flag = false; + break ; + } + } + if (flag) { + status = FpdParserForThread.STATUS_DEPENDENCY_READY; + } + } + return status; + } + + public void setStatus(int status) { + this.status = status; + } + +} 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 index 0000000000..b16530b59f --- /dev/null +++ b/Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java @@ -0,0 +1,399 @@ +/** @file + This file is ANT task FpdParserTask. + + FpdParserTask is used to parse FPD (Framework Platform Description) and generate + build.out.xml. It is for Package or Platform build use. + + Copyright (c) 2006, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + **/ +package org.tianocore.build.fpd; + +import java.io.File; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.Ant; +import org.apache.xmlbeans.XmlObject; + +import org.tianocore.build.global.GlobalData; +import org.tianocore.build.global.OutputManager; +import org.tianocore.build.id.FpdModuleIdentification; +import org.tianocore.build.id.ModuleIdentification; +import org.tianocore.build.FrameworkBuildTask; +import org.tianocore.build.GenBuildThread; +import org.tianocore.common.exception.EdkException; + +/** + FpdParserTask is an ANT task. The main function is parsing Framework + Platform Descritpion (FPD) XML file and generating its ANT build script for + corresponding platform. + +

The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR + and BUILD_DIR.

+ +

The task generates ${PLATFORM}_build.xml file which will be called by top level + build.xml. The task also generate Fv.inf files (File is for Tool GenFvImage) + and flash definition file (File is for Tool FlashMap) if necessary.

+ +

FpdParserTask task stores all FPD information to GlobalData. And parse + tools definition file to set up compiler options for different Target and + different ToolChainTag.

+ +

The method parseFpdFile is also prepared for single module build.

+ +

The usage is (take NT32 Platform for example):

+ +
+  <FPDParser platformName="Nt32" />
+  
+ +

The task will initialize all information through parsing Framework Database, + SPD, Tool chain configuration files.

+ + @since GenBuild 1.0 +**/ +public class FpdParserForThread extends FpdParserTask { + + public static Map allThreads = new LinkedHashMap(); + + List queueList = new ArrayList(); + + public static Object deamonSemaphore = new Object(); + + static Object countSemaphore = new Object(); + + public static int STATUS_DEPENDENCY_NOT_READY = 1; + + public static int STATUS_DEPENDENCY_READY = 2; + + public static int STATUS_START_RUN = 3; + + public static int STATUS_END_RUN = 4; + + private int currentQueueCode = 0; + + public static int currentRunNumber = 0; + + /** + Public construct method. It is necessary for ANT task. + **/ + public FpdParserForThread() { + } + + /** + ANT task's entry method. The main steps is described as following: + +
    +
  • Initialize global information (Framework DB, SPD files and all MSA files + listed in SPD). This step will execute only once in whole build process;
  • +
  • Parse specified FPD file;
  • +
  • Generate FV.inf files;
  • +
  • Generate PlatformName_build.xml file for Flatform build;
  • +
  • Collect PCD information.
  • +
+ + @throws BuildException + Surface area is not valid. + **/ + public void execute() throws BuildException { + // + // Parse FPD file + // + parseFpdFile(); + + // + // Prepare BUILD_DIR + // + isUnified = OutputManager.getInstance().prepareBuildDir(getProject()); + + // + // For every Target and ToolChain + // + String[] targetList = GlobalData.getToolChainInfo().getTargets(); + for (int i = 0; i < targetList.length; i++) { + String[] toolchainList = GlobalData.getToolChainInfo().getTagnames(); + for(int j = 0; j < toolchainList.length; j++) { + // + // Prepare FV_DIR + // + String ffsCommonDir = getProject().getProperty("BUILD_DIR") + File.separatorChar + + targetList[i] + File.separatorChar + + toolchainList[j]; + File fvDir = new File(ffsCommonDir + File.separatorChar + "FV"); + fvDir.mkdirs(); + getProject().setProperty("FV_DIR", fvDir.getPath().replaceAll("(\\\\)", "/")); + + // + // Gen Fv.inf files + // + genFvInfFiles(ffsCommonDir); + } + } + + // + // Gen build.xml + // + PlatformBuildFileGenerator fileGenerator = new PlatformBuildFileGenerator(getProject(), outfiles, fvs, isUnified, saq); + fileGenerator.genBuildFile(); + + // + // Prepare Queue + // + queueList.add("libqueue"); + + String[] validFv = saq.getFpdValidImageNames(); + + for (int i = 0; i < validFv.length; i++) { + queueList.add(validFv[i]); + } + + Iterator fvsNameIter = fvs.keySet().iterator(); + + while (fvsNameIter.hasNext()) { + String fvName = fvsNameIter.next(); + if (!isContain(validFv, fvName)) { + queueList.add(fvName); + } + } + + // + // Ant call ${PLATFORM}_build.xml + // + Ant ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml"); + ant.setTarget("prebuild"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + System.out.println("Task number is " + allThreads.size()); + + // + // Waiting for all thread over, or time out + // + synchronized (deamonSemaphore) { + // + // Initialize BUGBUG + // + + while (true) { + // + // If all modules are already built + // + if (currentQueueCode >= queueList.size()) { + break ; + } + + Set currentQueueModules = fvs.get(queueList.get(currentQueueCode)); + + if (currentQueueModules == null) { + ++currentQueueCode; + continue ; + } + Iterator currentIter = currentQueueModules.iterator(); + + GenBuildThread a = null; + + boolean existNoneReady = false; + + while (currentIter.hasNext()) { + GenBuildThread item = allThreads.get(currentIter.next()); + if (item.getStatus() == STATUS_DEPENDENCY_NOT_READY) { + existNoneReady = true; + } else if (item.getStatus() == STATUS_DEPENDENCY_READY) { + a = item; + addCount(); + a.start(); + if (currentRunNumber == FrameworkBuildTask.MAX_CONCURRENT_THREAD_NUMBER) { + break ; + } + } + } + + if (a != null) { + // + // Exist ready thread + // + System.out.println("## Exist ready thread"); + + } else if (existNoneReady && currentRunNumber == 0) { + // + // No active thread, but still have dependency not read thread + // + throw new BuildException("Found can't resolve dependencies. "); + } else if (!existNoneReady && currentRunNumber == 0) { + // + // Current queue build finish, move to next + // + System.out.println("## Current queue build finish, move to next"); + ++currentQueueCode; + continue ; + } else { + // + // active thread exist, but no ready thread + // + System.out.println("## active thread exist, but no ready thread" + currentRunNumber); + } + + try { + deamonSemaphore.wait(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + // + // call fvs, postbuild + // + ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml"); + ant.setTarget("fvs"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + ant = new Ant(); + ant.setProject(getProject()); + ant.setAntfile(platformId.getFpdFile().getParent() + File.separatorChar + platformId.getName() + "_build.xml"); + ant.setTarget("postbuild"); + ant.setInheritAll(true); + ant.init(); + ant.execute(); + + } + + + /** + Parse all modules listed in FPD file. + **/ + void parseModuleSAFiles() throws EdkException{ + + Map> moduleSAs = saq.getFpdModules(); + + // + // For every Module lists in FPD file. + // + Set keys = moduleSAs.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + FpdModuleIdentification fpdModuleId = iter.next(); + + // + // Generate GenBuildThread + // + GenBuildThread genBuildThread = new GenBuildThread(); + genBuildThread.setArch(fpdModuleId.getArch()); + genBuildThread.setParentModuleId(null); + genBuildThread.setModuleId(fpdModuleId.getModule()); + genBuildThread.setProject(getProject()); + + Set dependencies = new LinkedHashSet(); + + GlobalData.registerFpdModuleSA(fpdModuleId, moduleSAs.get(fpdModuleId)); + + // + // Add all dependent Library Instance + // + saq.push(GlobalData.getDoc(fpdModuleId)); + + ModuleIdentification[] libinstances = saq.getLibraryInstance(fpdModuleId.getArch()); + saq.pop(); + + for (int i = 0; i < libinstances.length; i++) { + FpdModuleIdentification libFpdModuleId = new FpdModuleIdentification(libinstances[i], fpdModuleId.getArch()); + // + // Add to dependencies + // + dependencies.add(libFpdModuleId); + + // + // Create thread for library instances + // + GenBuildThread liBuildThread = new GenBuildThread(); + liBuildThread.setArch(fpdModuleId.getArch()); + liBuildThread.setParentModuleId(fpdModuleId.getModule()); + liBuildThread.setModuleId(libinstances[i]); + liBuildThread.setProject(getProject()); + liBuildThread.setStatus(STATUS_DEPENDENCY_READY); + liBuildThread.setHighPriority(true); + allThreads.put(libFpdModuleId, liBuildThread); + + updateFvs("libqueue", libFpdModuleId); + } + + genBuildThread.setDependencies(dependencies); +// if (dependencies.size() == 0) { + genBuildThread.setStatus(STATUS_DEPENDENCY_READY); +// } + + allThreads.put(fpdModuleId, genBuildThread); + + // + // Put fpdModuleId to the corresponding FV + // + saq.push(GlobalData.getDoc(fpdModuleId)); + String fvBinding = saq.getModuleFvBindingKeyword(); + + fpdModuleId.setFvBinding(fvBinding); + updateFvs(fvBinding, fpdModuleId); + + // + // Prepare for out put file name + // + ModuleIdentification moduleId = fpdModuleId.getModule(); + + String baseName = saq.getModuleOutputFileBasename(); + + if (baseName == null) { + baseName = moduleId.getName(); + } + outfiles.put(fpdModuleId, fpdModuleId.getArch() + File.separatorChar + + moduleId.getGuid() + "-" + baseName + + getSuffix(moduleId.getModuleType())); + + // + // parse module build options, if any + // + GlobalData.addModuleToolChainOption(fpdModuleId, parseModuleBuildOptions(false)); + GlobalData.addModuleToolChainFamilyOption(fpdModuleId, parseModuleBuildOptions(true)); + saq.pop(); + } + } + + private boolean isContain(String[] list, String item) { + for (int i = 0; i < list.length; i++) { + if (list[i].equalsIgnoreCase(item)) { + return true; + } + } + return false; + } + + public synchronized static void addCount() { + synchronized (countSemaphore) { + ++currentRunNumber; + } + } + + public synchronized static void subCount() { + synchronized (countSemaphore) { + --currentRunNumber; + } + } +} -- 2.39.2