Skip to content

Commit

Permalink
FlattenPdbs: improve performance (microsoft#511)
Browse files Browse the repository at this point in the history
## Description

FlattenPdbs generally takes anywhere from .8 to 1.5 seconds for a given
platform. This change reduces this time to .3 to .4 seconds due to the
following changes:

1. Only copy pdbs in the the OUTPUT folder. The original code did not
check what folder the pdb was in, and would copy the same pdb multiple
times due to the same file siting in OUTPUT and DEBUG folders.

2. Performs a hardlink rather than copying the file. This improves
performance as a hardlink is treated as it's own file, but points the
same physical file on disk. This means we create just the file metadata,
and don't need to copy the data the file contains. A reference counter
ensures that deleting the file in one place does not not delete the file
on disk (unless it is the last reference), so the other hardlinks are
not affected.

3. The above change also allows the code to check the ino value (a
unique identifier for a file on disk) and skip the making of a hardlink
if it is already linked. This is a small optimization as running a build
only rebuilds modules that have changed.

- [ ] Impacts functionality?
- **Functionality** - Does the change ultimately impact how firmware
functions?
- Examples: Add a new library, publish a new PPI, update an algorithm,
...
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact on an
application,
    flow, or firmware?
  - Examples: Crypto algorithm change, buffer overflow fix, parameter
    validation improvement, ...
- [ ] Breaking change?
- **Breaking change** - Will anyone consuming this change experience a
break
    in build or boot behavior?
- Examples: Add a new library class, move a module to a different repo,
call
    a function in a new library class in a pre-existing module, ...
- [ ] Includes tests?
  - **Tests** - Does the change include any explicit test code?
  - Examples: Unit tests, integration tests, robot tests, ...
- [ ] Includes documentation?
- **Documentation** - Does the change contain explicit documentation
additions
    outside direct code modifications (and comments)?
- Examples: Update readme file, add feature readme file, link to
documentation
    on an a separate Web page, ...

## How This Was Tested

1. Verified performance improvements
2. Verified non-changed files are not copied to the bdb folder
3. verified changed files are copied to the pdb folder
4. Verified files deleted in the pdb folder are replaced

## Integration Instructions

N/A
  • Loading branch information
Javagedes authored and kenlautner committed Dec 18, 2023
1 parent 857b4ed commit be49c42
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions BaseTools/Plugin/FlattenPdbs/FlattenPdbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,35 +30,36 @@
###
from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin
import logging
import shutil
import os
from pathlib import Path

# MU_CHANGE Entire File - Perf improvements
class FlattenPdbs(IUefiBuildPlugin):

def do_post_build(self, thebuilder):
#Path to Build output
BuildPath = thebuilder.env.GetValue("BUILD_OUTPUT_BASE")
build_path = Path(thebuilder.env.GetValue("BUILD_OUTPUT_BASE"))
#Path to where the PDBs will be stored
PDBpath = os.path.join(BuildPath, "PDB")

IgnorePdbs = ['vc1'] #make lower case
pdb_path = Path(build_path, "PDB")

try:
if not os.path.isdir(PDBpath):
os.mkdir(PDBpath)
except:
if not pdb_path.is_dir():
pdb_path.mkdir()
except Exception:
logging.critical("Error making PDB directory")

logging.critical("Copying PDBs to flat directory")
for dirpath, dirnames, filenames in os.walk(BuildPath):
if PDBpath in dirpath:
for file in Path(build_path).rglob("*.pdb"):
# pdb exists in DEBUG and OUTPUT directory. Same file.
pdb_out = Path(pdb_path / file.name)
if file.parent.name != "OUTPUT":
continue
# If it exists and has the same file identifier, skip it.
if pdb_out.exists() and file.stat().st_ino == pdb_out.stat().st_ino:
continue
if "vc1" in file.name.lower():
continue
for filename in filenames:
fnl = filename.strip().lower()
if(fnl.endswith(".pdb")):
if(any(e for e in IgnorePdbs if e in fnl)):
# too much info. logging.debug("Flatten PDB - Ignore Pdb: %s" % filename)
pass
else:
shutil.copy(os.path.join(dirpath, filename), os.path.join(PDBpath, filename))
return 0
# Hard link it, which is slightly faster, but mainly allows us to tell
# if the file has changed (st_ino is different)
pdb_out.unlink(missing_ok=True)
file.link_to(pdb_out) # Replace with pdb_out.hardlink_to(file) when support for python 3.9 is dropped
return 0

0 comments on commit be49c42

Please sign in to comment.