Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / examples / Shared_Malloc / test_malloc.cpp
blobd0a1bf279f960d1328049d4ac52e25bc16f63a43
1 // This program tests out all the various ACE_Malloc combinations and
2 // the ACE_Allocator_Adapter.
4 #include "ace/Thread.h"
5 #include "ace/Thread_Manager.h"
6 #include "ace/Malloc.h"
7 #include "ace/Signal.h"
8 #include "ace/Truncate.h"
9 #include "ace/OS_NS_stdio.h"
10 #include "ace/OS_NS_string.h"
11 #include "ace/OS_NS_sys_wait.h"
12 #include "ace/OS_NS_unistd.h"
13 #include "Malloc.h"
14 #include "Options.h"
17 static int
18 gen_size ()
20 #if defined (ACE_HAS_THREADS)
21 unsigned int seed =
22 static_cast<unsigned int> (reinterpret_cast<uintptr_t> (&seed));
24 return (
25 ACE_Utils::truncate_cast<int> (
26 ACE_OS::rand_r (&seed) % Options::instance ()->max_msg_size ()) + 1);
27 #else
28 return (
29 ACE_Utils::truncate_cast<int> (
30 ACE_OS::rand () % Options::instance ()->max_msg_size ()) + 1);
31 #endif /* ACE_HAS_THREADS */
34 // Recursively allocate and deallocate dynamic memory.
36 static int
37 malloc_recurse (int count)
39 static char default_char = 0;
41 if (count <= 0)
43 if (Options::instance ()->debug ())
45 // Note that you'll need to #define ACE_HAS_MALLOC_STATS in
46 // the main ACE config.h file and remake ACE to enable this.
47 ACE_MALLOC_STATS (Malloc::instance ()->print_stats ());
50 else
52 int alloc_size = gen_size ();
53 void *ptr = Malloc::instance ()->malloc (alloc_size);
55 if (ptr == 0)
56 ACE_ERROR ((LM_ERROR,
57 "(%P|%t) *** malloc of size %d failed, %p\n%a",
58 "malloc",
59 alloc_size));
60 else
62 ACE_OS::memset (ptr, default_char++, alloc_size);
64 if (Options::instance ()->debug ())
65 ACE_DEBUG ((LM_INFO,
66 "(%P|%t) %u (alloc), size = %d\n",
67 ptr,
68 alloc_size));
70 // Call ourselves recursively
71 malloc_recurse (count - 1);
73 if (Options::instance ()->debug ())
74 ACE_DEBUG ((LM_INFO,
75 "(%P|%t) %u (free), size = %d\n",
76 ptr,
77 alloc_size));
78 Malloc::instance ()->free (ptr);
82 return 0;
85 #if defined (ACE_HAS_THREADS)
86 static void *
87 worker (void *arg)
89 // Cast the arg to a long, first, because a pointer is the same
90 // size as a long on all current ACE platforms.
91 malloc_recurse (static_cast<int> (reinterpret_cast<intptr_t> (arg)));
93 return 0;
95 #endif /* ACE_HAS_THREADS */
97 // Create the appropriate type of process/thread.
99 static void
100 spawn ()
102 if (Options::instance ()->spawn_threads ())
104 #if defined (ACE_HAS_THREADS)
105 if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (worker),
106 (void *) Options::instance ()->iteration_count (),
107 THR_BOUND) == -1)
108 ACE_ERROR ((LM_ERROR, "%p\n%a", "thread create failed"));
109 #else
110 if (Options::instance ()->spawn_count () > 1)
111 ACE_ERROR ((LM_ERROR,
112 "only one thread may be run in a process on this platform\n%a",
113 1));
114 #endif /* ACE_HAS_THREADS */
116 #if !defined (ACE_WIN32)
117 else if (ACE_OS::fork (ACE_TEXT_CHAR_TO_TCHAR (Options::instance ()->program_name ())) == 0)
119 if (Options::instance ()->exec_slave ())
121 char iterations[20];
122 char msg_size[20];
124 ACE_OS::sprintf (iterations, "%lu",
125 (unsigned long)
126 Options::instance ()->iteration_count ());
127 ACE_OS::sprintf (msg_size, "%lu",
128 (unsigned long)
129 Options::instance ()->max_msg_size ());
130 const char *cp = 0;
132 if (Options::instance ()->debug ())
133 cp = "-d";
134 else
135 cp = "";
137 const char *argv[] =
139 Options::instance ()->slave_name (),
140 "-p",
141 "-n",
142 iterations,
143 "-L",
144 msg_size,
149 if (ACE_OS::execv (Options::instance ()->program_name (),
150 (char *const *) argv) == -1)
151 ACE_ERROR ((LM_ERROR, "%p\n", "exec failed"));
152 ACE_OS::_exit (1);
154 else
156 ACE_DEBUG ((LM_INFO,
157 "(%P|%t) about to recurse with iteration count = %d\n",
158 Options::instance ()->iteration_count ()));
160 malloc_recurse (Options::instance ()->iteration_count ());
161 Malloc::instance ()->remove ();
162 ACE_OS::exit (0);
165 #endif /* ACE_WIN32 */
168 // Wait for all the child processes/threads to exit.
170 static void
171 wait_for_children ()
173 if (Options::instance ()->spawn_threads ())
175 #if defined (ACE_HAS_THREADS)
176 // Wait for the threads to terminate.
177 ACE_Thread_Manager::instance ()->wait ();
178 #else
179 malloc_recurse (Options::instance ()->iteration_count ());
180 #endif /* ACE_HAS_THREADS */
182 #if !defined (ACE_WIN32)
183 else
185 pid_t pid;
187 while ((pid = ACE_OS::wait (0)) != -1)
188 ACE_DEBUG ((LM_DEBUG, "(%P|%t) reaped pid = %d\n", pid));
190 #endif /* ACE_WIN32 */
193 extern "C" void
194 handler (int)
196 Malloc::instance ()->remove ();
197 ACE_ERROR ((LM_ERROR, "(%P|%t) removed handler\n%a", 0));
201 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
203 // Register a signal handler.
204 ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
205 ACE_UNUSED_ARG (sa);
207 Options::instance ()->parse_args (argc, argv);
209 #if !defined (ACE_WIN32)
210 if (Options::instance ()->child ())
212 ACE_DEBUG ((LM_INFO,
213 "(%P|%t) about to recurse with iteration count = %d, debug = %d\n",
214 Options::instance ()->iteration_count ()));
216 // We've been forked...
217 malloc_recurse (Options::instance ()->iteration_count ());
218 Malloc::instance ()->remove ();
220 else
221 #endif /* ACE_WIN32 */
223 for (size_t i = 0;
224 i < Options::instance ()->spawn_count ();
225 i++)
226 spawn ();
228 wait_for_children ();
229 Malloc::instance ()->remove ();
231 return 0;