From 33e0fc44cc8a357ff29f482a84e4cf1ec8cece43 Mon Sep 17 00:00:00 2001 From: Daniel Widdis Date: Sun, 8 Aug 2021 10:05:21 -0700 Subject: [PATCH] Update NUMA_NODE_RELATIONSHIP to new variable size structure --- CHANGES.md | 1 + .../src/com/sun/jna/platform/win32/WinNT.java | 78 ++++++++++++++++--- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 81c35ced15..8456dacb07 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Features * [#1352](https://github.com/java-native-access/jna/pull/1352): Add `BringWindowToTop` to `c.s.j.p.win32.User32` - [@kahgoh](https://github.com/kahgoh). * [#1354](https://github.com/java-native-access/jna/pull/1352): Add `GetParent` to `c.s.j.p.win32.User32` - [@kahgoh](https://github.com/kahgoh). * [#1360](https://github.com/java-native-access/jna/issues/1360): Add `CommandLineToArgvW` to `c.s.j.p.win32.Shell32` and corresponding util in `c.s.j.p.win32.Shell32Util` - [@dbwiddis](https://github.com/dbwiddis). +* [#1363](https://github.com/java-native-access/jna/issues/1363): Update `NUMA_NODE_RELATIONSHIP` in `c.s.j.p.win32.WinNT` to new version of the structure and improve support for future values of `c.s.j.p.win32.WinNT.LOGICAL_PROCESSOR_RELATIONSHIP` - [@dbwiddis](https://github.com/dbwiddis). Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java index ba65d57dc9..745b0d0eb5 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinNT.java @@ -23,6 +23,11 @@ */ package com.sun.jna.platform.win32; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import com.sun.jna.FromNativeContext; import com.sun.jna.IntegerType; import com.sun.jna.Memory; @@ -3018,9 +3023,12 @@ public static SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX fromPointer(Pointer memory switch (relationship) { case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore: case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage: + case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorDie: + case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorModule: result = new PROCESSOR_RELATIONSHIP(memory); break; case LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode: + case LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNodeEx: result = new NUMA_NODE_RELATIONSHIP(memory); break; case LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache: @@ -3118,7 +3126,10 @@ public PROCESSOR_RELATIONSHIP(Pointer memory) { @Override public void read() { readField("groupCount"); - groupMask = new GROUP_AFFINITY[groupCount]; + // Resize if needed + if (groupCount != groupMask.length) { + groupMask = new GROUP_AFFINITY[groupCount]; + } super.read(); } } @@ -3126,33 +3137,80 @@ public void read() { /** * Represents information about a NUMA node in a processor group. */ - @FieldOrder({ "nodeNumber", "reserved", "groupMask" }) + @FieldOrder({ "nodeNumber", "reserved", "groupCount", "groupMasks" }) public static class NUMA_NODE_RELATIONSHIP extends SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX { /** - * Identifies the NUMA node. Valid values are {@code 0} to the highest - * NUMA node number inclusive. A non-NUMA multiprocessor system will - * report that all processors belong to one NUMA node. + * Identifies the NUMA node. Valid values are {@code 0} to the highest NUMA node + * number inclusive. A non-NUMA multiprocessor system will report that all + * processors belong to one NUMA node. */ public int nodeNumber; /** * This member is reserved. */ - public byte[] reserved = new byte[20]; + public byte[] reserved = new byte[18]; + + /** + * The number of groups included in the GroupMasks array. This field was + * introduced in TBD Release Iron. On earlier versions, this value is always 0. + */ + public short groupCount; /** * A {@link GROUP_AFFINITY} structure that specifies a group number and - * processor affinity within the group. + * processor affinity within the group. This member is only relevant if + * {@code groupCount} is 0. */ public GROUP_AFFINITY groupMask; + /** + * An array of {@link GROUP_AFFINITY} structures that specifies a group number + * and processor affinity within the group. This member is only relevant if + * {@code groupCount} is 1 or greater. + */ + public GROUP_AFFINITY[] groupMasks = new GROUP_AFFINITY[1]; + public NUMA_NODE_RELATIONSHIP() { } public NUMA_NODE_RELATIONSHIP(Pointer memory) { super(memory); } + + @Override + public void read() { + readField("groupCount"); + // In older version of structure this is part of reserved array and has 0 value. + // Force a minimum array size of 1. + int actualGroupCount = Math.max(1, groupCount); + // Resize if needed + if (actualGroupCount != groupMasks.length) { + groupMasks = new GROUP_AFFINITY[actualGroupCount]; + } + super.read(); + // Copy first value from array to older version of structure for compatibility + groupMask = groupMasks[0]; + } + + /* + * The groupMask field is provided as a public instance variable for + * compatibility. getFieldList is overridden to remove it before comparing + * against the structure field order. + */ + @Override + protected List getFieldList() { + List fields = new ArrayList(super.getFieldList()); + Iterator fieldIterator = fields.iterator(); + while (fieldIterator.hasNext()) { + Field field = fieldIterator.next(); + if ("groupMask".equals(field.getName())) { + fieldIterator.remove(); + } + } + return fields; + } } /** @@ -3387,8 +3445,10 @@ public interface LOGICAL_PROCESSOR_RELATIONSHIP { /** *

- * Upcoming value of this enum added for forward compatibility. Documentation - * will be added when available. + * Introduced in TBD - Release Iron. Requests that the full affinity be + * returned. Unlike the other relation types, RelationNumaNodeEx is not used on + * input. It is simply a request for RelationNumaNode with full group + * information. *

*/ int RelationNumaNodeEx = 6;