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
26 package sun.nio.ch.iouring;
27
28 import java.lang.foreign.*;
29 import java.lang.invoke.MethodHandle;
30 import java.nio.ByteBuffer;
31 import java.nio.charset.StandardCharsets;
32 import java.util.LinkedList;
33 import java.util.NoSuchElementException;
34 import java.util.List;
35
36 import static java.lang.foreign.ValueLayout.JAVA_BYTE;
37 import static jdk.internal.ffi.generated.iouring.iouring_h.*;
38
39 @SuppressWarnings("restricted")
40 class Util {
41
42 public static void print(MemorySegment segment, String title) {
43 print(segment, title, 32);
44 }
45
46 /**
47 * Prints to System.out contents of MemorySegment
48 *
49 * @param segment
50 * @param title
51 * @param wrap Number of bytes to wrap line at
52 */
53 public static void print(MemorySegment segment, String title, int wrap) {
54 long size = segment.byteSize();
55 long startAddress = segment.address();
56 System.out.printf("%s, Size: %d bytes, Wrap: %d", title, size, wrap);
57 for (long offset=0L; offset<size; offset++) {
58 int b = segment.get(ValueLayout.JAVA_BYTE, offset) & 0xff;
59 long address = startAddress + offset;
60 if (offset % wrap == 0) {
61 System.out.println("");
62 System.out.printf("%08X ", address);
63 }
64 System.out.printf("%02X", b);
65 if (offset % 4 == 3)
66 System.out.print(" ");
67 }
68 System.out.println("");
69 }
70
71 public static String sqe_opcode(int code) {
72 if (code == IORING_OP_ACCEPT())
73 return "IORING_OP_ACCEPT";
74 else if (code == IORING_OP_CLOSE())
75 return "IORING_OP_CLOSE";
76 else if (code == IORING_OP_SOCKET())
77 return "IORING_OP_SOCKET";
78 else if (code == IORING_OP_CONNECT())
79 return "IORING_OP_CONNECT";
80 else if (code == IORING_OP_WRITE())
81 return "IORING_OP_WRITE";
82 else if (code == IORING_OP_OPENAT())
83 return "IORING_OP_OPENAT";
84 else if (code == IORING_OP_READ_FIXED())
85 return "IORING_OP_READ_FIXED";
86 else if (code == IORING_OP_WRITE_FIXED())
87 return "IORING_OP_WRITE_FIXED";
88 else if (code == IORING_OP_POLL_ADD())
89 return "IORING_OP_POLL_ADD";
90 else if (code == IORING_OP_POLL_REMOVE())
91 return "IORING_OP_POLL_REMOVE";
92 else if (code == IORING_OP_TIMEOUT())
93 return "IORING_OP_TIMEOUT";
94 else if (code == IORING_OP_READ())
95 return "IORING_OP_READ";
96 else if (code == IORING_OP_LINK_TIMEOUT())
97 return "IORING_OP_LINK_TIMEOUT";
98 else if (code == IORING_OP_NOP())
99 return "IORING_OP_NOP";
100 else if (code == IORING_OP_MSG_RING())
101 return "IORING_OP_MSG_RING";
102 else return String.format("UNKNOWN(%d)", code);
103 }
104
105 static MethodHandle locateStdHandle(String name,
106 FunctionDescriptor descriptor,
107 Linker.Option... options) {
108 try {
109 Linker linker = Linker.nativeLinker();
110 SymbolLookup stdlib = linker.defaultLookup();
111 return linker.downcallHandle(
112 stdlib.find(name).orElseThrow(),
113 descriptor,
114 options
115 );
116 } catch (NoSuchElementException e) {
117 String msg = String.format("Error loading %s from standard lib",
118 name);
119 throw new RuntimeException(msg);
120 }
121 }
122
123 static MethodHandle locateHandleFromLib(String libname,
124 String symbol,
125 FunctionDescriptor descriptor,
126 Linker.Option... options) {
127 try {
128 Linker linker = Linker.nativeLinker();
129 SymbolLookup lib = SymbolLookup.libraryLookup(
130 libname, Arena.global());
131 MethodHandle fn = linker.downcallHandle(
132 lib.find(symbol).orElseThrow(),
133 descriptor,
134 options
135 );
136 return fn;
137 } catch (NoSuchElementException e) {
138 String msg = String.format("Error loading %s from %s",
139 symbol, libname);
140 throw new RuntimeException(msg);
141 }
142 }
143
144 public final static ValueLayout INT_POINTER =
145 ValueLayout.ADDRESS.withTargetLayout(
146 ValueLayout.JAVA_INT
147 );
148
149 private final static ValueLayout POINTER =
150 ValueLayout.ADDRESS.withTargetLayout(
151 MemoryLayout.sequenceLayout(Long.MAX_VALUE, JAVA_BYTE)
152 );
153
154 private static final MethodHandle strerror_fn = locateStdHandle(
155 "strerror",
156 FunctionDescriptor.of(
157 POINTER,
158 ValueLayout.JAVA_INT
159 )
160 );
161 public static String strerror(int errno) {
162 try {
163 MemorySegment result = (MemorySegment) strerror_fn.invokeExact(errno);
164 return result.getString(0, StandardCharsets.UTF_8);
165 } catch (Throwable t) {
166 return "Error: " + errno;
167 }
168 }
169
170 }