Ive blogged about using enclaves from a C program. There is an interface from Java which uses this C interface.
Is is relatively easy to use enclave services from a java program, as there are java classes for most of the functions, available from JZOS toolkit. For example the WorkloadManager class is defined here.
Below is a program I used to get the Work Load Manager(WLM) services working.
import java.util.concurrent.TimeUnit;
import com.ibm.jzos.wlm.ServerClassification;
import com.ibm.jzos.wlm.WorkUnit;
import com.ibm.jzos.wlm.WorkloadManager;
public class main
{
// run it with /usr/lpp/java/J8.0_64/bin/java main
public static void main(String[] args) throws Exception
{
WorkloadManager wlmToken = new WorkloadManager("JES", "SM3");
ServerClassification serverC = wlmToken.createServerClassification();
serverC.setTransactionName("TCI3");
for ( int j = 0;j<1000;j++)
{
WorkUnit wU = new WorkUnit(serverC, "MAINCP");
wU.join();
float f;
for (int i = 0;i<1000000;i++) f=ii2;
TimeUnit.MICROSECONDS.sleep(20*1000); // 200 milliseconds
wU.leave();
wU.delete(); // end the workload
}
wlmToken.disconnect();
}
}
The WLM statements are explained below.
WorkloadManager wlmToken = new WorkloadManager(“JES”, “SM3”);
This connects to the Work Load Manager and returns a connection token. This needs to be done once per JVM. You can use any relevant subsystem type, I used JES, and a SubsystemInstance (SI) of SM3. As a test, I created a new subsystem category in WLM called DOG, and used that. I defined ServerInstance SI with a value of SM3 within DOG and it worked.
z/OS uses uses subsystems such as JES for jobs submitted into JES2, and STC for Started task.
ServerClassification serverC = m.createServerClassification();
If your application is going to classify the transaction to determine the WLM service class and reporting class you need this. You create it, then add the classification criteria to it, see the following section.
Internally this passes the connection token wlmToken to the createServerClassification function.
serverC.setTransactionName(“TCI3”);
This passes information to WLM to determine the best service class and reporting class. Within Subsystem CAT, Subsystem Instance SM1, I had a sub rule TransactionName (TN) with a value TCI3. I defined the service class and a reporting class.
WorkUnit wU = new WorkUnit(serverC, “MAINCP”);
This creates the Independent (business transaction) enclave. I have not see the value MAINCP reported in any reports. This invokes the C run time function CreateWorkUnit(). The CreateWorkUnit function requires a STCK value of when the work unit started. The Java code does this for you and passes the STCK through.
wU.join();
This connect the current task to the enclave, and any CPU it uses will be recorded against the enclave.
wU.leave();
Disconnect the current task from the enclave. After this call any CPU used by the thread will be recorded against the address space.
wU.delete();
The Independent enclave(Business transaction) has finished. WLM records the elapsed time and resources used for the business transaction.
m.disconnect();
The program disconnects from WLM.
Reporting class output.
I used RMF to print the SMF 72 records for this program. The Reporting class for this program had
-TRANSACTIONS-- TRANS-TIME HHH.MM.SS.FFFFFF AVG 0.29 ACTUAL 36320 MPL 0.29 EXECUTION 35291 ENDED 998 QUEUED 1028 END/S 8.31 R/S AFFIN 0 #SWAPS 0 INELIGIBLE 0 EXCTD 0 CONVERSION 0 STD DEV 18368 ----SERVICE---- SERVICE TIME ---APPL %--- IOC 0 CPU 12.543 CP 0.01 CPU 10747 SRB 0.000 IIPCP 0.01 MSO 0 RCT 0.000 IIP 10.44 SRB 0 IIT 0.000 AAPCP 0.00 TOT 10747 HST 0.000 AAP N/A
From this we can see that for the interval
- 998 transactions ended. (Another report interval had 2 transactions ending)
- the response time was an average of 36.3 milliseconds
- a total of 12.543 seconds of CPU was used.
- it spent 10.44 % of the time on a ZIIP.
- 0.01 % of the time it was executing ZIIP eligible work on a CP as there was no available ZIIP.
Additional functions.
The functions below
- ContinueWorkUnit – for dependent enclave
- JoinWorkUnit – as before
- LeaveWorkUnit – as before
- DeleteWorkUnit – as before
can be used to record CPU against the dependent (Address space) enclave. There is no WLM classify for a dependent enclave.
Java threads and WLM
A common application pattern is to use connection pooling. For example the connect/disconnect to a database or MQ is expensive. If you have a pool of threads, which connect, and start connected, an application can request a thread and get a thread which has already been connected to the resource manager.
It should be a simple matter of changing the interface from
connectionPool.getConnection()
to
connectionPool.getConnection(WorkUnit wU)
{
connection = connectionPool.getConnection()
connection.join(wU)
}
and add a connection.leave(wU) to the releaseConnection.