1 /*
 2  * Copyright (c) 2023, 2025, 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 jdk.internal.vm;
26 
27 import java.nio.charset.StandardCharsets;
28 import java.util.List;
29 import java.util.stream.IntStream;
30 import jdk.internal.access.JavaLangAccess;
31 import jdk.internal.access.SharedSecrets;
32 import sun.nio.ch.Poller;
33 
34 /**
35  * The implementation for the jcmd Thread.vthread_* diagnostic commands. These methods are
36  * called from the "Attach Listener" thread.
37  */
38 public class JcmdVThreadCommands {
39     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
40 
41     private JcmdVThreadCommands() { }
42 
43     /**
44      * Invoked by the VM to print the virtual scheduler to a byte[].
45      */
46     private static byte[] printScheduler() {
47         StringBuilder sb = new StringBuilder();
48 
49         // virtual thread scheduler
50         sb.append(JLA.defaultVirtualThreadScheduler())
51           .append(System.lineSeparator());
52 
53         return sb.toString().getBytes(StandardCharsets.UTF_8);
54     }
55 
56     /**
57      * Invoked by the VM to print the I/O pollers to a byte[].
58      */
59     private static byte[] printPollers() {
60         StringBuilder sb = new StringBuilder();
61 
62         Poller masterPoller = Poller.masterPoller();
63         List<Poller> readPollers = Poller.readPollers();
64         List<Poller> writePollers = Poller.writePollers();
65 
66         if (masterPoller != null) {
67             sb.append("Master I/O poller:")
68               .append(System.lineSeparator())
69               .append(masterPoller)
70               .append(System.lineSeparator());
71 
72             // break
73             sb.append(System.lineSeparator());
74         }
75 
76         sb.append("Read I/O pollers:");
77         sb.append(System.lineSeparator());
78         IntStream.range(0, readPollers.size())
79                 .forEach(i -> sb.append('[')
80                                 .append(i)
81                                 .append("] ")
82                                 .append(readPollers.get(i))
83                                 .append(System.lineSeparator()));
84 
85         // break
86         sb.append(System.lineSeparator());
87 
88         sb.append("Write I/O pollers:");
89         sb.append(System.lineSeparator());
90         IntStream.range(0, writePollers.size())
91                 .forEach(i -> sb.append('[')
92                                 .append(i)
93                                 .append("] ")
94                                 .append(writePollers.get(i))
95                                 .append(System.lineSeparator()));
96 
97         return sb.toString().getBytes(StandardCharsets.UTF_8);
98     }
99 }