µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
Memory management

C++ API memory management definitions. More...

Classes

class  os::rtos::memory::allocator_deleter< A >
 Allocator deleter. More...
 
class  os::rtos::memory::allocator_stateless_default_resource< T >
 Standard allocator based on the RTOS system default memory manager. More...
 
class  os::rtos::memory::allocator_stateless_polymorphic_synchronized< T, L, get_resource >
 Allocator using memory resources. More...
 
class  os::memory::block_pool
 Memory resource managing a pool of same size blocks, using an existing arena. More...
 
class  os::memory::block_pool_typed_allocated< T, A >
 Memory resource managing a dynamically allocated pool. of same size blocks of type T. More...
 
class  os::memory::block_pool_typed_inclusive< T, N >
 Memory resource managing an internal pool. of same size blocks of type T. More...
 
class  os::memory::first_fit_top
 Memory resource implementing the first fit, top-down allocation policies, using an existing arena. More...
 
class  os::memory::first_fit_top_allocated< A >
 Memory resource implementing the first fit, top-down allocation policies, using a dynamically allocated arena. More...
 
class  os::memory::first_fit_top_inclusive< N >
 Memory resource implementing the first fit, top-down allocation policies, using an internal arena. More...
 
class  os::memory::lifo
 Memory resource implementing the LIFO allocation/deallocation policies, using an existing arena. More...
 
class  os::memory::lifo_allocated< A >
 Memory resource implementing the LIFO allocation policies, using a dynamically allocated arena. More...
 
class  os::memory::lifo_inclusive< N >
 Memory resource implementing the LIFO allocation policies, using an internal arena. More...
 
class  os::memory::malloc_memory_resource
 A memory manager that allocates memory via the system std::malloc() and deallocates via std::free(). More...
 
class  os::rtos::memory::memory_resource
 Memory resource manager (abstract class). More...
 
class  os::memory::new_delete_memory_resource
 A memory manager that allocates memory via the system operator new and deallocates via operator delete. More...
 
class  os::memory::null_memory_resource
 An internal memory manager that throws a bad_alloc() exception when trying to allocate. More...
 

Typedefs

template<typename T >
using os::rtos::memory::allocator = allocator_stateless_default_resource< T >
 Type of allocator used by the system objects. Must be stateless.
 
template<typename T , typename U = T>
using os::rtos::memory::allocator_typed = allocator_stateless_polymorphic_synchronized< T, scheduler::lockable, get_resource_typed< U > >
 Type of an allocator for objects of type T.
 
using os::rtos::memory::out_of_memory_handler_t = void(*)(void)
 Type of out of memory handler.
 
template<typename T , typename U = T>
using os::rtos::memory::unique_ptr = std::unique_ptr< T, allocator_deleter< allocator_typed< T, U > > >
 Type of a RTOS unique pointer to objects of type T.
 

Functions

template<typename T , typename A , typename... Args>
auto os::rtos::memory::allocate_unique (const A &allocator, Args &&... args)
 Function template to allocate a unique pointer.
 
template<typename T , typename... Args>
std::enable_if<!std::is_array< T >::value, std::shared_ptr< T > >::type os::rtos::make_shared (Args &&... args)
 Create an object that is owned by a shared_ptr and is allocated using the RTOS system allocator.
 
void * operator new (std::size_t bytes)
 Allocate space for a new object instance.
 
template<typename T1 , typename T2 , typename L , F get_resource>
bool os::rtos::memory::operator!= (const allocator_stateless_polymorphic_synchronized< T1, L, get_resource > &lhs, const allocator_stateless_polymorphic_synchronized< T2, L, get_resource > &rhs) noexcept
 
template<typename T1 , typename T2 , typename L , F get_resource>
bool os::rtos::memory::operator== (const allocator_stateless_polymorphic_synchronized< T1, L, get_resource > &lhs, const allocator_stateless_polymorphic_synchronized< T2, L, get_resource > &rhs) noexcept
 

RTOS System Memory Functions

