• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *   Copyright © International Business Machines  Corp., 2006, 2008
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * NAME
20  *      async_handler_jk.c
21  *
22  * DESCRIPTION
23  *     This test mimics an async event handler in a real-time JVM
24  *     An async event server thread is created that goes to sleep waiting
25  *     to be woken up to do some work.
26  *
27  *     A user thread is created that simulates the firing of an event by
28  *     signalling the async handler thread to do some work.
29  *
30  * USAGE:
31  *     Use run_auto.sh script in current directory to build and run test.
32  *
33  * AUTHOR
34  *      John Kacur <jkacur@ca.ibm.com>
35  *
36  * HISTORY
37  *     2006-Nov-20: Initial Version by John Kacur <jkacur@ca.ibm.com>
38  *
39  *****************************************************************************/
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <math.h>
44 #include <librttest.h>
45 #include <libstats.h>
46 
47 // This is the normal priority for an event handler if not specified.
48 #define NORMAL_PRIORITY	43
49 #define THREAD_FLAG_SUSPENDED 8
50 #define PASS_US 100
51 
52 long start, end;
53 
54 /* Function Prototypes */
55 void *async_event_server(void *arg);
56 void *handler1(void *arg);
57 
usage(void)58 void usage(void)
59 {
60 	rt_help();
61 	printf("async_handler_jk specific options:\n");
62 }
63 
parse_args(int c,char * v)64 int parse_args(int c, char *v)
65 {
66 
67 	int handled = 1;
68 	switch (c) {
69 	case 'h':
70 		usage();
71 		exit(0);
72 	default:
73 		handled = 0;
74 		break;
75 	}
76 	return handled;
77 }
78 
async_event_server(void * arg)79 void *async_event_server(void *arg)
80 {
81 	int err = 0;
82 	struct thread *thread = ((struct thread *)arg);
83 
84 	thread->func = NULL;	// entrypoint
85 	thread->flags |= THREAD_FLAG_SUSPENDED;
86 
87 	for (;;) {
88 		if ((err = pthread_mutex_lock(&thread->mutex)))
89 			return (void *)(intptr_t) err;
90 
91 		/* Go to sleep and wait for work */
92 		while (thread->flags & THREAD_FLAG_SUSPENDED)
93 			pthread_cond_wait(&thread->cond, &thread->mutex);
94 
95 		pthread_mutex_unlock(&thread->mutex);
96 
97 		/* The JVM would be able to dynamically choose a handler */
98 		thread->func = handler1;
99 
100 		if (thread->func != NULL)
101 			thread->func(arg);
102 
103 		// Reset Priority to original async server priority
104 		set_thread_priority(thread->pthread, thread->priority);
105 
106 		thread->flags |= THREAD_FLAG_SUSPENDED;
107 	}			// Go back to sleep and wait for next command
108 }
109 
user_thread(void * arg)110 void *user_thread(void *arg)
111 {
112 	struct thread *thread = ((struct thread *)arg);
113 	struct thread *server = (struct thread *)thread->arg;
114 
115 	start = rt_gettime();
116 
117 	/* Change the async server thread priority to be the priority
118 	   of the user_thread. (event thread) */
119 	set_thread_priority(server->pthread, thread->priority);
120 
121 	/* Clear the THREAD_FLAG_SUSPENDED flag of the server before signal */
122 	server->flags &= ~THREAD_FLAG_SUSPENDED;
123 
124 	/* Signal the async server thread - simulates firing of an event */
125 	pthread_cond_broadcast(&server->cond);
126 
127 	return NULL;
128 }
129 
handler1(void * arg)130 void *handler1(void *arg)
131 {
132 	end = rt_gettime();
133 	return NULL;
134 }
135 
main(int argc,char * argv[])136 int main(int argc, char *argv[])
137 {
138 	int aes_id;		// asynchronous event server id
139 	int user_id;		// User thread - that fires the event
140 	long delta;
141 	struct thread *server;
142 	setup();
143 
144 	pass_criteria = PASS_US;
145 	rt_init("h", parse_args, argc, argv);
146 
147 	aes_id = create_fifo_thread(async_event_server, NULL, 83);
148 	server = get_thread(aes_id);
149 
150 	user_id =
151 	    create_fifo_thread(user_thread, (void *)server, NORMAL_PRIORITY);
152 
153 	usleep(1000);
154 	pthread_detach(server->pthread);
155 	join_thread(user_id);
156 	join_threads();
157 	delta = (end - start) / NS_PER_US;
158 
159 	printf("delta = %ld us\n", delta);
160 	printf("\nCriteria: latencies < %d\n", (int)pass_criteria);
161 	printf("Result: %s\n", delta > pass_criteria ? "FAIL" : "PASS");
162 
163 	return 0;
164 }
165