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 }