memory_resourceos::rtos::memory::malloc_resource (void) noexcept
 Get the address of a memory manager based on POSIX malloc().
 
memory_resourceos::rtos::memory::set_default_resource (memory_resource *res) noexcept
 Set the default RTOS system memory manager.
 
memory_resourceos::rtos::memory::get_default_resource (void) noexcept
 Get the default RTOS system memory manager.
 
void os::rtos::memory::init_once_default_resource (void)
 

Operators

bool os::rtos::memory::operator== (const memory_resource &lhs, const memory_resource &rhs) noexcept
 Compare the memory_resource instances for equality.
 
bool os::rtos::memory::operator!= (const memory_resource &lhs, const memory_resource &rhs) noexcept
 Compare the memory_resource instances for inequality.
 

Type Specific Resource Managers

template<typename T >
memory_resourceos::rtos::memory::set_resource_typed (memory_resource *res) noexcept
 Function template to set a memory resource.
 
template<typename T >
memory_resourceos::rtos::memory::get_resource_typed (void) noexcept
 Function template to get a memory resource.
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< thread > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< thread > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< condition_variable > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< condition_variable > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< event_flags > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< event_flags > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< memory_pool > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< memory_pool > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< message_queue > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< message_queue > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< mutex > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< mutex > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< semaphore > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< semaphore > (void) noexcept
 
template<>
memory_resourceos::rtos::memory::set_resource_typed< timer > (memory_resource *res) noexcept
 
template<>
memory_resourceos::rtos::memory::get_resource_typed< timer > (void) noexcept
 

Standard Memory Functions

memory_resourceos::estd::pmr::new_delete_resource (void) noexcept
 Get the address of a memory manager based on new/delete.
 
memory_resourceos::estd::pmr::null_memory_resource (void) noexcept
 Get the address of an ineffective memory manager.
 
memory_resourceos::estd::pmr::set_default_resource (memory_resource *res) noexcept
 Set the default application memory manager.
 
memory_resourceos::estd::pmr::get_default_resource (void) noexcept
 Get the default application memory manager.
 

Detailed Description

The µOS++ RTOS includes several advanced and flexible memory management features.

First, it defines a configurable memory manager for the application free store (also known as the "heap").

Second, it defines a separate memory manager to be used by the RTOS system objects. This separate manager can be configured to use any allocation policy. It may use either a statically or a dynamically allocated area.

The reason for the system memory manager is to allow RTOS system objects to be separated from application objects; this has several advantages:

Third, system objects that require dynamic memory may be created with custom allocators, defined by the user.

Access to the application memory manager is done using the standard functions:

The default application memory manager is set in the os_startup_initialize_free_store() function, called by the startup code when running on bare metal.

On synthetic POSIX platforms the default memory manager is os::memory::malloc_memory_resource, which uses memory from the system free store.

By default the RTOS system memory manager is the same as the application memory manager, but, for isolation reasons, it is recommended to define a separate memory manager for the RTOS system objects.

The basic memory management class is os::rtos::memory::memory_resource, which will be standard starting with C++17. The µOS++ version of this class includes several extensions, like out of memory processing and statistics (and this is the reason the class is not defined in os::estd).

Typedef Documentation

◆ allocator

template<typename T >
using os::rtos::memory::allocator = typedef allocator_stateless_default_resource<T>
Template Parameters
TType of elements to be allocated.

Definition at line 53 of file os-types.h.

◆ allocator_typed

Template Parameters
Ttype of object.

The allocator uses scheduler critical sections to be thread safe, and the default memory resource associated with the given type.

Definition at line 1074 of file os-memory.h.

◆ out_of_memory_handler_t

using os::rtos::memory::out_of_memory_handler_t = typedef void (*) (void)

Definition at line 141 of file os-memory.h.

◆ unique_ptr

template<typename T , typename U = T>
using os::rtos::memory::unique_ptr = typedef std::unique_ptr<T, allocator_deleter<allocator_typed<T, U> >>
Template Parameters
Ttype of object.

The type is based on the standard unique pointer, but with the specific RTOS deleter.

