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..39958da6d4 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: @@ -3126,33 +3134,84 @@ 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); } + + /* + * The groupMasks array default size is 1. Resize only if larger. Since the + * groupMasks array always has at least one element we copy it to the groupMask + * field. This is needed for backwards compatibility in the case groupCount is 0 + * but done all the time for convenience. + */ + @Override + public void read() { + // resize array if needed + readField("groupCount"); + if (groupCount > 1) { + groupMasks = new GROUP_AFFINITY[groupCount]; + } + // Now read the fields from field order + super.read(); + // Finally copy first value from array to older version of structure + 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 +3446,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;