genode/repos/libports/src/lib/libc/libc_mmap_registry.h
Norman Feske 17c79a9e23 base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.

While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).

To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.

Issue #1987
2016-08-29 17:27:10 +02:00

123 lines
2.4 KiB
C++

/*
* \brief Registry for keeping track of mmapped regions
* \author Norman Feske
* \date 2012-08-16
*/
#ifndef _LIBC_MMAP_REGISTRY_H_
#define _LIBC_MMAP_REGISTRY_H_
/* Genode includes */
#include <base/lock.h>
#include <base/env.h>
#include <base/log.h>
/* libc-internal includes */
#include <libc-plugin/plugin.h>
/* libc includes */
#include <errno.h>
namespace Libc {
class Mmap_registry;
/**
* Return singleton instance of mmap registry
*/
Mmap_registry *mmap_registry();
}
class Libc::Mmap_registry
{
public:
struct Entry : Genode::List<Entry>::Element
{
void * const start;
Plugin * const plugin;
Entry(void *start, Plugin *plugin)
: start(start), plugin(plugin) { }
};
private:
Genode::List<Mmap_registry::Entry> _list;
Genode::Lock mutable _lock;
/*
* Common for both const and non-const lookup functions
*/
template <typename ENTRY>
static ENTRY *_lookup_by_addr_unsynchronized(ENTRY *curr, void * const start)
{
for (; curr; curr = curr->next())
if (curr->start == start)
return curr;
return 0;
}
Entry const *_lookup_by_addr_unsynchronized(void * const start) const
{
return _lookup_by_addr_unsynchronized(_list.first(), start);
}
Entry *_lookup_by_addr_unsynchronized(void * const start)
{
return _lookup_by_addr_unsynchronized(_list.first(), start);
}
public:
void insert(void *start, Genode::size_t len, Plugin *plugin)
{
Genode::Lock::Guard guard(_lock);
if (_lookup_by_addr_unsynchronized(start)) {
Genode::warning(__func__, ": mmap region at ", start, " "
"is already registered");
return;
}
_list.insert(new (Genode::env()->heap()) Entry(start, plugin));
}
Plugin *lookup_plugin_by_addr(void *start) const
{
Genode::Lock::Guard guard(_lock);
Entry const * const e = _lookup_by_addr_unsynchronized(start);
return e ? e->plugin : 0;
}
bool registered(void *start) const
{
Genode::Lock::Guard guard(_lock);
return _lookup_by_addr_unsynchronized(start) != 0;
}
void remove(void *start)
{
Genode::Lock::Guard guard(_lock);
Entry *e = _lookup_by_addr_unsynchronized(start);
if (!e) {
Genode::warning("lookup for address ", start, " "
"in in mmap registry failed");
return;
}
_list.remove(e);
destroy(Genode::env()->heap(), e);
}
};
#endif /* _LIBC_MMAP_REGISTRY_H_ */