Definition at line 1086 of file os-memory.h.

Function Documentation

◆ allocate_unique()

template<typename T , typename A , typename... Args>
auto os::rtos::memory::allocate_unique ( const A &  allocator,
Args &&...  args 
)
Template Parameters
TType of object to be allocated.
AAllocator type.
ArgsVariable arguments list.
Parameters
allocatorReference to allocator.
argsArguments used to construct the object of type T.
Returns
A standard unique pointer with deleter.

◆ get_default_resource() [1/2]

memory_resource * os::estd::pmr::get_default_resource ( void  )
inlinenoexcept
Parameters
None.
Returns
Pointer to a memory manager object instance.

If not set explicitly by the user, this function will return an instance of malloc_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 181 of file memory_resource.

182 {
183 rtos::memory::init_once_default_resource ();
184 return default_resource;
185 }
memory_resource * default_resource

References os::estd::pmr::default_resource.

Referenced by calloc(), free(), malloc(), operator new(), os_terminate_goodbye(), and realloc().

◆ get_default_resource() [2/2]

memory_resource * os::rtos::memory::get_default_resource ( void  )
inlinenoexcept
Parameters
None.
Returns
Pointer to a memory manager object instance.

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1136 of file os-memory.h.

1137 {
1138 rtos::memory::init_once_default_resource ();
1139 return default_resource;
1140 }

References os::rtos::memory::init_once_default_resource().

Referenced by os_memory_get_default(), and os_terminate_goodbye().

◆ get_resource_typed()

template<typename T >
memory_resource * os::rtos::memory::get_resource_typed ( void  )
noexcept
Returns
Pointer to current memory resource.

◆ get_resource_typed< condition_variable >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< condition_variable > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1165 of file os-memory.h.

