mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-07 11:14:53 +00:00
config_tools: refine cat widget
refine cat widget Tracked-On: #6691 Signed-off-by: Weiyi Feng <weiyix.feng@intel.com>
This commit is contained in:
parent
9f7c4b6bab
commit
342e8c05f6
@ -1,18 +1,631 @@
|
|||||||
import {dialog, invoke} from "@tauri-apps/api";
|
import {dialog, invoke} from "@tauri-apps/api";
|
||||||
import JSON2XML from "./json2xml"
|
import JSON2XML from "./json2xml"
|
||||||
import {OpenDialogOptions} from "@tauri-apps/api/dialog";
|
import {OpenDialogOptions} from "@tauri-apps/api/dialog";
|
||||||
|
import _ from "lodash";
|
||||||
|
import {vueUtils} from "@lljj/vue3-form-naive";
|
||||||
|
|
||||||
enum HistoryType {
|
function all(arr: boolean[]): boolean {
|
||||||
|
return arr.every(element => element === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function count(source, target) {
|
||||||
|
return (source.match(new RegExp(target, 'g')) || []).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
configurator: Configurator;
|
||||||
|
getSchemaData: () => any;
|
||||||
|
getCurrentScenarioData: () => any;
|
||||||
|
getBoardData: () => any;
|
||||||
|
pyodide: {
|
||||||
|
pyimport: (name: string) => { main: (...any) => any },
|
||||||
|
runPython: (code: string) => string
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum HistoryTypeEnum {
|
||||||
WorkingFolder,
|
WorkingFolder,
|
||||||
Board,
|
Board,
|
||||||
Scenario
|
Scenario
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HistoryTypeString = keyof typeof HistoryType;
|
export type HistoryTypes = keyof typeof HistoryTypeEnum;
|
||||||
|
|
||||||
|
|
||||||
|
enum PolicyTypeEnum {
|
||||||
|
Unified,
|
||||||
|
Code,
|
||||||
|
Data
|
||||||
|
}
|
||||||
|
|
||||||
|
type PolicyType = keyof typeof PolicyTypeEnum
|
||||||
|
|
||||||
|
type Policy = {
|
||||||
|
VM: string,
|
||||||
|
VCPU: number,
|
||||||
|
TYPE: PolicyType,
|
||||||
|
CLOS_MASK: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CATDBRecord = {
|
||||||
|
CACHE_LEVEL: number,
|
||||||
|
CACHE_ID: string,
|
||||||
|
META: { vmid: number },
|
||||||
|
VM: string,
|
||||||
|
VCPU: number,
|
||||||
|
TYPE: PolicyType,
|
||||||
|
CLOS_MASK: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CATUIDataObject = {
|
||||||
|
errorMsg: string,
|
||||||
|
regions: {
|
||||||
|
level: number,
|
||||||
|
id: string,
|
||||||
|
capacity_mask_length: number,
|
||||||
|
type: string,
|
||||||
|
cache_size: number,
|
||||||
|
processors: number[],
|
||||||
|
data: {
|
||||||
|
RTCore: Policy[],
|
||||||
|
Standard: Policy[],
|
||||||
|
VCAT: Policy[],
|
||||||
|
},
|
||||||
|
}[],
|
||||||
|
summary: {
|
||||||
|
[CATRegionLevel: string]: {
|
||||||
|
count: number,
|
||||||
|
[CATRegionID: string]: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type vmID = number;
|
||||||
|
|
||||||
|
class CAT {
|
||||||
|
private scenario: any;
|
||||||
|
private schemaData: any;
|
||||||
|
private CAT_REGION_INFO: any;
|
||||||
|
|
||||||
|
private switches: {
|
||||||
|
SSRAM_ENABLED: boolean,
|
||||||
|
RDT_ENABLED: boolean,
|
||||||
|
CDP_ENABLED: boolean,
|
||||||
|
VCAT_ENABLED: boolean
|
||||||
|
};
|
||||||
|
|
||||||
|
private preLaunchedVMCPUs: string[];
|
||||||
|
private serviceVM: any;
|
||||||
|
private serviceVMCPUs: string[];
|
||||||
|
|
||||||
|
public CATDB: CATDBRecord[];
|
||||||
|
private vmIDs: { [vmName: string]: vmID };
|
||||||
|
|
||||||
|
hexToRange(hexValue, maxValue) {
|
||||||
|
let str_bin = Number.parseInt(hexValue).toString(2);
|
||||||
|
let block_length = str_bin.length;
|
||||||
|
let block_enabled_length = count(str_bin, "1");
|
||||||
|
|
||||||
|
let start: number
|
||||||
|
let end: number
|
||||||
|
|
||||||
|
if (block_length > maxValue) {
|
||||||
|
if (block_enabled_length >= maxValue) {
|
||||||
|
str_bin = "1".repeat(maxValue);
|
||||||
|
} else {
|
||||||
|
str_bin = "0".repeat(maxValue - block_enabled_length) + "1".repeat(block_enabled_length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (block_length < maxValue) {
|
||||||
|
str_bin = "0".repeat(maxValue - block_length) + str_bin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start = str_bin.indexOf("1") !== -1 ? str_bin.indexOf("1") : 0;
|
||||||
|
end = start + count(str_bin, "1");
|
||||||
|
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
|
||||||
|
rangeToHex(value, max) {
|
||||||
|
let newHexValue = '0'.repeat(value[0]) + '1'.repeat(value[1] - value[0]) + '0'.repeat(max - value[1])
|
||||||
|
newHexValue = (parseInt(newHexValue, 2).toString(16))
|
||||||
|
let zeroPadding = '0'.repeat(Number.parseInt('1'.repeat(max), 2).toString(16).length - newHexValue.length)
|
||||||
|
newHexValue = '0x' + zeroPadding + newHexValue;
|
||||||
|
return newHexValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
formDataProxy(name, data = null, update = false) {
|
||||||
|
let path = {
|
||||||
|
'SSRAM_ENABLED': 'FEATURES.SSRAM.SSRAM_ENABLED',
|
||||||
|
'RDT_ENABLED': 'FEATURES.RDT.RDT_ENABLED',
|
||||||
|
'CDP_ENABLED': 'FEATURES.RDT.CDP_ENABLED',
|
||||||
|
'VCAT_ENABLED': 'FEATURES.RDT.VCAT_ENABLED',
|
||||||
|
}[name]
|
||||||
|
|
||||||
|
// check parent node exists
|
||||||
|
let oldValue = vueUtils.getPathVal(this.scenario.hv, path);
|
||||||
|
if (oldValue === undefined) {
|
||||||
|
let t = path.split('.');
|
||||||
|
let parentPath = t.splice(0, t.length - 1).join('.');
|
||||||
|
if (!vueUtils.getPathVal(this.scenario.hv, parentPath)) {
|
||||||
|
vueUtils.setPathVal(this.scenario.hv, parentPath, {});
|
||||||
|
}
|
||||||
|
// set to checkbox default value
|
||||||
|
vueUtils.setPathVal(this.scenario.hv, path, 'n');
|
||||||
|
}
|
||||||
|
// if data is not empty, set value
|
||||||
|
if (data !== null) {
|
||||||
|
vueUtils.setPathVal(this.scenario.hv, path, data)
|
||||||
|
|
||||||
|
// if data is not empty, set value as expected and update CAT_INFO
|
||||||
|
if (update) {
|
||||||
|
switch (name) {
|
||||||
|
case 'SSRAM_ENABLED':
|
||||||
|
this.formDataProxy('RDT_ENABLED', 'n');
|
||||||
|
this.formDataProxy('CDP_ENABLED', 'n');
|
||||||
|
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||||
|
break;
|
||||||
|
case 'RDT_ENABLED':
|
||||||
|
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||||
|
if (data === 'n') {
|
||||||
|
this.formDataProxy('CDP_ENABLED', 'n');
|
||||||
|
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'CDP_ENABLED':
|
||||||
|
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||||
|
if (data === 'y') {
|
||||||
|
this.formDataProxy('RDT_ENABLED', 'y');
|
||||||
|
this.formDataProxy('VCAT_ENABLED', 'n');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'VCAT_ENABLED':
|
||||||
|
this.formDataProxy('SSRAM_ENABLED', 'n');
|
||||||
|
if (data === 'y') {
|
||||||
|
this.formDataProxy('RDT_ENABLED', 'y');
|
||||||
|
this.formDataProxy('CDP_ENABLED', 'n');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let result: string;
|
||||||
|
// @ts-ignore
|
||||||
|
result = vueUtils.getPathVal(this.scenario.hv, path);
|
||||||
|
if (typeof result !== 'string') {
|
||||||
|
console.log(`Unexpected result of ${name}: `, result)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scenarioLoaded() {
|
||||||
|
// get CAT schema && scenario data
|
||||||
|
this.schemaData = window.getSchemaData();
|
||||||
|
this.scenario = window.getCurrentScenarioData();
|
||||||
|
this.vmIDs = this.getVMIDs()
|
||||||
|
// get cat scenario data
|
||||||
|
this.CATDB = this.getCATDataFromScenario();
|
||||||
|
}
|
||||||
|
|
||||||
|
getScenarioDataFromCAT() {
|
||||||
|
let CATUIData = this.getCATUIData();
|
||||||
|
let ScenarioCATData: {
|
||||||
|
CACHE_ALLOCATION: {
|
||||||
|
CACHE_ID: string,
|
||||||
|
CACHE_LEVEL: number,
|
||||||
|
POLICY: Policy[]
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
if (CATUIData.regions.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ScenarioCATData = {CACHE_ALLOCATION: []}
|
||||||
|
for (const region of CATUIData.regions) {
|
||||||
|
let policies: Policy[] = region.data.RTCore.concat(region.data.Standard, region.data.VCAT);
|
||||||
|
ScenarioCATData.CACHE_ALLOCATION.push({
|
||||||
|
CACHE_ID: region.id,
|
||||||
|
CACHE_LEVEL: region.level,
|
||||||
|
POLICY: policies
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ScenarioCATData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getCATUIData(): CATUIDataObject {
|
||||||
|
// get CAT schema && scenario && board basic data
|
||||||
|
this.schemaData = window.getSchemaData();
|
||||||
|
this.scenario = window.getCurrentScenarioData();
|
||||||
|
this.CAT_REGION_INFO = window.getBoardData().CAT_INFO;
|
||||||
|
|
||||||
|
// check scenario data is empty
|
||||||
|
// usually, this happens when user has no scenario loaded, then import a board
|
||||||
|
if (!this.scenario.hv) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get switches status from scenario
|
||||||
|
// @ts-ignore
|
||||||
|
this.switches = new Proxy({}, {
|
||||||
|
get: (target: {}, switchName: string | symbol): any => {
|
||||||
|
return this.formDataProxy(switchName) === 'y'
|
||||||
|
},
|
||||||
|
set: (target: {}, switchName: string | symbol, value: boolean): boolean => {
|
||||||
|
return this.formDataProxy(switchName, value ? 'y' : 'n', true) === 'y';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// if no CAT REGION INFO from board xml,
|
||||||
|
// means this board(or CPU) not support CAT, or all support CAT region only have one CPU core
|
||||||
|
if (this.CAT_REGION_INFO.length === 0) {
|
||||||
|
let errorMsg = 'This board(or CPU) not support CAT, or all support CAT region only have one CPU core';
|
||||||
|
console.log(errorMsg);
|
||||||
|
return {
|
||||||
|
errorMsg,
|
||||||
|
regions: [],
|
||||||
|
summary: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// correct switches and return rdt_enabled result
|
||||||
|
if (!this.correctSwitches()) {
|
||||||
|
return {
|
||||||
|
errorMsg: '',
|
||||||
|
regions: [],
|
||||||
|
summary: {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// CPU affinity data checks
|
||||||
|
// If error, only show error message
|
||||||
|
let errorMsg = this.checkCPUAffinity()
|
||||||
|
|
||||||
|
|
||||||
|
// get CPU data
|
||||||
|
this.preLaunchedVMCPUs = this.getPreLaunchedVMCPUs();
|
||||||
|
this.serviceVM = this.getServiceVM();
|
||||||
|
this.serviceVMCPUs = this.getServiceVMVCPUs()
|
||||||
|
this.vmIDs = this.getVMIDs()
|
||||||
|
|
||||||
|
|
||||||
|
let CATUIData: CATUIDataObject = {
|
||||||
|
errorMsg, regions: [], summary: {}
|
||||||
|
};
|
||||||
|
// mapping CAT region info
|
||||||
|
this.CAT_REGION_INFO.map(region => {
|
||||||
|
let regionData = _.cloneDeep(region);
|
||||||
|
if (!CATUIData.summary.hasOwnProperty(regionData.level)) {
|
||||||
|
CATUIData.summary[regionData.level] = {count: 0}
|
||||||
|
}
|
||||||
|
CATUIData.summary[regionData.level].count++;
|
||||||
|
CATUIData.summary[regionData.level][regionData.id] = CATUIData.summary[regionData.level].count;
|
||||||
|
|
||||||
|
regionData['data'] = {
|
||||||
|
RTCore: this.getRTCoreData(regionData),
|
||||||
|
Standard: this.getStandardData(regionData),
|
||||||
|
VCAT: this.getVCATData(regionData)
|
||||||
|
}
|
||||||
|
CATUIData.regions.push(regionData);
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return CATUIData
|
||||||
|
}
|
||||||
|
|
||||||
|
haveCPUAffinity(vmConfig) {
|
||||||
|
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
vmConfig.hasOwnProperty('cpu_affinity') &&
|
||||||
|
vmConfig.cpu_affinity.hasOwnProperty('pcpu') &&
|
||||||
|
_.isArray(vmConfig.cpu_affinity.pcpu)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCPUAffinity() {
|
||||||
|
// check cpu affinity
|
||||||
|
let errMsg = ['CPU affinity is not set for the following VMs:'];
|
||||||
|
let result = all(this.scenario.vm.map(vmConfig => {
|
||||||
|
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
let haveCPUAffinitySetting = this.haveCPUAffinity(vmConfig);
|
||||||
|
if (!haveCPUAffinitySetting) {
|
||||||
|
errMsg.push(`VM ${vmConfig.name} has no CPU affinity setting`);
|
||||||
|
}
|
||||||
|
return haveCPUAffinitySetting;
|
||||||
|
}))
|
||||||
|
if (result) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
errMsg.push('Please set CPU affinity for all VMs');
|
||||||
|
return errMsg.join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
correctSwitches() {
|
||||||
|
if (this.switches.SSRAM_ENABLED) {
|
||||||
|
if (this.switches.RDT_ENABLED) {
|
||||||
|
this.switches.RDT_ENABLED = false
|
||||||
|
}
|
||||||
|
if (this.switches.CDP_ENABLED) {
|
||||||
|
this.switches.CDP_ENABLED = false
|
||||||
|
}
|
||||||
|
if (this.switches.VCAT_ENABLED) {
|
||||||
|
this.switches.VCAT_ENABLED = false
|
||||||
|
}
|
||||||
|
} else if (this.switches.RDT_ENABLED) {
|
||||||
|
if (this.switches.CDP_ENABLED) {
|
||||||
|
if (this.switches.VCAT_ENABLED) {
|
||||||
|
this.switches.VCAT_ENABLED = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (this.switches.CDP_ENABLED || this.switches.VCAT_ENABLED) {
|
||||||
|
if (!this.switches.RDT_ENABLED) {
|
||||||
|
this.switches.RDT_ENABLED = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.switches.RDT_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreLaunchedVMCPUs() {
|
||||||
|
let preLaunchedVMCPUs = [];
|
||||||
|
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
if (vmConfig.load_order === 'PRE_LAUNCHED_VM' && this.haveCPUAffinity(vmConfig)) {
|
||||||
|
let vmCPUIDs = vmConfig.cpu_affinity.pcpu.map(pcpu => {
|
||||||
|
return pcpu.pcpu_id;
|
||||||
|
})
|
||||||
|
preLaunchedVMCPUs.concat(vmCPUIDs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return preLaunchedVMCPUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
newPolicy(CACHE_ID, CACHE_LEVEL, vmConfig, VCPU, TYPE: PolicyType, maxLength): Policy {
|
||||||
|
let originPolicy = {
|
||||||
|
VM: vmConfig.name,
|
||||||
|
VCPU, TYPE,
|
||||||
|
CLOS_MASK: this.getCLOSMask(CACHE_ID, CACHE_LEVEL, vmConfig['@id'], vmConfig.name, VCPU, TYPE, maxLength)
|
||||||
|
}
|
||||||
|
return new Proxy(originPolicy, {
|
||||||
|
set: (target, key, value) => {
|
||||||
|
target[key] = value;
|
||||||
|
if (key === 'CLOS_MASK') {
|
||||||
|
console.log(`${CACHE_ID} ${CACHE_LEVEL} ${vmConfig.name} ${VCPU} ${TYPE} CLOS_MASK: ${value}`);
|
||||||
|
this.setCLOSMask(CACHE_ID, CACHE_LEVEL, vmConfig['@id'], vmConfig.name, VCPU, TYPE, value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType) {
|
||||||
|
for (let i = 0; i < this.CATDB.length; i++) {
|
||||||
|
let CATData = this.CATDB[i];
|
||||||
|
if (
|
||||||
|
CATData.CACHE_ID === CACHE_ID && CATData.CACHE_LEVEL === CACHE_LEVEL &&
|
||||||
|
CATData.META.vmid === vmID && CATData.VCPU === VCPU && CATData.TYPE === TYPE
|
||||||
|
) {
|
||||||
|
return CATData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCLOSMask(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType, CLOS_MASK: string) {
|
||||||
|
let CATData = this.selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE);
|
||||||
|
if (CATData !== false) {
|
||||||
|
CATData.CLOS_MASK = CLOS_MASK;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.CATDB.push({
|
||||||
|
META: {vmid: vmID},
|
||||||
|
CACHE_ID, CACHE_LEVEL,
|
||||||
|
CLOS_MASK,
|
||||||
|
VM: vmName, VCPU, TYPE,
|
||||||
|
})
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getCLOSMask(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE: PolicyType, maxLength: number) {
|
||||||
|
let CATData = this.selectCATData(CACHE_ID, CACHE_LEVEL, vmID, vmName, VCPU, TYPE);
|
||||||
|
if (CATData !== false) {
|
||||||
|
let CLOS_MASK = CATData.CLOS_MASK;
|
||||||
|
// ensure CLOS_MASK length is shorter or equal to maxLength
|
||||||
|
CLOS_MASK = this.rangeToHex(this.hexToRange(CLOS_MASK, maxLength), maxLength);
|
||||||
|
return CLOS_MASK;
|
||||||
|
}
|
||||||
|
let CLOS_MASK = "0x" + parseInt('1'.repeat(maxLength), 2).toString(16)
|
||||||
|
this.CATDB.push({
|
||||||
|
META: {vmid: vmID},
|
||||||
|
CACHE_ID, CACHE_LEVEL,
|
||||||
|
CLOS_MASK,
|
||||||
|
VM: vmName, VCPU, TYPE,
|
||||||
|
})
|
||||||
|
return CLOS_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRTCoreData(regionData): Policy[] {
|
||||||
|
let RTCoreData: Policy[] = [];
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
if (this.haveCPUAffinity(vmConfig)) {
|
||||||
|
vmConfig.cpu_affinity.pcpu.map(
|
||||||
|
(pcpu, index) => {
|
||||||
|
if (
|
||||||
|
regionData.processors.indexOf(pcpu.pcpu_id) !== -1 &&
|
||||||
|
pcpu.hasOwnProperty('real_time_vcpu') &&
|
||||||
|
pcpu.real_time_vcpu === 'y'
|
||||||
|
) {
|
||||||
|
if (!this.switches.CDP_ENABLED) {
|
||||||
|
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Unified', regionData.capacity_mask_length))
|
||||||
|
} else {
|
||||||
|
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Code', regionData.capacity_mask_length))
|
||||||
|
RTCoreData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Data', regionData.capacity_mask_length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_.sortBy(RTCoreData, ['VM', 'VCPU', 'TYPE']);
|
||||||
|
|
||||||
|
return RTCoreData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getStandardData(regionData): Policy[] {
|
||||||
|
let StandardData: Policy[] = [];
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
if (this.haveCPUAffinity(vmConfig)) {
|
||||||
|
vmConfig.cpu_affinity.pcpu.map(
|
||||||
|
(pcpu, index) => {
|
||||||
|
if (
|
||||||
|
regionData.processors.indexOf(pcpu.pcpu_id) !== -1 && (
|
||||||
|
!pcpu.hasOwnProperty('real_time_vcpu') ||
|
||||||
|
pcpu.real_time_vcpu === 'n'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (!this.switches.CDP_ENABLED) {
|
||||||
|
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, 'Unified', regionData.capacity_mask_length))
|
||||||
|
} else {
|
||||||
|
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, "Code", regionData.capacity_mask_length))
|
||||||
|
StandardData.push(this.newPolicy(regionData.level, regionData.id, vmConfig, index, "Data", regionData.capacity_mask_length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// add service vm policy
|
||||||
|
StandardData = StandardData.concat(
|
||||||
|
this.getServiceData(regionData),
|
||||||
|
)
|
||||||
|
|
||||||
|
_.sortBy(StandardData, ['VM', 'VCPU', 'TYPE']);
|
||||||
|
return StandardData;
|
||||||
|
}
|
||||||
|
|
||||||
|
getServiceData(regionData): Policy[] {
|
||||||
|
let ServiceData: Policy[] = [];
|
||||||
|
|
||||||
|
this.serviceVMCPUs.map((pcpuID, index) => {
|
||||||
|
if (regionData.processors.indexOf(pcpuID) !== -1) {
|
||||||
|
if (!this.switches.CDP_ENABLED) {
|
||||||
|
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Unified", regionData.capacity_mask_length))
|
||||||
|
} else {
|
||||||
|
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Code", regionData.capacity_mask_length))
|
||||||
|
ServiceData.push(this.newPolicy(regionData.level, regionData.id, this.serviceVM, index, "Data", regionData.capacity_mask_length))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return ServiceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
getVCATData(regionData): Policy[] {
|
||||||
|
let VCATData: Policy[] = [];
|
||||||
|
// VCAT is only available for CPU 0
|
||||||
|
if (this.switches.VCAT_ENABLED && regionData.processors.indexOf(0) !== -1) {
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
if (
|
||||||
|
this.haveCPUAffinity(vmConfig) &&
|
||||||
|
vmConfig.hasOwnProperty('virtual_cat_support') &&
|
||||||
|
vmConfig.virtual_cat_support === "y"
|
||||||
|
) {
|
||||||
|
VCATData.push(
|
||||||
|
this.newPolicy(regionData.level, regionData.id, vmConfig, 0, "Unified", vmConfig.virtual_cat_number)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_.sortBy(VCATData, ['VM']);
|
||||||
|
return VCATData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getServiceVM() {
|
||||||
|
let serviceVM = null;
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
if (vmConfig.load_order === 'SERVICE_VM') {
|
||||||
|
serviceVM = vmConfig;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return serviceVM;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getServiceVMVCPUs() {
|
||||||
|
let serviceVMCPUs = [];
|
||||||
|
if (this.serviceVM !== null) {
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
this.schemaData.HV.BasicConfigType.definitions.CPUAffinityConfiguration.properties.pcpu_id.enum.map((pcpu_id) => {
|
||||||
|
// if pcpu_id in preLaunchedVMCPUIDs, it's used by pre launched vm, we need skip it
|
||||||
|
if (this.preLaunchedVMCPUs.indexOf(pcpu_id) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
serviceVMCPUs.push(pcpu_id);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return serviceVMCPUs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private getCATDataFromScenario() {
|
||||||
|
let hv = this.scenario.hv;
|
||||||
|
let scenarioCATData: CATDBRecord[] = []
|
||||||
|
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
if (
|
||||||
|
hv !== null &&
|
||||||
|
hv.hasOwnProperty('CACHE_ALLOCATION') &&
|
||||||
|
_.isArray(hv.CACHE_ALLOCATION)
|
||||||
|
) {
|
||||||
|
// noinspection JSUnresolvedVariable
|
||||||
|
hv.CACHE_ALLOCATION.map((cache_region) => {
|
||||||
|
if (
|
||||||
|
cache_region.hasOwnProperty('POLICY') &&
|
||||||
|
cache_region.POLICY.length > 0
|
||||||
|
) {
|
||||||
|
cache_region.POLICY.map(policy => {
|
||||||
|
scenarioCATData.push({
|
||||||
|
CACHE_ID: cache_region.id,
|
||||||
|
CACHE_LEVEL: cache_region.level,
|
||||||
|
CLOS_MASK: policy.CLOS_MASK,
|
||||||
|
META: {vmid: this.vmIDs[policy.VM]},
|
||||||
|
TYPE: policy.TYPE,
|
||||||
|
VCPU: policy.VCPU,
|
||||||
|
VM: policy.VM
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return scenarioCATData
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVMIDs(): { [vmName: string]: vmID } {
|
||||||
|
let vmIDs = {}
|
||||||
|
this.scenario.vm.map(vmConfig => {
|
||||||
|
vmIDs[vmConfig.name] = vmConfig['@id']
|
||||||
|
})
|
||||||
|
return vmIDs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PythonObject {
|
class PythonObject {
|
||||||
api(scriptName, output_format, ...params) {
|
api(scriptName, output_format, ...params) {
|
||||||
// @ts-ignore
|
|
||||||
let pythonFunction = window.pyodide.pyimport(`configurator.pyodide.${scriptName}`);
|
let pythonFunction = window.pyodide.pyimport(`configurator.pyodide.${scriptName}`);
|
||||||
let result = pythonFunction.main(...params);
|
let result = pythonFunction.main(...params);
|
||||||
if (output_format === 'json') {
|
if (output_format === 'json') {
|
||||||
@ -54,12 +667,14 @@ class PythonObject {
|
|||||||
|
|
||||||
class Configurator {
|
class Configurator {
|
||||||
public pythonObject: PythonObject;
|
public pythonObject: PythonObject;
|
||||||
|
public cat: CAT;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pythonObject = new PythonObject()
|
this.pythonObject = new PythonObject()
|
||||||
|
this.cat = new CAT()
|
||||||
}
|
}
|
||||||
|
|
||||||
getHistory(historyType: HistoryTypeString): Promise<String[] | []> {
|
getHistory(historyType: HistoryTypes): Promise<String[] | []> {
|
||||||
return invoke("get_history", {historyType})
|
return invoke("get_history", {historyType})
|
||||||
.then((historyJsonText) => {
|
.then((historyJsonText) => {
|
||||||
if (typeof historyJsonText === "string") {
|
if (typeof historyJsonText === "string") {
|
||||||
@ -69,7 +684,7 @@ class Configurator {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
addHistory(historyType: HistoryTypeString, historyPath: String) {
|
addHistory(historyType: HistoryTypes, historyPath: string) {
|
||||||
return invoke("add_history", {historyType, historyPath})
|
return invoke("add_history", {historyType, historyPath})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,44 +692,43 @@ class Configurator {
|
|||||||
return dialog.open(options)
|
return dialog.open(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
readFile(filePath: String): Promise<String> {
|
readFile(filePath: string): Promise<String> {
|
||||||
return invoke("acrn_read", {filePath})
|
return invoke("acrn_read", {filePath})
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFile(filePath: String, contents: String) {
|
writeFile(filePath: string, contents: string) {
|
||||||
return invoke("acrn_write", {filePath, contents})
|
return invoke("acrn_write", {filePath, contents})
|
||||||
}
|
}
|
||||||
|
|
||||||
isFile(filePath: String): Promise<Boolean> {
|
isFile(filePath: string): Promise<Boolean> {
|
||||||
return invoke("acrn_is_file", {path: filePath})
|
return invoke("acrn_is_file", {path: filePath})
|
||||||
}
|
}
|
||||||
|
|
||||||
readDir(path: String, recursive: Boolean) {
|
readDir(path: string, recursive: Boolean) {
|
||||||
return invoke('acrn_read_dir', {path, recursive})
|
return invoke('acrn_read_dir', {path, recursive})
|
||||||
}
|
}
|
||||||
|
|
||||||
creatDir(path: String, recursive = true) {
|
creatDir(path: string, recursive = true) {
|
||||||
return invoke('acrn_create_dir', {path, recursive})
|
return invoke('acrn_create_dir', {path, recursive})
|
||||||
}
|
}
|
||||||
|
|
||||||
removeDir(path: String) {
|
removeDir(path: string) {
|
||||||
return invoke('acrn_remove_dir', {path})
|
return invoke('acrn_remove_dir', {path})
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFile(path: String) {
|
removeFile(path: string) {
|
||||||
return invoke('acrn_remove_file', {path})
|
return invoke('acrn_remove_file', {path})
|
||||||
}
|
}
|
||||||
|
|
||||||
runPython(code: String, isJSON = false): String | Object {
|
runPython(code: string, isJSON = false): string | Object {
|
||||||
// @ts-ignore
|
let result = window.pyodide.runPython(code);
|
||||||
let result = window.pydoide.runPython(code);
|
|
||||||
if (isJSON) {
|
if (isJSON) {
|
||||||
result = JSON.parse(result)
|
result = JSON.parse(result)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBoard(path: String) {
|
loadBoard(path: string) {
|
||||||
return this.readFile(path)
|
return this.readFile(path)
|
||||||
.then((fileContent) => {
|
.then((fileContent) => {
|
||||||
let syntactical_errors = this.pythonObject.validateBoardStructure(fileContent);
|
let syntactical_errors = this.pythonObject.validateBoardStructure(fileContent);
|
||||||
@ -125,7 +739,7 @@ class Configurator {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
loadScenario(path: String): Object {
|
loadScenario(path: string): Object {
|
||||||
return this.readFile(path).then((fileContent) => {
|
return this.readFile(path).then((fileContent) => {
|
||||||
let syntactical_errors = this.pythonObject.validateScenarioStructure(fileContent);
|
let syntactical_errors = this.pythonObject.validateScenarioStructure(fileContent);
|
||||||
if (syntactical_errors !== "") {
|
if (syntactical_errors !== "") {
|
||||||
@ -174,11 +788,12 @@ class Configurator {
|
|||||||
|
|
||||||
convertScenarioToXML(scenarioData: Object) {
|
convertScenarioToXML(scenarioData: Object) {
|
||||||
let json2xml = new JSON2XML();
|
let json2xml = new JSON2XML();
|
||||||
let xml_data = json2xml.convert(scenarioData);
|
return json2xml.convert(scenarioData)
|
||||||
return xml_data
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let configurator = new Configurator()
|
let configurator = new Configurator()
|
||||||
|
|
||||||
|
window.configurator = configurator
|
||||||
export default configurator
|
export default configurator
|
||||||
|
@ -192,6 +192,7 @@ export default {
|
|||||||
this.showFlag = false;
|
this.showFlag = false;
|
||||||
this.updateCurrentFormSchema()
|
this.updateCurrentFormSchema()
|
||||||
this.updateCurrentFormData()
|
this.updateCurrentFormData()
|
||||||
|
configurator.cat.scenarioLoaded()
|
||||||
},
|
},
|
||||||
getSchemaData() {
|
getSchemaData() {
|
||||||
return this.schemas
|
return this.schemas
|
||||||
@ -438,6 +439,8 @@ export default {
|
|||||||
let totalMsg = msg.length // msg and errMsg must be same length.
|
let totalMsg = msg.length // msg and errMsg must be same length.
|
||||||
let needSaveLaunchScript = false
|
let needSaveLaunchScript = false
|
||||||
|
|
||||||
|
this.scenario.hv.CACHE_REGION = configurator.cat.getScenarioDataFromCAT()
|
||||||
|
|
||||||
let scenarioWithDefaults = this.applyScenarioDefaults(this.scenario)
|
let scenarioWithDefaults = this.applyScenarioDefaults(this.scenario)
|
||||||
let scenarioXMLData = this.scenarioToXML(scenarioWithDefaults)
|
let scenarioXMLData = this.scenarioToXML(scenarioWithDefaults)
|
||||||
this.scenario = scenarioWithDefaults
|
this.scenario = scenarioWithDefaults
|
||||||
|
@ -56,7 +56,11 @@
|
|||||||
</b-form-checkbox>
|
</b-form-checkbox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="py-4" v-for="CACHE_ALLOCATION in CAT_INFO" v-if="RDT_ENABLED==='y'">
|
<!-- begin CAT Table -->
|
||||||
|
<div class="py-3" v-if="CAT_INFO.errorMsg">
|
||||||
|
{{ CAT_INFO.errorMsg }}
|
||||||
|
</div>
|
||||||
|
<div class="py-4" v-for="CACHE_ALLOCATION in CAT_INFO.regions" v-if="RDT_ENABLED==='y'">
|
||||||
<p v-if="CACHE_ALLOCATION.level===3">
|
<p v-if="CACHE_ALLOCATION.level===3">
|
||||||
L3 Cache Allocation Technology
|
L3 Cache Allocation Technology
|
||||||
<br/>
|
<br/>
|
||||||
@ -67,7 +71,7 @@
|
|||||||
<div class="d-flex justify-content-between py-2 align-items-center">
|
<div class="d-flex justify-content-between py-2 align-items-center">
|
||||||
<text>
|
<text>
|
||||||
L{{ CACHE_ALLOCATION.level }} Cache Allocation Technology {{
|
L{{ CACHE_ALLOCATION.level }} Cache Allocation Technology {{
|
||||||
cat_level_region_sum[CACHE_ALLOCATION.level].count > 1 ? ' Module ' + cat_level_region_sum[CACHE_ALLOCATION.level][CACHE_ALLOCATION.id] : ''
|
CAT_INFO.summary[CACHE_ALLOCATION.level].count > 1 ? ' Module ' + CAT_INFO.summary[CACHE_ALLOCATION.level.toString()][CACHE_ALLOCATION.id] : ''
|
||||||
}}
|
}}
|
||||||
(requires CPU affinity to cores {{
|
(requires CPU affinity to cores {{
|
||||||
Math.min(...CACHE_ALLOCATION.processors)
|
Math.min(...CACHE_ALLOCATION.processors)
|
||||||
@ -80,14 +84,24 @@
|
|||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="leftTitle">
|
<div class="leftTitle">
|
||||||
<!--left title-->
|
<!--left title-->
|
||||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.POLICY">
|
<div style="min-height: 36px">
|
||||||
<div v-if="index===0&&CACHE_ALLOCATION.real_time_count>0">Real-time</div>
|
<!-- for align right -->
|
||||||
<div v-if="index===CACHE_ALLOCATION.real_time_count&&CACHE_ALLOCATION.cat_count>0">Standard</div>
|
</div>
|
||||||
<div v-if="index===CACHE_ALLOCATION.cat_count">Virtual CAT</div>
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.RTCore">
|
||||||
<text v-if="index<CACHE_ALLOCATION.cat_count">
|
<div v-if="index===0">Real-time</div>
|
||||||
|
<text>
|
||||||
{{ POLICY.VM }} vCPU {{ POLICY.VCPU }}{{ POLICY.TYPE === 'Unified' ? '' : "_" + POLICY.TYPE }}
|
{{ POLICY.VM }} vCPU {{ POLICY.VCPU }}{{ POLICY.TYPE === 'Unified' ? '' : "_" + POLICY.TYPE }}
|
||||||
</text>
|
</text>
|
||||||
<text v-else>
|
</div>
|
||||||
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.Standard">
|
||||||
|
<div v-if="index===0">Standard</div>
|
||||||
|
<text>
|
||||||
|
{{ POLICY.VM }} vCPU {{ POLICY.VCPU }}{{ POLICY.TYPE === 'Unified' ? '' : "_" + POLICY.TYPE }}
|
||||||
|
</text>
|
||||||
|
</div>
|
||||||
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.VCAT">
|
||||||
|
<div v-if="index===0">Virtual CAT</div>
|
||||||
|
<text>
|
||||||
{{ POLICY.VM }}
|
{{ POLICY.VM }}
|
||||||
</text>
|
</text>
|
||||||
</div>
|
</div>
|
||||||
@ -103,14 +117,30 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<!--right table-->
|
<!--right table-->
|
||||||
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.POLICY">
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.RTCore">
|
||||||
<div class="policyDisabledBlock"
|
<div class="policyDisabledBlock"
|
||||||
v-if="index===CACHE_ALLOCATION.real_time_count && CACHE_ALLOCATION.real_time_count>0"></div>
|
v-if="index===0"></div>
|
||||||
<div class="policyDisabledBlock"
|
|
||||||
v-if="index===CACHE_ALLOCATION.cat_count && CACHE_ALLOCATION.cat_count>0"></div>
|
|
||||||
<HexBlockRangeSelector
|
<HexBlockRangeSelector
|
||||||
v-model="POLICY.CLOS_MASK"
|
v-model="POLICY.CLOS_MASK"
|
||||||
:isVcat="index>=CACHE_ALLOCATION.cat_count"
|
:isVcat="false"
|
||||||
|
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.Standard">
|
||||||
|
<div class="policyDisabledBlock"
|
||||||
|
v-if="index===0"></div>
|
||||||
|
<HexBlockRangeSelector
|
||||||
|
v-model="POLICY.CLOS_MASK"
|
||||||
|
:isVcat="false"
|
||||||
|
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-for="(POLICY,index) in CACHE_ALLOCATION.data.VCAT">
|
||||||
|
<div class="policyDisabledBlock"
|
||||||
|
v-if="index===0"></div>
|
||||||
|
<HexBlockRangeSelector
|
||||||
|
v-model="POLICY.CLOS_MASK"
|
||||||
|
:isVcat="true"
|
||||||
:max="CACHE_ALLOCATION.capacity_mask_length"
|
:max="CACHE_ALLOCATION.capacity_mask_length"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -130,6 +160,7 @@ import _ from "lodash";
|
|||||||
import {vueUtils, fieldProps} from "@lljj/vue3-form-naive";
|
import {vueUtils, fieldProps} from "@lljj/vue3-form-naive";
|
||||||
import HexBlockRangeSelector from "./CAT/HexBlockRangeSelector.vue";
|
import HexBlockRangeSelector from "./CAT/HexBlockRangeSelector.vue";
|
||||||
import IconInfo from '@lljj/vjsf-utils/icons/IconInfo.vue';
|
import IconInfo from '@lljj/vjsf-utils/icons/IconInfo.vue';
|
||||||
|
import configurator from "../../../../lib/acrn";
|
||||||
|
|
||||||
function count(source, target) {
|
function count(source, target) {
|
||||||
return (source.match(new RegExp(target, 'g')) || []).length;
|
return (source.match(new RegExp(target, 'g')) || []).length;
|
||||||
@ -185,29 +216,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
CAT_INFO: {
|
|
||||||
handler(newValue, _) {
|
|
||||||
if (newValue === null) {
|
|
||||||
// set formData CACHE_REGION to null
|
|
||||||
vueUtils.setPathVal(this.rootFormData, this.curNodePath, newValue)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let data = [];
|
|
||||||
for (let i = 0; i < newValue.length; i++) {
|
|
||||||
data.push(newValue[i].data)
|
|
||||||
}
|
|
||||||
// set formData CACHE_REGION.CACHE_ALLOCATION to data
|
|
||||||
let CACHE_REGION = {CACHE_ALLOCATION: data}
|
|
||||||
vueUtils.setPathVal(this.rootFormData, this.curNodePath, CACHE_REGION)
|
|
||||||
},
|
|
||||||
deep: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
CAT_INFO: null,
|
CAT_INFO: {errorMsg: null, regions: [], summary: {}},
|
||||||
cat_level_region_sum: {},
|
|
||||||
SSRAMInfo: this.rootSchema.definitions['SSRAMInfo'],
|
SSRAMInfo: this.rootSchema.definitions['SSRAMInfo'],
|
||||||
RDTType: this.rootSchema.definitions['RDTType']
|
RDTType: this.rootSchema.definitions['RDTType']
|
||||||
}
|
}
|
||||||
@ -302,414 +313,28 @@ export default {
|
|||||||
return vueUtils.getPathVal(this.rootFormData, path)
|
return vueUtils.getPathVal(this.rootFormData, path)
|
||||||
},
|
},
|
||||||
setDefaultClosMask(CACHE_REGION) {
|
setDefaultClosMask(CACHE_REGION) {
|
||||||
if (CACHE_REGION.capacity_mask_length < (CACHE_REGION.real_time_count + 1)) {
|
if (CACHE_REGION.data.RTCore.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (CACHE_REGION.capacity_mask_length < (CACHE_REGION.data.RTCore.length + 1)) {
|
||||||
alert('Can\'t generate default settings for this region(due to too many realtime cpu)')
|
alert('Can\'t generate default settings for this region(due to too many realtime cpu)')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.POLICY.length; policyIndex++) {
|
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.RTCore.length; policyIndex++) {
|
||||||
if (policyIndex < CACHE_REGION.real_time_count) {
|
CACHE_REGION.data.RTCore[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||||
// noinspection JSUnresolvedVariable
|
'0'.repeat(policyIndex) + '1' + '0'.repeat(CACHE_REGION.capacity_mask_length - policyIndex - 1),
|
||||||
CACHE_REGION.data.POLICY[policyIndex].CLOS_MASK = '0x' + parseInt(
|
2).toString(16)
|
||||||
'0'.repeat(policyIndex) + '1' + '0'.repeat(CACHE_REGION.capacity_mask_length - policyIndex - 1),
|
}
|
||||||
2).toString(16)
|
|
||||||
} else {
|
for (let policyIndex = 0; policyIndex < CACHE_REGION.data.Standard.length; policyIndex++) {
|
||||||
// noinspection JSUnresolvedVariable
|
// noinspection JSUnresolvedVariable
|
||||||
CACHE_REGION.data.POLICY[policyIndex].CLOS_MASK = '0x' + parseInt(
|
CACHE_REGION.data.Standard[policyIndex].CLOS_MASK = '0x' + parseInt(
|
||||||
'0'.repeat(CACHE_REGION.real_time_count) + '1'.repeat(CACHE_REGION.capacity_mask_length - CACHE_REGION.real_time_count),
|
'0'.repeat(CACHE_REGION.data.RTCore.length) + '1'.repeat(CACHE_REGION.capacity_mask_length - CACHE_REGION.data.RTCore.length),
|
||||||
2).toString(16)
|
2).toString(16);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
updateCatInfo() {
|
updateCatInfo() {
|
||||||
// get settings from formData
|
this.CAT_INFO = configurator.cat.getCATUIData()
|
||||||
let RDT_ENABLED = this.RDT_ENABLED === 'y'
|
|
||||||
let CDP_ENABLED = this.CDP_ENABLED === 'y'
|
|
||||||
let VCAT_ENABLED = this.VCAT_ENABLED === 'y'
|
|
||||||
|
|
||||||
if (!RDT_ENABLED) {
|
|
||||||
// keep CAT_INFO
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// get vmConfig from formData
|
|
||||||
// let getCPUAffinity = () => {
|
|
||||||
// // vmName: {pcpu_id:0, vcpu_id:0, isRT:false}
|
|
||||||
// let vmCpuAffinity = {};
|
|
||||||
// window.getCurrentScenarioData().vm.map((vmConfig) => {
|
|
||||||
// // if this vm is service vm, skip it
|
|
||||||
// if (vmConfig.load_order === 'SERVICE_VM') {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
let getCurrentFormDataCPUAffinitySettings = () => {
|
|
||||||
/**
|
|
||||||
* let vCatsExample = [
|
|
||||||
* // VCPU is force set to 0
|
|
||||||
* // CLOS_MASK is force set to width of capacity_mask_length (for vcat only)
|
|
||||||
* {"VM": "VM_C", "VCPU": 0, "CLOS_MASK": 2},
|
|
||||||
* {"VM": "VM_D", "VCPU": 0, "CLOS_MASK": 5},
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
let vCats = []
|
|
||||||
/**
|
|
||||||
* get pcpu config from current formData
|
|
||||||
* let pcpu_vms_example = {
|
|
||||||
* 0: {
|
|
||||||
* 'y': [],
|
|
||||||
* 'n': [
|
|
||||||
* {"VM": "POST_VM_1", "VCPU": 0},
|
|
||||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
|
||||||
* ]
|
|
||||||
* },
|
|
||||||
* 1: {
|
|
||||||
* 'y': [
|
|
||||||
* {"VM": "POST_VM_1", "VCPU": 1}
|
|
||||||
* ],
|
|
||||||
* 'n': [
|
|
||||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let pcpu_vms = {}
|
|
||||||
let serviceVM = null;
|
|
||||||
let preLaunchedVMCPUIDs = [];
|
|
||||||
|
|
||||||
window.getCurrentScenarioData().vm.map((vmConfig) => {
|
|
||||||
// if this vm is service vm, we got it and skip it
|
|
||||||
if (vmConfig.load_order === 'SERVICE_VM') {
|
|
||||||
serviceVM = vmConfig;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// no cpu affinity, skip it
|
|
||||||
if (
|
|
||||||
!vmConfig.hasOwnProperty('cpu_affinity') ||
|
|
||||||
!vmConfig.cpu_affinity.hasOwnProperty('pcpu') ||
|
|
||||||
!_.isArray(vmConfig.cpu_affinity.pcpu)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// now, we got pre/post vm config with cpu affinity data here
|
|
||||||
|
|
||||||
if (vmConfig.load_order === 'PRE_LAUNCHED_VM') {
|
|
||||||
preLaunchedVMCPUIDs = preLaunchedVMCPUIDs.concat(vmConfig.cpu_affinity.pcpu)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if vcat is enabled in hv, we need to check current vm is enabled vcat
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
if (
|
|
||||||
VCAT_ENABLED &&
|
|
||||||
vmConfig.hasOwnProperty('virtual_cat_support') &&
|
|
||||||
vmConfig.virtual_cat_support === "y"
|
|
||||||
) {
|
|
||||||
// if enabled vcat in vmConfig, add vm's vcat config to vCats
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
vCats.push({"VM": vmConfig.name, "VCPU": 0, "CLOS_MASK": vmConfig.virtual_cat_number})
|
|
||||||
// for enabled virtual_cat_support vm, it doesn't need set CAT
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get cpu affinity settings from pre/post vms which are not enabled vCAT
|
|
||||||
vmConfig.cpu_affinity.pcpu.map((pcpu, index) => {
|
|
||||||
if (!pcpu_vms.hasOwnProperty(pcpu.pcpu_id)) {
|
|
||||||
pcpu_vms[pcpu.pcpu_id] = {'y': [], 'n': []}
|
|
||||||
}
|
|
||||||
pcpu_vms[pcpu.pcpu_id][
|
|
||||||
// old scenario may not have this attr
|
|
||||||
pcpu.real_time_vcpu ?
|
|
||||||
// if it had this attr, use it
|
|
||||||
pcpu.real_time_vcpu :
|
|
||||||
// doesn't have it, auto set to no
|
|
||||||
'n'
|
|
||||||
].push({
|
|
||||||
// '@id': vmConfig['@id'],
|
|
||||||
"VM": vmConfig.name,
|
|
||||||
"VCPU": index,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// generate service vm cpu affinity setting
|
|
||||||
if (serviceVM !== null) {
|
|
||||||
let serviceVMCPUIndex = 0;
|
|
||||||
let schemaData = window.getSchemaData()
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
schemaData.HV.BasicConfigType.definitions.CPUAffinityConfiguration.properties.pcpu_id.enum.map((pcpu_id) => {
|
|
||||||
// if pcpu_id in preLaunchedVMCPUIDs, it's used by pre launched vm, we need skip it
|
|
||||||
if (preLaunchedVMCPUIDs.indexOf(pcpu_id) !== -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// noinspection JSCheckFunctionSignatures
|
|
||||||
if (!pcpu_vms.hasOwnProperty(pcpu_id)) {
|
|
||||||
pcpu_vms[pcpu_id] = {'y': [], 'n': []}
|
|
||||||
}
|
|
||||||
pcpu_vms[pcpu_id].n.push({
|
|
||||||
// '@id': serviceVM['@id'],
|
|
||||||
"VM": serviceVM.name,
|
|
||||||
"VCPU": serviceVMCPUIndex
|
|
||||||
})
|
|
||||||
serviceVMCPUIndex++;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
vCats: vCats,
|
|
||||||
pcpu_vms: pcpu_vms,
|
|
||||||
serviceVM: serviceVM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let getScenarioCATData = () => {
|
|
||||||
/**
|
|
||||||
* load data from scenario
|
|
||||||
* let scenarioHVCACHE_REGIONData_data_example = {
|
|
||||||
* "CACHE_ALLOCATION": [
|
|
||||||
* {
|
|
||||||
* "CACHE_ID": "0x8", "CACHE_LEVEL": 2, "POLICY": [
|
|
||||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "POST_RT_VM1", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "VM4-RTVM2", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "VM4-RTVM2", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
|
||||||
* ]
|
|
||||||
* },
|
|
||||||
* {
|
|
||||||
* "CACHE_ID": "0x9", "CACHE_LEVEL": 2, "POLICY": [
|
|
||||||
* {"VM": "VM5-RTVM3", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "VM5-RTVM3", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "VM6-RTVM4", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"},
|
|
||||||
* {"VM": "VM6-RTVM4", "VCPU": 1, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let scenarioHVCACHE_REGIONData = vueUtils.getPathVal(this.rootFormData, this.curNodePath);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* let scenario_cat_data_example = {
|
|
||||||
* 2: {
|
|
||||||
* '0x7': {
|
|
||||||
* "CACHE_ID": "0x7", "CACHE_LEVEL": 2, "POLICY": [
|
|
||||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
|
||||||
* ]
|
|
||||||
* },
|
|
||||||
* '0x8': {
|
|
||||||
* "CACHE_ID": "0x8", "CACHE_LEVEL": 2, "POLICY": [
|
|
||||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
* },
|
|
||||||
* 3: {
|
|
||||||
* '0x0': {}
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let scenario_cat_data = {}
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
if (
|
|
||||||
scenarioHVCACHE_REGIONData !== null &&
|
|
||||||
scenarioHVCACHE_REGIONData.hasOwnProperty('CACHE_ALLOCATION') &&
|
|
||||||
_.isArray(scenarioHVCACHE_REGIONData.CACHE_ALLOCATION)
|
|
||||||
) {
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
scenarioHVCACHE_REGIONData.CACHE_ALLOCATION.map((cache_region) => {
|
|
||||||
if (!scenario_cat_data.hasOwnProperty(cache_region['CACHE_LEVEL'])) {
|
|
||||||
scenario_cat_data[cache_region['CACHE_LEVEL']] = {}
|
|
||||||
}
|
|
||||||
scenario_cat_data[cache_region['CACHE_LEVEL']][cache_region['CACHE_ID']] = cache_region
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return scenario_cat_data
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let mergeAndGenerateData = (currentFormDataCPUAffinitySettings, scenarioCatData) => {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get CAT info from board xml
|
|
||||||
* let board_cat_info_example = [
|
|
||||||
* {
|
|
||||||
* "id": "0x0", "level": 3, "type": "3", "cache_size": 31457280, "capacity_mask_length": 12,
|
|
||||||
* "processors": [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]
|
|
||||||
* }
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* let cat_level_region_sum_example = {
|
|
||||||
* 2: {
|
|
||||||
* count: 2,
|
|
||||||
* '0x8': 1,
|
|
||||||
* '0x9': 2
|
|
||||||
* },
|
|
||||||
* 3: {
|
|
||||||
* count: 1,
|
|
||||||
* '0x0': 1
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
|
|
||||||
let scenario_cat_data = scenarioCatData
|
|
||||||
let {pcpu_vms, vCats} = currentFormDataCPUAffinitySettings;
|
|
||||||
|
|
||||||
this.cat_level_region_sum = {}
|
|
||||||
|
|
||||||
let board_cat_info = _.cloneDeep(window.getBoardData().CAT_INFO);
|
|
||||||
|
|
||||||
board_cat_info.map((
|
|
||||||
cat_region_info
|
|
||||||
) => {
|
|
||||||
|
|
||||||
// count regions for each cat level
|
|
||||||
if (!this.cat_level_region_sum.hasOwnProperty(cat_region_info.level)) {
|
|
||||||
this.cat_level_region_sum[cat_region_info.level] = {count: 0};
|
|
||||||
}
|
|
||||||
this.cat_level_region_sum[cat_region_info.level].count += 1
|
|
||||||
this.cat_level_region_sum[cat_region_info.level][cat_region_info.id] = this.cat_level_region_sum[cat_region_info.level].count;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get vm cpu clos_mask from scenario
|
|
||||||
* let vmCPUClosMasks_example = {
|
|
||||||
* 'VM_NAME': {
|
|
||||||
* // vcpu_id: {type: clos_mask}
|
|
||||||
* 0: {"Unified": '0xfff'},
|
|
||||||
* 1: {"Code": '0xff0', "Data": '0x00f'} // CDP_ENABLED
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let vmCPUClosMasks = {}
|
|
||||||
if (
|
|
||||||
scenario_cat_data.hasOwnProperty(cat_region_info.level) &&
|
|
||||||
scenario_cat_data[cat_region_info.level].hasOwnProperty(cat_region_info.id)
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* let current_region_scenario_cat_data_example = {
|
|
||||||
* "CACHE_ID": "0x7", "CACHE_LEVEL": 2, "POLICY": [
|
|
||||||
* {"VM": "POST_RT_VM1", "VCPU": 0, "TYPE": "Unified", "CLOS_MASK": "0x0fff"}
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
let current_region_scenario_cat_data = scenario_cat_data[cat_region_info.level][cat_region_info.id];
|
|
||||||
|
|
||||||
for (let i = 0; i < current_region_scenario_cat_data.POLICY.length; i++) {
|
|
||||||
let currentRegionScenarioPolicy = current_region_scenario_cat_data.POLICY[i]
|
|
||||||
if (!vmCPUClosMasks.hasOwnProperty(currentRegionScenarioPolicy.VM)) {
|
|
||||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM] = {}
|
|
||||||
}
|
|
||||||
if (!vmCPUClosMasks[currentRegionScenarioPolicy.VM].hasOwnProperty(currentRegionScenarioPolicy.VCPU)) {
|
|
||||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM][currentRegionScenarioPolicy.VCPU] = {}
|
|
||||||
}
|
|
||||||
if (["Unified", "Code", "Data"].indexOf(currentRegionScenarioPolicy.TYPE) >= 0) {
|
|
||||||
vmCPUClosMasks[currentRegionScenarioPolicy.VM][currentRegionScenarioPolicy.VCPU][currentRegionScenarioPolicy.TYPE] = currentRegionScenarioPolicy.CLOS_MASK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cat_region_info['data'] = {
|
|
||||||
"CACHE_ID": cat_region_info.id,
|
|
||||||
"CACHE_LEVEL": cat_region_info.level,
|
|
||||||
"POLICY": []
|
|
||||||
}
|
|
||||||
|
|
||||||
function addCATPolicy(cpu_policy_line, line_type, vcat_mask_length = null) {
|
|
||||||
let cpu_policy = _.cloneDeep(cpu_policy_line)
|
|
||||||
cpu_policy['TYPE'] = line_type;
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
let clos_mask = "0x" + parseInt('1'.repeat(
|
|
||||||
// if vcat_mask_length is not null
|
|
||||||
vcat_mask_length !== null ?
|
|
||||||
// filled by vcat_mask_length
|
|
||||||
vcat_mask_length :
|
|
||||||
// filled by capacity_mask_length
|
|
||||||
cat_region_info.capacity_mask_length
|
|
||||||
), 2).toString(16);
|
|
||||||
if (
|
|
||||||
vmCPUClosMasks.hasOwnProperty(cpu_policy.VM) &&
|
|
||||||
vmCPUClosMasks[cpu_policy.VM].hasOwnProperty(cpu_policy.VCPU) &&
|
|
||||||
vmCPUClosMasks[cpu_policy.VM][cpu_policy.VCPU].hasOwnProperty(line_type)
|
|
||||||
) {
|
|
||||||
let scenario_clos_mask = vmCPUClosMasks[cpu_policy.VM][cpu_policy.VCPU][line_type];
|
|
||||||
if (vcat_mask_length === null || count(Number.parseInt(scenario_clos_mask).toString(2), '1') === vcat_mask_length) {
|
|
||||||
clos_mask = scenario_clos_mask
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cpu_policy['CLOS_MASK'] = clos_mask;
|
|
||||||
cat_region_info.data.POLICY.push(cpu_policy)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* let cpu_policies_example = [
|
|
||||||
* {"VM": "POST_VM_1", "VCPU": 0},
|
|
||||||
* {"VM": "POST_VM_2", "VCPU": 2}
|
|
||||||
* ]
|
|
||||||
*/
|
|
||||||
function addPolicy(cpu_policies) {
|
|
||||||
for (let j = 0; j < cpu_policies.length; j++) {
|
|
||||||
let cpu_policies_line = cpu_policies[j];
|
|
||||||
if (CDP_ENABLED) {
|
|
||||||
addCATPolicy(cpu_policies_line, "Code")
|
|
||||||
addCATPolicy(cpu_policies_line, "Data")
|
|
||||||
} else {
|
|
||||||
addCATPolicy(cpu_policies_line, "Unified")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CDP_ENABLED ? 2 * cpu_policies.length : cpu_policies.length
|
|
||||||
}
|
|
||||||
|
|
||||||
// add rt vm policy
|
|
||||||
cat_region_info.real_time_count = 0
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
for (let i = 0; i < cat_region_info.processors.length; i++) {
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
let pcpu_id = cat_region_info.processors[i];
|
|
||||||
let cpu_policies = pcpu_vms[pcpu_id] ? pcpu_vms[pcpu_id]['y'] : [];
|
|
||||||
cat_region_info.real_time_count += addPolicy(cpu_policies)
|
|
||||||
}
|
|
||||||
// add std vm policy
|
|
||||||
cat_region_info.cat_count = _.cloneDeep(cat_region_info.real_time_count)
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
for (let i = 0; i < cat_region_info.processors.length; i++) {
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
let pcpu_id = cat_region_info.processors[i];
|
|
||||||
let cpu_policies = pcpu_vms[pcpu_id] ? pcpu_vms[pcpu_id]['n'] : [];
|
|
||||||
cat_region_info.cat_count += addPolicy(cpu_policies)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add vcat vm policy
|
|
||||||
// noinspection JSUnresolvedVariable
|
|
||||||
if (cat_region_info.processors.indexOf(0) !== -1) {
|
|
||||||
for (let i = 0; i < vCats.length; i++) {
|
|
||||||
addCATPolicy(vCats[i], 'Unified', vCats[i].CLOS_MASK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// order policy by @id
|
|
||||||
// cat_region_info.data.POLICY.sort(function (a, b) {
|
|
||||||
// return a['@id'] - b['@id']
|
|
||||||
// });
|
|
||||||
})
|
|
||||||
|
|
||||||
for (let i = 0; i < board_cat_info.length; i++) {
|
|
||||||
if (board_cat_info[i].data.POLICY.length === 0) {
|
|
||||||
board_cat_info.splice(i--, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return board_cat_info;
|
|
||||||
}
|
|
||||||
|
|
||||||
let generate = () => {
|
|
||||||
let currentFormDataCPUAffinitySettings = getCurrentFormDataCPUAffinitySettings();
|
|
||||||
let scenarioCatData = getScenarioCATData();
|
|
||||||
this.CAT_INFO = mergeAndGenerateData(currentFormDataCPUAffinitySettings, scenarioCatData);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
generate()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,20 +6,14 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Slider from '@vueform/slider'
|
import Slider from '@vueform/slider'
|
||||||
|
import configurator from '../../../../../lib/acrn'
|
||||||
|
|
||||||
function count(source, target) {
|
|
||||||
return (source.match(new RegExp(target, 'g')) || []).length;
|
|
||||||
}
|
|
||||||
|
|
||||||
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
let getHexValue = (value, max) => {
|
|
||||||
let newHexValue = '0'.repeat(value[0]) + '1'.repeat(value[1] - value[0]) + '0'.repeat(max - value[1])
|
|
||||||
newHexValue = (parseInt(newHexValue, 2).toString(16))
|
|
||||||
let zeroPadding = '0'.repeat(Number.parseInt('1'.repeat(max), 2).toString(16).length - newHexValue.length)
|
|
||||||
newHexValue = '0x' + zeroPadding + newHexValue;
|
|
||||||
return newHexValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "HexBlockRangeSelector",
|
name: "HexBlockRangeSelector",
|
||||||
@ -36,32 +30,7 @@ export default {
|
|||||||
},
|
},
|
||||||
hexField: {
|
hexField: {
|
||||||
get() {
|
get() {
|
||||||
let str_bin = Number.parseInt(this.modelValue).toString(2);
|
return configurator.cat.hexToRange(this.modelValue, this.max)
|
||||||
let block_length = str_bin.length;
|
|
||||||
let block_enabled_length = count(str_bin, "1");
|
|
||||||
|
|
||||||
let start = 0
|
|
||||||
let end = 0
|
|
||||||
|
|
||||||
if (block_length > this.max) {
|
|
||||||
if (block_enabled_length >= this.max) {
|
|
||||||
str_bin = "1".repeat(this.max);
|
|
||||||
} else {
|
|
||||||
str_bin = "0".repeat(this.max - block_enabled_length) + "1".repeat(block_enabled_length);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (block_length < this.max) {
|
|
||||||
str_bin = "0".repeat(this.max - block_length) + str_bin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start = str_bin.indexOf("1") !== -1 ? str_bin.indexOf("1") : 0;
|
|
||||||
end = start + count(str_bin, "1");
|
|
||||||
|
|
||||||
// noinspection UnnecessaryLocalVariableJS
|
|
||||||
let result = [start, end]
|
|
||||||
return result
|
|
||||||
|
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value[1] - value[0] === 0) {
|
if (value[1] - value[0] === 0) {
|
||||||
@ -71,7 +40,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.lastValue = JSON.parse(JSON.stringify(value))
|
this.lastValue = JSON.parse(JSON.stringify(value))
|
||||||
}
|
}
|
||||||
this.$emit("update:modelValue", getHexValue(value, this.max))
|
this.$emit("update:modelValue", configurator.cat.rangeToHex(value, this.max))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user