mirror of https://github.com/acidanthera/audk.git
Add thread control classes. (2)
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1434 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
19bf6b15d0
commit
abce9cbd99
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue