1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package optkl.ifacemapper;
26
27
28
29 import java.lang.foreign.GroupLayout;
30 import java.lang.foreign.MemoryLayout;
31 import java.lang.foreign.MemorySegment;
32 import java.lang.foreign.ValueLayout;
33 import java.lang.invoke.VarHandle;
34 import java.util.Objects;
35
36
37
38 /*
39
40
41 See backend_ffi_shared/include/shared.h
42
43 Make sure the final static values below match the #defines
44 // iface buffer bitz
45 // iface bffa bitz
46 // 4a7 1face bffa b175
47
48
49
50 struct state{
51 long magic1; // MAGIC
52 int bits;
53 int mode;
54 void * vendorPtr; // In OpenCL this points to native OpenCL::Buffer
55 long magic2; // MAGIC
56 }
57 */
58
59 public record BufferState(MemorySegment segment, long paddedSize) {
60 public static final long alignment = ValueLayout.JAVA_LONG.byteSize();
61 // hat iface buffer bitz
62 // hat iface bffa bitz
63 // 4a7 1face bffa b175
64 public static final long MAGIC = 0x4a71facebffab175L;
65
66 public static final int NO_STATE = 0;
67 public static final int NEW_STATE = 1;
68 public static final int HOST_OWNED = 2;
69 public static final int DEVICE_OWNED = 3;
70 public static final int DEVICE_VALID_HOST_HAS_COPY = 4;
71 public static String[] stateNames = new String[]{
72 "NO_STATE",
73 "NEW_STATE",
74 "HOST_OWNED",
75 "DEVICE_OWNED",
76 "DEVICE_VALID_HOST_HAS_COPY"
77 };
78 static final MemoryLayout stateMemoryLayout = MemoryLayout.structLayout(
79 ValueLayout.JAVA_LONG.withName("magic1"),
80 ValueLayout.ADDRESS.withName("ptr"),
81 ValueLayout.JAVA_LONG.withName("length"),
82 ValueLayout.JAVA_INT.withName("bits"),
83 ValueLayout.JAVA_INT.withName("state"),
84 ValueLayout.ADDRESS.withName("vendorPtr"),
85 ValueLayout.JAVA_LONG.withName("magic2")
86 ).withName("state");
87
88 static long byteSize() {
89 return stateMemoryLayout.byteSize();
90 }
91
92 static final VarHandle magic1 = stateMemoryLayout.varHandle(
93 MemoryLayout.PathElement.groupElement("magic1")
94 );
95 static final VarHandle ptr = stateMemoryLayout.varHandle(
96 MemoryLayout.PathElement.groupElement("ptr")
97 );
98 static final VarHandle length = stateMemoryLayout.varHandle(
99 MemoryLayout.PathElement.groupElement("length")
100 );
101
102 static final VarHandle state = stateMemoryLayout.varHandle(
103 MemoryLayout.PathElement.groupElement("state")
104 );
105
106 static final VarHandle magic2 = stateMemoryLayout.varHandle(
107 MemoryLayout.PathElement.groupElement("magic2")
108 );
109
110 static final VarHandle vendorPtr = stateMemoryLayout.varHandle(
111 MemoryLayout.PathElement.groupElement("vendorPtr")
112 );
113
114 public static long getLayoutSizeAfterPadding(GroupLayout layout) {
115 return layout.byteSize() +
116 ((layout.byteSize() % BufferState.alignment) == 0 ? 0 : BufferState.alignment - (layout.byteSize() % BufferState.alignment));
117 }
118
119 public static <T> BufferState of(T t) {
120 MappableIface buffer = (MappableIface) Objects.requireNonNull(t);
121 MemorySegment s = MappableIface.getMemorySegment(buffer);
122 return new BufferState(s, s.byteSize() - BufferState.byteSize());
123 }
124 public BufferState setState(int newState) {
125 BufferState.state.set(segment, paddedSize, newState);
126 return this;
127 }
128 public BufferState setPtr(MemorySegment ptr) {
129 BufferState.ptr.set(segment, paddedSize, ptr);
130 return this;
131 }
132
133 BufferState setLength(long newLength) {
134 BufferState.length.set(segment, paddedSize, newLength);
135 return this;
136 }
137 BufferState setMagic() {
138 BufferState.magic1.set(segment, paddedSize, MAGIC);
139 BufferState.magic2.set(segment, paddedSize, MAGIC);
140 return this;
141 }
142
143
144 public int getState() {
145 return (Integer)BufferState.state.get(segment, paddedSize);
146 }
147 public String getStateString(){
148 return stateNames[getState()];
149 }
150 public MemorySegment getVendorPtr() {
151 return (MemorySegment) BufferState.vendorPtr.get(segment, paddedSize);
152 }
153 public void setVendorPtr(MemorySegment vendorPtr) {
154 BufferState.vendorPtr.set(segment, paddedSize, vendorPtr);
155 }
156
157 public long magic1() {
158 return (Long) BufferState.magic1.get(segment, paddedSize);
159 }
160
161 public long magic2() {
162 return (Long) BufferState.magic2.get(segment, paddedSize);
163 }
164
165 public boolean ok() {
166 return MAGIC == magic1() && MAGIC == magic2();
167 }
168
169
170 @Override
171 public String toString() {
172 StringBuilder builder = new StringBuilder();
173 if (ok()) {
174 builder.append("State:ok").append("\n");
175 var vendorPtr = getVendorPtr();
176 builder.append(",").append("VENDOR_PTR:").append(Long.toHexString(vendorPtr.address()));
177 builder.append("\n");
178 } else {
179 builder.append("State: not ok").append("\n");
180 }
181 return builder.toString();
182 }
183
184 }