1167 {
1168 rtos::memory::init_once_default_resource ();
1169 return resource_condition_variable;
1170 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< event_flags >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< event_flags > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1180 of file os-memory.h.

1182 {
1183 rtos::memory::init_once_default_resource ();
1184 return resource_event_flags;
1185 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< memory_pool >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< memory_pool > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1195 of file os-memory.h.

1197 {
1198 rtos::memory::init_once_default_resource ();
1199 return resource_memory_pool;
1200 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< message_queue >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< message_queue > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1210 of file os-memory.h.

1212 {
1213 rtos::memory::init_once_default_resource ();
1214 return resource_message_queue;
1215 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< mutex >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< mutex > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1225 of file os-memory.h.

1227 {
1228 rtos::memory::init_once_default_resource ();
1229 return resource_mutex;
1230 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< semaphore >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< semaphore > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1240 of file os-memory.h.

1242 {
1243 rtos::memory::init_once_default_resource ();
1244 return resource_semaphore;
1245 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< thread >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< thread > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1150 of file os-memory.h.

1152 {
1153 rtos::memory::init_once_default_resource ();
1154 return resource_thread;
1155 }

References os::rtos::memory::init_once_default_resource().

◆ get_resource_typed< timer >()

template<>
memory_resource * os::rtos::memory::get_resource_typed< timer > ( void  )
inlinenoexcept

If not set explicitly by the user, this function will return an instance of null_memory_resource on bare metal platforms and of malloc_memory_resource on POSIX platforms.

Definition at line 1255 of file os-memory.h.

1257 {
1258 rtos::memory::init_once_default_resource ();
1259 return resource_timer;
1260 }

References os::rtos::memory::init_once_default_resource().

◆ init_once_default_resource()

◆ make_shared()

template<typename T , typename... Args>
std::enable_if<!std::is_array< T >::value, std::shared_ptr< T > >::type os::rtos::make_shared ( Args &&...  args)
inline
Parameters
argsArguments for the T object's constructor.
Returns
A shared_ptr that owns the newly created object.
Exceptions
*An exception may be thrown from allocate() or from the constructor of T.

Definition at line 177 of file os.h.

178 {
179 // -Wno-psabi to disble the ABI warning.
180 typedef typename std::remove_const<T>::type T_nc;
181 return std::allocate_shared<T> (memory::allocator<T_nc> (),
182 std::forward<Args> (args)...);
183 }

◆ malloc_resource()

memory_resource * os::rtos::memory::malloc_resource ( void  )
noexcept
Parameters
None.
Returns
Pointer to a memory manager object instance.
See also
malloc_memory_resource

Definition at line 190 of file os-memory.cpp.

191 {
192 return reinterpret_cast<memory_resource*> (&malloc_res);
193 }
rtos::memory::memory_resource memory_resource

◆ new_delete_resource()

memory_resource * os::estd::pmr::new_delete_resource ( void  )
noexcept
Parameters
None.
Returns
Pointer to a memory manager object instance.

◆ null_memory_resource()

memory_resource * os::estd::pmr::null_memory_resource ( void  )
noexcept
Parameters
None.
Returns
Pointer to a memory manager object instance.

◆ operator new()

void * operator new ( std::size_t  bytes)
Parameters
bytesNumber of bytes to allocate.
Returns
Pointer to allocated object.

The allocation function (3.7.4.1) called by a new-expression (5.3.4) to allocate a storage of size bytes suitably aligned to represent any object of that size.

Return a non-null pointer to suitably aligned storage (3.7.4), or else throw a bad-alloc exception. This requirement is binding on a replacement version of this function.

Note
A C++ program may define a function with this function signature that displaces the default version defined by the C++ standard library.
Warning
Cannot be invoked from Interrupt Service Routines.

Definition at line 136 of file new.cpp.

137{
139 if (bytes == 0)
140 {
141 bytes = 1;
142 }
143
144 // ----- Begin of critical section ------------------------------------------
146
147 while (true)
148 {
149 void* mem = estd::pmr::get_default_resource ()->allocate (bytes);
150
151 if (mem != nullptr)
152 {
153#if defined(OS_TRACE_LIBCPP_OPERATOR_NEW)
154 trace::printf ("::%s(%d)=%p\n", __func__, bytes, mem);
155#endif
156 return mem;
157 }
158
159 // If allocate() fails and there is a new_handler,
160 // call it to try free up memory.
161 if (new_handler_)
162 {
163 new_handler_ ();
164 }
165 else
166 {
168 }
169 }
170
171 // ----- End of critical section --------------------------------------------
172}
void * allocate(std::size_t bytes, std::size_t alignment=max_align)
Allocate a memory block.
Definition os-memory.h:1290
Scheduler critical section RAII helper.
Definition os-sched.h:171
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:59
memory_resource * get_default_resource(void) noexcept
Get the default application memory manager.
std::new_handler new_handler_
The current new handler.
Definition new.cpp:53
void __throw_bad_alloc(void)
bool in_handler_mode(void)
Check if the CPU is in handler mode.
Definition os-sched.h:1101

References os::estd::__throw_bad_alloc(), os::rtos::memory::memory_resource::allocate(), os::estd::pmr::get_default_resource(), os::rtos::interrupts::in_handler_mode(), anonymous_namespace{new.cpp}::new_handler_, and os::trace::printf().

◆ operator!=() [1/2]

template<typename T1 , typename T2 , typename L , F get_resource>
bool os::rtos::memory::operator!= ( const allocator_stateless_polymorphic_synchronized< T1, L, get_resource > &  lhs,
const allocator_stateless_polymorphic_synchronized< T2, L, get_resource > &  rhs 
)
noexcept

◆ operator!=() [2/2]

bool os::rtos::memory::operator!= ( const memory_resource lhs,
const memory_resource rhs 
)
inlinenoexcept
Parameters
lhsFirst instance to compare.
rhsSecond instance to compare.
Return values
trueThe two object memory_resource instances are not equal.
falseThe two object memory_resource instances are equal.

Definition at line 1470 of file os-memory.h.

1472 {
1473 return !(lhs == rhs);
1474 }

◆ operator==() [1/2]

template<typename T1 , typename T2 , typename L , F get_resource>
bool os::rtos::memory::operator== ( const allocator_stateless_polymorphic_synchronized< T1, L, get_resource > &  lhs,
const allocator_stateless_polymorphic_synchronized< T2, L, get_resource > &  rhs 
)
noexcept

◆ operator==() [2/2]

bool os::rtos::memory::operator== ( const memory_resource lhs,
const memory_resource rhs 
)
inlinenoexcept
Parameters
lhsFirst instance to compare.
rhsSecond instance to compare.
Return values
trueThe two object memory_resource instances are equal.
falseThe two object memory_resource instances are not equal.

Definition at line 1463 of file os-memory.h.

1465 {
1466 return &lhs == &rhs || lhs.is_equal (rhs);
1467 }

◆ set_default_resource() [1/2]

memory_resource * os::estd::pmr::set_default_resource ( memory_resource res)
noexcept
Parameters
resPointer to new memory manager object instance.
Returns
Pointer to previous memory manager object instance.

Definition at line 57 of file memory-resource.cpp.

58 {
59 trace::printf ("estd::pmr::%s(%p) \n", __func__, res);
60
62 default_resource = res;
63
64 return old;
65 }

References os::estd::pmr::default_resource, and os::trace::printf().

Referenced by os_startup_initialize_free_store().

◆ set_default_resource() [2/2]

memory_resource * os::rtos::memory::set_default_resource ( memory_resource res)
noexcept
Parameters
resPointer to new memory manager object instance.
Returns
Pointer to previous memory manager object instance.

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager handling the free RAM.

Warning
This function is not thread safe.

Definition at line 207 of file os-memory.cpp.

208 {
209 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
210
212 default_resource = res;
213
214 return old;
215 }

References os::trace::printf().

Referenced by os_startup_initialize_free_store().

◆ set_resource_typed()

template<typename T >
memory_resource * os::rtos::memory::set_resource_typed ( memory_resource res)
noexcept
Parameters
resPointer to memory resource.
Returns
Pointer to previous memory resource.

◆ set_resource_typed< condition_variable >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 244 of file os-memory.cpp.

246 {
247 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
248
249 memory_resource* old = resource_condition_variable;
250 resource_condition_variable = res;
251
252 return old;
253 }

References os::trace::printf().

◆ set_resource_typed< event_flags >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 262 of file os-memory.cpp.

264 {
265 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
266
267 memory_resource* old = resource_event_flags;
268 resource_event_flags = res;
269
270 return old;
271 }

References os::trace::printf().

◆ set_resource_typed< memory_pool >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 280 of file os-memory.cpp.

282 {
283 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
284
285 memory_resource* old = resource_memory_pool;
286 resource_memory_pool = res;
287
288 return old;
289 }

References os::trace::printf().

◆ set_resource_typed< message_queue >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 298 of file os-memory.cpp.

300 {
301 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
302
303 memory_resource* old = resource_message_queue;
304 resource_message_queue = res;
305
306 return old;
307 }

References os::trace::printf().

◆ set_resource_typed< mutex >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 316 of file os-memory.cpp.

318 {
319 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
320
321 memory_resource* old = resource_mutex;
322 resource_mutex = res;
323
324 return old;
325 }

References os::trace::printf().

◆ set_resource_typed< semaphore >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 334 of file os-memory.cpp.

336 {
337 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
338
339 memory_resource* old = resource_semaphore;
340 resource_semaphore = res;
341
342 return old;
343 }

References os::trace::printf().

◆ set_resource_typed< thread >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 226 of file os-memory.cpp.

228 {
229 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
230
231 memory_resource* old = resource_thread;
232 resource_thread = res;
233
234 return old;
235 }

References os::trace::printf().

◆ set_resource_typed< timer >()

On bare metal applications, this function is called from os_startup_initialize_free_store(), during the system startup, with a memory manager specific to this object type.

Definition at line 352 of file os-memory.cpp.

354 {
355 trace::printf ("rtos::memory::%s(%p) \n", __func__, res);
356
357 memory_resource* old = resource_timer;
358 resource_timer = res;
359
360 return old;
361 }

References os::trace::printf().