diff options
author | wuyizhong <wuyizhong@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-09-04 04:50:59 +0000 |
---|---|---|
committer | wuyizhong <wuyizhong@6f19259b-4bc3-4df7-8a09-765794883524> | 2006-09-04 04:50:59 +0000 |
commit | abce9cbd99ef521ec601e2525bc3c92113567c3c (patch) | |
tree | fdb7dffdcc0a962c27ba25dc8f5aabe7b0528034 /Tools | |
parent | 19bf6b15d0dd0a61a0835714c09a4e707e7cd518 (diff) | |
download | edk2-platforms-abce9cbd99ef521ec601e2525bc3c92113567c3c.tar.xz |
Add thread control classes. (2)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1434 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'Tools')
-rw-r--r-- | Tools/Source/GenBuild/org/tianocore/build/GenBuildThread.java | 217 | ||||
-rw-r--r-- | Tools/Source/GenBuild/org/tianocore/build/fpd/FpdParserForThread.java | 399 |
2 files changed, 616 insertions, 0 deletions
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<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
+
+ 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<Property> properties = new Vector<Property>();
+ 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<FpdModuleIdentification> 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<FpdModuleIdentification> 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<FpdModuleIdentification> 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;
+
+/**
+ <code>FpdParserTask</code> is an ANT task. The main function is parsing Framework
+ Platform Descritpion (FPD) XML file and generating its ANT build script for
+ corresponding platform.
+
+ <p>The task sets global properties PLATFORM, PLATFORM_DIR, PLATFORM_RELATIVE_DIR
+ and BUILD_DIR. </p>
+
+ <p>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. </p>
+
+ <p>FpdParserTask task stores all FPD information to GlobalData. And parse
+ tools definition file to set up compiler options for different Target and
+ different ToolChainTag. </p>
+
+ <p>The method parseFpdFile is also prepared for single module build. </p>
+
+ <p>The usage is (take NT32 Platform for example):</p>
+
+ <pre>
+ <FPDParser platformName="Nt32" />
+ </pre>
+
+ <p>The task will initialize all information through parsing Framework Database,
+ SPD, Tool chain configuration files. </p>
+
+ @since GenBuild 1.0
+**/
+public class FpdParserForThread extends FpdParserTask {
+
+ public static Map<FpdModuleIdentification, GenBuildThread> allThreads = new LinkedHashMap<FpdModuleIdentification, GenBuildThread>();
+
+ List<String> queueList = new ArrayList<String>();
+
+ 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:
+
+ <ul>
+ <li>Initialize global information (Framework DB, SPD files and all MSA files
+ listed in SPD). This step will execute only once in whole build process;</li>
+ <li>Parse specified FPD file; </li>
+ <li>Generate FV.inf files; </li>
+ <li>Generate PlatformName_build.xml file for Flatform build; </li>
+ <li>Collect PCD information. </li>
+ </ul>
+
+ @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<String> 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<FpdModuleIdentification> currentQueueModules = fvs.get(queueList.get(currentQueueCode));
+
+ if (currentQueueModules == null) {
+ ++currentQueueCode;
+ continue ;
+ }
+ Iterator<FpdModuleIdentification> 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<FpdModuleIdentification, Map<String, XmlObject>> moduleSAs = saq.getFpdModules();
+
+ //
+ // For every Module lists in FPD file.
+ //
+ Set<FpdModuleIdentification> keys = moduleSAs.keySet();
+ Iterator<FpdModuleIdentification> 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<FpdModuleIdentification> dependencies = new LinkedHashSet<FpdModuleIdentification>();
+
+ 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;
+ }
+ }
+}
|