1e1c6140eSIngo Weinhold/*
2e1c6140eSIngo Weinhold * Copyright 2011, Michael Lotz <mmlr@mlotz.ch>.
3e1c6140eSIngo Weinhold * Copyright 2011, Ingo Weinhold <ingo_weinhold@gmx.de>.
4e1c6140eSIngo Weinhold *
5e1c6140eSIngo Weinhold * Distributed under the terms of the MIT License.
6e1c6140eSIngo Weinhold */
7e1c6140eSIngo Weinhold#ifndef SLAB_DEBUG_H
8e1c6140eSIngo Weinhold#define SLAB_DEBUG_H
9e1c6140eSIngo Weinhold
10e1c6140eSIngo Weinhold
1175088a86SMichael Lotz#include <AllocationTracking.h>
12e1c6140eSIngo Weinhold#include <debug.h>
13e1c6140eSIngo Weinhold#include <slab/Slab.h>
14e1c6140eSIngo Weinhold#include <tracing.h>
15e1c6140eSIngo Weinhold
16e1c6140eSIngo Weinhold#include "kernel_debug_config.h"
17e1c6140eSIngo Weinhold
18e1c6140eSIngo Weinhold
19e1c6140eSIngo Weinhold//#define TRACE_SLAB
20e1c6140eSIngo Weinhold#ifdef TRACE_SLAB
21e1c6140eSIngo Weinhold#define TRACE_CACHE(cache, format, args...) \
22e1c6140eSIngo Weinhold	dprintf("Cache[%p, %s] " format "\n", cache, cache->name , ##args)
23e1c6140eSIngo Weinhold#else
24e1c6140eSIngo Weinhold#define TRACE_CACHE(cache, format, bananas...) do { } while (0)
25e1c6140eSIngo Weinhold#endif
26e1c6140eSIngo Weinhold
27e1c6140eSIngo Weinhold
28e1c6140eSIngo Weinhold#define COMPONENT_PARANOIA_LEVEL	OBJECT_CACHE_PARANOIA
29e1c6140eSIngo Weinhold#include <debug_paranoia.h>
30e1c6140eSIngo Weinhold
31e1c6140eSIngo Weinhold
32e1c6140eSIngo Weinhold// Macros determining whether allocation tracking is actually available.
33e1c6140eSIngo Weinhold#define SLAB_OBJECT_CACHE_ALLOCATION_TRACKING (SLAB_ALLOCATION_TRACKING != 0 \
34e1c6140eSIngo Weinhold	&& SLAB_OBJECT_CACHE_TRACING != 0 \
35e1c6140eSIngo Weinhold	&& SLAB_OBJECT_CACHE_TRACING_STACK_TRACE > 0)
36e1c6140eSIngo Weinhold	// The object cache code needs to do allocation tracking.
37e1c6140eSIngo Weinhold#define SLAB_MEMORY_MANAGER_ALLOCATION_TRACKING (SLAB_ALLOCATION_TRACKING != 0 \
38e1c6140eSIngo Weinhold	&& SLAB_MEMORY_MANAGER_TRACING != 0 \
39e1c6140eSIngo Weinhold	&& SLAB_MEMORY_MANAGER_TRACING_STACK_TRACE > 0)
40e1c6140eSIngo Weinhold	// The memory manager code needs to do allocation tracking.
41e1c6140eSIngo Weinhold#define SLAB_ALLOCATION_TRACKING_AVAILABLE \
42e1c6140eSIngo Weinhold	(SLAB_OBJECT_CACHE_ALLOCATION_TRACKING \
43e1c6140eSIngo Weinhold		|| SLAB_MEMORY_MANAGER_ALLOCATION_TRACKING)
44e1c6140eSIngo Weinhold	// Guards code that is needed for either object cache or memory manager
45e1c6140eSIngo Weinhold	// allocation tracking.
46e1c6140eSIngo Weinhold
47e1c6140eSIngo Weinhold
48e1c6140eSIngo Weinholdstruct object_depot;
49e1c6140eSIngo Weinhold
50e1c6140eSIngo Weinhold
51e1c6140eSIngo Weinhold#if SLAB_ALLOCATION_TRACKING_AVAILABLE
52e1c6140eSIngo Weinhold
5350175c99SIngo Weinholdnamespace BKernel {
54e1c6140eSIngo Weinhold
5550175c99SIngo Weinholdclass AllocationTrackingCallback {
5650175c99SIngo Weinholdpublic:
5750175c99SIngo Weinhold	virtual						~AllocationTrackingCallback();
580422a0f3SIngo Weinhold
5950175c99SIngo Weinhold	virtual	bool				ProcessTrackingInfo(
6050175c99SIngo Weinhold									AllocationTrackingInfo* info,
61f606e8fdSIngo Weinhold									void* allocation,
6250175c99SIngo Weinhold									size_t allocationSize) = 0;
6350175c99SIngo Weinhold};
64f908ff9bSIngo Weinhold
6550175c99SIngo Weinhold}
6650175c99SIngo Weinhold
6750175c99SIngo Weinholdusing BKernel::AllocationTrackingCallback;
68f908ff9bSIngo Weinhold
69f908ff9bSIngo Weinhold#endif // SLAB_ALLOCATION_TRACKING_AVAILABLE
700422a0f3SIngo Weinhold
710422a0f3SIngo Weinhold
7250175c99SIngo Weinholdvoid		dump_object_depot(object_depot* depot);
7350175c99SIngo Weinholdint			dump_object_depot(int argCount, char** args);
7450175c99SIngo Weinholdint			dump_depot_magazine(int argCount, char** args);
7550175c99SIngo Weinhold
7650175c99SIngo Weinhold
77e1c6140eSIngo Weinhold#if PARANOID_KERNEL_MALLOC || PARANOID_KERNEL_FREE
78e1c6140eSIngo Weinholdstatic inline void*
79e1c6140eSIngo Weinholdfill_block(void* buffer, size_t size, uint32 pattern)
80e1c6140eSIngo Weinhold{
81e1c6140eSIngo Weinhold	if (buffer == NULL)
82e1c6140eSIngo Weinhold		return NULL;
83e1c6140eSIngo Weinhold
84e1c6140eSIngo Weinhold	size &= ~(sizeof(pattern) - 1);
85e1c6140eSIngo Weinhold	for (size_t i = 0; i < size / sizeof(pattern); i++)
86e1c6140eSIngo Weinhold		((uint32*)buffer)[i] = pattern;
87e1c6140eSIngo Weinhold
88e1c6140eSIngo Weinhold	return buffer;
89e1c6140eSIngo Weinhold}
90e1c6140eSIngo Weinhold#endif
91e1c6140eSIngo Weinhold
92e1c6140eSIngo Weinhold
93e1c6140eSIngo Weinholdstatic inline void*
94e1c6140eSIngo Weinholdfill_allocated_block(void* buffer, size_t size)
95e1c6140eSIngo Weinhold{
96e1c6140eSIngo Weinhold#if PARANOID_KERNEL_MALLOC
97e1c6140eSIngo Weinhold	return fill_block(buffer, size, 0xcccccccc);
98e1c6140eSIngo Weinhold#else
99e1c6140eSIngo Weinhold	return buffer;
100e1c6140eSIngo Weinhold#endif
101e1c6140eSIngo Weinhold}
102e1c6140eSIngo Weinhold
103e1c6140eSIngo Weinhold
104e1c6140eSIngo Weinholdstatic inline void*
105e1c6140eSIngo Weinholdfill_freed_block(void* buffer, size_t size)
106e1c6140eSIngo Weinhold{
107e1c6140eSIngo Weinhold#if PARANOID_KERNEL_FREE
108e1c6140eSIngo Weinhold	return fill_block(buffer, size, 0xdeadbeef);
109e1c6140eSIngo Weinhold#else
110e1c6140eSIngo Weinhold	return buffer;
111e1c6140eSIngo Weinhold#endif
112e1c6140eSIngo Weinhold}
113e1c6140eSIngo Weinhold
114e1c6140eSIngo Weinhold
115e1c6140eSIngo Weinhold#endif	// SLAB_DEBUG_H
116