Add cmake option to enable/disable cache and alloc tracing.
This commit is contained in:
@@ -17,6 +17,11 @@ set(BUDDY_SYSTEM_FILE ${PROJECT_SOURCE_DIR}/src/mem/libbuddysystem.a)
|
|||||||
|
|
||||||
# Add the memory option.
|
# Add the memory option.
|
||||||
option(USE_BUDDY_SYSTEM "Build using the buddysystem written by the user." OFF)
|
option(USE_BUDDY_SYSTEM "Build using the buddysystem written by the user." OFF)
|
||||||
|
# Enables cache tracing.
|
||||||
|
option(ENABLE_CACHE_TRACE "Enables cache tracing." OFF)
|
||||||
|
# Enables memory allocation tracing.
|
||||||
|
option(ENABLE_ALLOC_TRACE "Enables memory allocation tracing." OFF)
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# ASSEMBLY
|
# ASSEMBLY
|
||||||
@@ -197,6 +202,18 @@ target_compile_definitions(
|
|||||||
__KERNEL__
|
__KERNEL__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Enables cache tracing.
|
||||||
|
if(ENABLE_CACHE_TRACE)
|
||||||
|
target_compile_definitions(${KERNEL_NAME} PUBLIC ENABLE_CACHE_TRACE)
|
||||||
|
endif(ENABLE_CACHE_TRACE)
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Enables memory allocation tracing.
|
||||||
|
if(ENABLE_ALLOC_TRACE)
|
||||||
|
target_compile_definitions(${KERNEL_NAME} PUBLIC ENABLE_ALLOC_TRACE)
|
||||||
|
endif(ENABLE_ALLOC_TRACE)
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Set the list of valid scheduling options.
|
# Set the list of valid scheduling options.
|
||||||
set(SCHEDULER_TYPES SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS SCHEDULER_EDF SCHEDULER_RM)
|
set(SCHEDULER_TYPES SCHEDULER_RR SCHEDULER_PRIORITY SCHEDULER_CFS SCHEDULER_EDF SCHEDULER_RM)
|
||||||
|
|||||||
+4
-15
@@ -9,9 +9,6 @@
|
|||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
#include "mem/gfp.h"
|
#include "mem/gfp.h"
|
||||||
|
|
||||||
//#define ENABLE_CACHE_TRACE
|
|
||||||
//#define ENABLE_ALLOC_TRACE
|
|
||||||
|
|
||||||
/// @brief Type for slab flags.
|
/// @brief Type for slab flags.
|
||||||
typedef unsigned int slab_flags_t;
|
typedef unsigned int slab_flags_t;
|
||||||
|
|
||||||
@@ -88,10 +85,6 @@ void kmem_cache_destroy(kmem_cache_t *cachep);
|
|||||||
|
|
||||||
#ifdef ENABLE_CACHE_TRACE
|
#ifdef ENABLE_CACHE_TRACE
|
||||||
|
|
||||||
#ifndef __FILENAME__
|
|
||||||
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// @brief Allocs a new object using the provided cache.
|
/// @brief Allocs a new object using the provided cache.
|
||||||
/// @param file File where the object is allocated.
|
/// @param file File where the object is allocated.
|
||||||
/// @param fun Function where the object is allocated.
|
/// @param fun Function where the object is allocated.
|
||||||
@@ -109,10 +102,10 @@ void *pr_kmem_cache_alloc(const char *file, const char *fun, int line, kmem_cach
|
|||||||
void pr_kmem_cache_free(const char *file, const char *fun, int line, void *addr);
|
void pr_kmem_cache_free(const char *file, const char *fun, int line, void *addr);
|
||||||
|
|
||||||
/// Wrapper that provides the filename, the function and line where the alloc is happening.
|
/// Wrapper that provides the filename, the function and line where the alloc is happening.
|
||||||
#define kmem_cache_alloc(...) pr_kmem_cache_alloc(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
|
#define kmem_cache_alloc(...) pr_kmem_cache_alloc(__FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
/// Wrapper that provides the filename, the function and line where the free is happening.
|
/// Wrapper that provides the filename, the function and line where the free is happening.
|
||||||
#define kmem_cache_free(...) pr_kmem_cache_free(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
|
#define kmem_cache_free(...) pr_kmem_cache_free(__FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/// @brief Allocs a new object using the provided cache.
|
/// @brief Allocs a new object using the provided cache.
|
||||||
@@ -129,10 +122,6 @@ void kmem_cache_free(void *addr);
|
|||||||
|
|
||||||
#ifdef ENABLE_ALLOC_TRACE
|
#ifdef ENABLE_ALLOC_TRACE
|
||||||
|
|
||||||
#ifndef __FILENAME__
|
|
||||||
#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// @brief Provides dynamically allocated memory in kernel space.
|
/// @brief Provides dynamically allocated memory in kernel space.
|
||||||
/// @param file File where the object is allocated.
|
/// @param file File where the object is allocated.
|
||||||
/// @param fun Function where the object is allocated.
|
/// @param fun Function where the object is allocated.
|
||||||
@@ -149,10 +138,10 @@ void *pr_kmalloc(const char *file, const char *fun, int line, unsigned int size)
|
|||||||
void pr_kfree(const char *file, const char *fun, int line, void *addr);
|
void pr_kfree(const char *file, const char *fun, int line, void *addr);
|
||||||
|
|
||||||
/// Wrapper that provides the filename, the function and line where the alloc is happening.
|
/// Wrapper that provides the filename, the function and line where the alloc is happening.
|
||||||
#define kmalloc(...) pr_kmalloc(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
|
#define kmalloc(...) pr_kmalloc(__FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
/// Wrapper that provides the filename, the function and line where the free is happening.
|
/// Wrapper that provides the filename, the function and line where the free is happening.
|
||||||
#define kfree(...) pr_kfree(__FILENAME__, __func__, __LINE__, __VA_ARGS__)
|
#define kfree(...) pr_kfree(__FILE__, __func__, __LINE__, __VA_ARGS__)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|||||||
+106
-88
@@ -158,11 +158,10 @@ void dynamic_timers_install()
|
|||||||
tvec_base_t *base = &cpu_base;
|
tvec_base_t *base = &cpu_base;
|
||||||
base->timer_ticks = 0;
|
base->timer_ticks = 0;
|
||||||
|
|
||||||
for(int i = 0; i < TVR_SIZE; ++i)
|
for (int i = 0; i < TVR_SIZE; ++i)
|
||||||
list_head_init(base->tv1.vec + i);
|
list_head_init(base->tv1.vec + i);
|
||||||
|
|
||||||
for(int i = 0; i < TVN_SIZE; ++i) {
|
for (int i = 0; i < TVN_SIZE; ++i) {
|
||||||
|
|
||||||
list_head_init(base->tv2.vec + i);
|
list_head_init(base->tv2.vec + i);
|
||||||
list_head_init(base->tv3.vec + i);
|
list_head_init(base->tv3.vec + i);
|
||||||
list_head_init(base->tv4.vec + i);
|
list_head_init(base->tv4.vec + i);
|
||||||
@@ -175,8 +174,8 @@ void dynamic_timers_install()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints used slots of timer vector
|
/// Prints used slots of timer vector
|
||||||
static void __print_tvec_slots(tvec_base_t *base, int tv_index) {
|
static void __print_tvec_slots(tvec_base_t *base, int tv_index)
|
||||||
|
{
|
||||||
if (tv_index < 0 || tv_index > 5)
|
if (tv_index < 0 || tv_index > 5)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -184,51 +183,57 @@ static void __print_tvec_slots(tvec_base_t *base, int tv_index) {
|
|||||||
char result[TVN_SIZE + 1];
|
char result[TVN_SIZE + 1];
|
||||||
result[TVN_SIZE] = '\0';
|
result[TVN_SIZE] = '\0';
|
||||||
|
|
||||||
struct timer_vec* tv = NULL;
|
struct timer_vec *tv = NULL;
|
||||||
switch(tv_index) {
|
switch (tv_index) {
|
||||||
|
// Root
|
||||||
// Root
|
case 1: {
|
||||||
case 1: {
|
pr_debug("base->tv1.vec:");
|
||||||
|
for (int i = 0; i < TVR_SIZE; ++i) {
|
||||||
pr_debug("base->tv1.vec:");
|
// New line in order to not clutter the screen
|
||||||
for(int i = 0; i < TVR_SIZE; ++i) {
|
int index = i % TVN_SIZE;
|
||||||
|
if (i != 0 && index == 0)
|
||||||
|
pr_debug("\n\t%s", result);
|
||||||
|
|
||||||
// New line in order to not clutter the screen
|
if (!list_head_empty(base->tv1.vec + i))
|
||||||
int index = i % TVN_SIZE;
|
result[index] = '1';
|
||||||
if (i != 0 && index == 0)
|
else
|
||||||
pr_debug("\n\t%s", result);
|
result[index] = '0';
|
||||||
|
}
|
||||||
|
|
||||||
if (!list_head_empty(base->tv1.vec + i))
|
// The last line
|
||||||
result[index] = '1';
|
pr_debug("\n\t%s\n", result);
|
||||||
else
|
return;
|
||||||
result[index] = '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// The last line
|
} break;
|
||||||
pr_debug("\n\t%s\n", result);
|
|
||||||
return;
|
|
||||||
|
|
||||||
} break;
|
// Normal
|
||||||
|
case 2:
|
||||||
// Normal
|
tv = &base->tv2;
|
||||||
case 2: tv = &base->tv2; break;
|
break;
|
||||||
case 3: tv = &base->tv3; break;
|
case 3:
|
||||||
case 4: tv = &base->tv4; break;
|
tv = &base->tv3;
|
||||||
case 5: tv = &base->tv5; break;
|
break;
|
||||||
|
case 4:
|
||||||
|
tv = &base->tv4;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
tv = &base->tv5;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < TVN_SIZE; ++i) {
|
for (int i = 0; i < TVN_SIZE; ++i) {
|
||||||
if (list_head_empty(tv->vec + i))
|
if (list_head_empty(tv->vec + i))
|
||||||
result[i] = '0';
|
result[i] = '0';
|
||||||
else
|
else
|
||||||
result[i] = '1';
|
result[i] = '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("base->tv%d.vec:\n\t%s\n", tv_index, result);
|
pr_debug("base->tv%d.vec:\n\t%s\n", tv_index, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dump all timer vector in base
|
/// Dump all timer vector in base
|
||||||
static inline void __dump_all_tvec_slots(tvec_base_t *base) {
|
static inline void __dump_all_tvec_slots(tvec_base_t *base)
|
||||||
|
{
|
||||||
__print_tvec_slots(base, 1);
|
__print_tvec_slots(base, 1);
|
||||||
__print_tvec_slots(base, 2);
|
__print_tvec_slots(base, 2);
|
||||||
__print_tvec_slots(base, 3);
|
__print_tvec_slots(base, 3);
|
||||||
@@ -238,13 +243,13 @@ static inline void __dump_all_tvec_slots(tvec_base_t *base) {
|
|||||||
|
|
||||||
/// Select correct timer vector and position inside of it for the input timer
|
/// Select correct timer vector and position inside of it for the input timer
|
||||||
/// index contains the position inside of the tv_index timer vector
|
/// index contains the position inside of the tv_index timer vector
|
||||||
static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int* index, int* tv_index)
|
static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int *index, int *tv_index)
|
||||||
{
|
{
|
||||||
assert(index && "index is NULL");
|
assert(index && "index is NULL");
|
||||||
assert(tv_index && "tv_index is NULL");
|
assert(tv_index && "tv_index is NULL");
|
||||||
|
|
||||||
unsigned long expires = timer->expires;
|
unsigned long expires = timer->expires;
|
||||||
unsigned long ticks = expires - base->timer_ticks;
|
unsigned long ticks = expires - base->timer_ticks;
|
||||||
|
|
||||||
unsigned long tv1_ticks = TIMER_TICKS(0);
|
unsigned long tv1_ticks = TIMER_TICKS(0);
|
||||||
unsigned long tv2_ticks = TIMER_TICKS(1);
|
unsigned long tv2_ticks = TIMER_TICKS(1);
|
||||||
@@ -253,49 +258,59 @@ static void __find_tvec(tvec_base_t *base, struct timer_list *timer, int* index,
|
|||||||
|
|
||||||
// Can happen if you add a timer with expires == ticks, or in the past
|
// Can happen if you add a timer with expires == ticks, or in the past
|
||||||
if ((signed long)ticks < 0) {
|
if ((signed long)ticks < 0) {
|
||||||
*index = base->timer_ticks & TVR_MASK;
|
*index = base->timer_ticks & TVR_MASK;
|
||||||
*tv_index = 1;
|
*tv_index = 1;
|
||||||
}
|
}
|
||||||
// tv1
|
// tv1
|
||||||
else if (ticks < tv1_ticks) {
|
else if (ticks < tv1_ticks) {
|
||||||
*index = expires & TVR_MASK;
|
*index = expires & TVR_MASK;
|
||||||
*tv_index = 1;
|
*tv_index = 1;
|
||||||
}
|
}
|
||||||
// tv2
|
// tv2
|
||||||
else if (ticks < tv2_ticks) {
|
else if (ticks < tv2_ticks) {
|
||||||
*index = (expires >> TIMER_TICKS_BITS(0)) & TVN_MASK;
|
*index = (expires >> TIMER_TICKS_BITS(0)) & TVN_MASK;
|
||||||
*tv_index = 2;
|
*tv_index = 2;
|
||||||
}
|
}
|
||||||
// tv3
|
// tv3
|
||||||
else if (ticks < tv3_ticks) {
|
else if (ticks < tv3_ticks) {
|
||||||
*index = (expires >> TIMER_TICKS_BITS(1)) & TVN_MASK;
|
*index = (expires >> TIMER_TICKS_BITS(1)) & TVN_MASK;
|
||||||
*tv_index = 3;
|
*tv_index = 3;
|
||||||
}
|
}
|
||||||
// tv4
|
// tv4
|
||||||
else if (ticks < tv4_ticks) {
|
else if (ticks < tv4_ticks) {
|
||||||
*index = (expires >> TIMER_TICKS_BITS(2)) & TVN_MASK;
|
*index = (expires >> TIMER_TICKS_BITS(2)) & TVN_MASK;
|
||||||
*tv_index = 4;
|
*tv_index = 4;
|
||||||
}
|
}
|
||||||
// tv5
|
// tv5
|
||||||
else {
|
else {
|
||||||
*index = (expires >> TIMER_TICKS_BITS(3)) & TVN_MASK;
|
*index = (expires >> TIMER_TICKS_BITS(3)) & TVN_MASK;
|
||||||
*tv_index = 5;
|
*tv_index = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add timers into different lists based on their expire time
|
/// Add timers into different lists based on their expire time
|
||||||
static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) {
|
static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
|
||||||
|
{
|
||||||
int index = 0, tv_index = 0;
|
int index = 0, tv_index = 0;
|
||||||
__find_tvec(base, timer, &index, &tv_index);
|
__find_tvec(base, timer, &index, &tv_index);
|
||||||
|
|
||||||
struct list_head* vec;
|
struct list_head *vec;
|
||||||
switch(tv_index) {
|
switch (tv_index) {
|
||||||
case 1: vec = base->tv1.vec + index; break;
|
case 1:
|
||||||
case 2: vec = base->tv2.vec + index; break;
|
vec = base->tv1.vec + index;
|
||||||
case 3: vec = base->tv3.vec + index; break;
|
break;
|
||||||
case 4: vec = base->tv4.vec + index; break;
|
case 2:
|
||||||
case 5: vec = base->tv5.vec + index; break;
|
vec = base->tv2.vec + index;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vec = base->tv3.vec + index;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
vec = base->tv4.vec + index;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
vec = base->tv5.vec + index;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index);
|
pr_debug("Adding timer at time_index: %d in tv%d\n", index, tv_index);
|
||||||
@@ -304,22 +319,31 @@ static void __add_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) {
|
|||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
||||||
__dump_all_tvec_slots(base);
|
__dump_all_tvec_slots(base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove timer from tvec_base
|
/// Remove timer from tvec_base
|
||||||
static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) {
|
static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer)
|
||||||
|
{
|
||||||
int index = 0, tv_index = 0;
|
int index = 0, tv_index = 0;
|
||||||
__find_tvec(base, timer, &index, &tv_index);
|
__find_tvec(base, timer, &index, &tv_index);
|
||||||
|
|
||||||
struct list_head* vec;
|
struct list_head *vec;
|
||||||
switch(tv_index) {
|
switch (tv_index) {
|
||||||
case 1: vec = base->tv1.vec + index; break;
|
case 1:
|
||||||
case 2: vec = base->tv2.vec + index; break;
|
vec = base->tv1.vec + index;
|
||||||
case 3: vec = base->tv3.vec + index; break;
|
break;
|
||||||
case 4: vec = base->tv4.vec + index; break;
|
case 2:
|
||||||
case 5: vec = base->tv5.vec + index; break;
|
vec = base->tv2.vec + index;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
vec = base->tv3.vec + index;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
vec = base->tv4.vec + index;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
vec = base->tv5.vec + index;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index);
|
pr_debug("Removing timer at time_index: %d in tv%d\n", index, tv_index);
|
||||||
@@ -327,13 +351,12 @@ static void __rem_timer_tvec_base(tvec_base_t *base, struct timer_list *timer) {
|
|||||||
|
|
||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
#ifdef ENABLE_REAL_TIMER_SYSTEM_DUMP
|
||||||
__dump_all_tvec_slots(base);
|
__dump_all_tvec_slots(base);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move all timers from tv up one level
|
/// Move all timers from tv up one level
|
||||||
static int cascate(tvec_base_t* base, timer_vec* tv, int time_index, int tv_index) {
|
static int cascate(tvec_base_t *base, timer_vec *tv, int time_index, int tv_index)
|
||||||
|
{
|
||||||
if (!list_head_empty(tv->vec + time_index)) {
|
if (!list_head_empty(tv->vec + time_index)) {
|
||||||
pr_debug("Relocating timers in tv%d.vec[%d]\n", tv_index, time_index);
|
pr_debug("Relocating timers in tv%d.vec[%d]\n", tv_index, time_index);
|
||||||
|
|
||||||
@@ -345,7 +368,6 @@ static int cascate(tvec_base_t* base, timer_vec* tv, int time_index, int tv_inde
|
|||||||
|
|
||||||
__add_timer_tvec_base(base, timer);
|
__add_timer_tvec_base(base, timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return time_index;
|
return time_index;
|
||||||
}
|
}
|
||||||
@@ -360,17 +382,15 @@ void run_timer_softirq()
|
|||||||
// While we are not up to date with current ticks
|
// While we are not up to date with current ticks
|
||||||
unsigned long current_ticks = timer_get_ticks();
|
unsigned long current_ticks = timer_get_ticks();
|
||||||
while (base->timer_ticks <= current_ticks) {
|
while (base->timer_ticks <= current_ticks) {
|
||||||
|
|
||||||
// Index of the current timer to execute
|
// Index of the current timer to execute
|
||||||
int current_time_index = base->timer_ticks & TVR_MASK;
|
int current_time_index = base->timer_ticks & TVR_MASK;
|
||||||
|
|
||||||
// If the index is zero then all lists in base->tv1 have been checked, so they are empty
|
// If the index is zero then all lists in base->tv1 have been checked, so they are empty
|
||||||
if (!current_time_index) {
|
if (!current_time_index) {
|
||||||
|
// Consider the first invocation of the cascade() function: it receives as arguments
|
||||||
// Consider the first invocation of the cascade() function: it receives as arguments
|
|
||||||
// the address in base, the address of base->tv2, and the index of the list
|
// the address in base, the address of base->tv2, and the index of the list
|
||||||
// in base->tv2 including the timers that will decay in the next 256 ticks. This
|
// in base->tv2 including the timers that will decay in the next 256 ticks. This
|
||||||
// index is determined by looking at the proper bits of the base->timer_ticks value.
|
// index is determined by looking at the proper bits of the base->timer_ticks value.
|
||||||
// cascade() moves all dynamic timers in the base->tv2 list into the
|
// cascade() moves all dynamic timers in the base->tv2 list into the
|
||||||
// proper lists of base->tv1; then, it returns a positive value, unless all base->tv2
|
// proper lists of base->tv1; then, it returns a positive value, unless all base->tv2
|
||||||
// lists are now empty. If so, cascade() is invoked once more to replenish
|
// lists are now empty. If so, cascade() is invoked once more to replenish
|
||||||
@@ -381,16 +401,17 @@ void run_timer_softirq()
|
|||||||
int tv4_index = (base->timer_ticks >> TIMER_TICKS_BITS(2)) & TVN_MASK;
|
int tv4_index = (base->timer_ticks >> TIMER_TICKS_BITS(2)) & TVN_MASK;
|
||||||
int tv5_index = (base->timer_ticks >> TIMER_TICKS_BITS(3)) & TVN_MASK;
|
int tv5_index = (base->timer_ticks >> TIMER_TICKS_BITS(3)) & TVN_MASK;
|
||||||
|
|
||||||
if (!cascate(base, &base->tv2, tv2_index, 2) &&
|
if (!cascate(base, &base->tv2, tv2_index, 2) &&
|
||||||
!cascate(base, &base->tv3, tv3_index, 3) &&
|
!cascate(base, &base->tv3, tv3_index, 3) &&
|
||||||
!cascate(base, &base->tv4, tv4_index, 4) &&
|
!cascate(base, &base->tv4, tv4_index, 4) &&
|
||||||
!cascate(base, &base->tv5, tv5_index, 5));
|
!cascate(base, &base->tv5, tv5_index, 5))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are timers to execute in this instant
|
// If there are timers to execute in this instant
|
||||||
if (!list_head_empty(&base->tv1.vec[current_time_index])) {
|
if (!list_head_empty(&base->tv1.vec[current_time_index])) {
|
||||||
pr_notice("Executing dynamic timers at %d ticks from start inside of tv1.vec[%d]\n",
|
pr_debug("Executing dynamic timers at %d ticks from start inside of tv1.vec[%d]\n",
|
||||||
base->timer_ticks, current_time_index);
|
base->timer_ticks, current_time_index);
|
||||||
|
|
||||||
// Trigger all timers
|
// Trigger all timers
|
||||||
struct list_head *it, *tmp;
|
struct list_head *it, *tmp;
|
||||||
@@ -399,7 +420,7 @@ void run_timer_softirq()
|
|||||||
|
|
||||||
// Executes timer function
|
// Executes timer function
|
||||||
spinlock_unlock(&base->lock);
|
spinlock_unlock(&base->lock);
|
||||||
pr_notice("Executing dynamic timer function...\n");
|
pr_debug("Executing dynamic timer function...\n");
|
||||||
timer->function(timer->data);
|
timer->function(timer->data);
|
||||||
spinlock_lock(&base->lock);
|
spinlock_lock(&base->lock);
|
||||||
|
|
||||||
@@ -426,12 +447,12 @@ void run_timer_softirq()
|
|||||||
|
|
||||||
// Executes timer function
|
// Executes timer function
|
||||||
spinlock_unlock(&base->lock);
|
spinlock_unlock(&base->lock);
|
||||||
pr_notice("Executing dynamic timer function...\n");
|
pr_debug("Executing dynamic timer function...\n");
|
||||||
timer->function(timer->data);
|
timer->function(timer->data);
|
||||||
spinlock_lock(&base->lock);
|
spinlock_lock(&base->lock);
|
||||||
|
|
||||||
// Removes timer from list
|
// Removes timer from list
|
||||||
pr_notice("Removing dynamic timer...\n");
|
pr_debug("Removing dynamic timer...\n");
|
||||||
list_head_del(it);
|
list_head_del(it);
|
||||||
kfree(timer);
|
kfree(timer);
|
||||||
}
|
}
|
||||||
@@ -453,27 +474,25 @@ void init_timer(struct timer_list *timer)
|
|||||||
void add_timer(struct timer_list *timer)
|
void add_timer(struct timer_list *timer)
|
||||||
{
|
{
|
||||||
tvec_base_t *base = &cpu_base;
|
tvec_base_t *base = &cpu_base;
|
||||||
timer->base = base;
|
timer->base = base;
|
||||||
|
|
||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
||||||
__add_timer_tvec_base(base, timer);
|
__add_timer_tvec_base(base, timer);
|
||||||
#else
|
#else
|
||||||
list_head_add_tail(&timer->entry, &base->list);
|
list_head_add_tail(&timer->entry, &base->list);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_timer(struct timer_list *timer)
|
void del_timer(struct timer_list *timer)
|
||||||
{
|
{
|
||||||
tvec_base_t *base = &cpu_base;
|
tvec_base_t *base = &cpu_base;
|
||||||
timer->base = NULL;
|
timer->base = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
#ifdef ENABLE_REAL_TIMER_SYSTEM
|
||||||
__rem_timer_tvec_base(base, timer);
|
__rem_timer_tvec_base(base, timer);
|
||||||
#else
|
#else
|
||||||
list_head_del(&timer->entry);
|
list_head_del(&timer->entry);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================================
|
//======================================================================================
|
||||||
@@ -483,8 +502,7 @@ void del_timer(struct timer_list *timer)
|
|||||||
/// @param data The data.
|
/// @param data The data.
|
||||||
static inline void debug_timeout(unsigned long data)
|
static inline void debug_timeout(unsigned long data)
|
||||||
{
|
{
|
||||||
pr_notice("Il timer è stato attivato con successo: %d, ticks: %d, seconds: %d\n",
|
pr_debug("The timer has been successfully deactivated: %d, ticks: %d, seconds: %d\n", data, timer_ticks, timer_get_seconds());
|
||||||
data, timer_ticks, timer_get_seconds());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Contains the entry of a wait queue and timespec which keeps trakc of
|
/// @brief Contains the entry of a wait queue and timespec which keeps trakc of
|
||||||
@@ -497,7 +515,7 @@ typedef struct sleep_data_t {
|
|||||||
} sleep_data_t;
|
} sleep_data_t;
|
||||||
|
|
||||||
/// @brief Callback for when a sleep timer expires
|
/// @brief Callback for when a sleep timer expires
|
||||||
/// @param data Custom data stored in the timer
|
/// @param data Custom data stored in the timer
|
||||||
void sleep_timeout(unsigned long data)
|
void sleep_timeout(unsigned long data)
|
||||||
{
|
{
|
||||||
// NOTE: We could modify the sleep_on and make it return the wait_queue_entry_t
|
// NOTE: We could modify the sleep_on and make it return the wait_queue_entry_t
|
||||||
@@ -550,7 +568,7 @@ int sys_nanosleep(const timespec *req, timespec *rem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Function executed when the real_timer of a process expires, sends SIGALRM to process.
|
/// @brief Function executed when the real_timer of a process expires, sends SIGALRM to process.
|
||||||
/// @param pid PID of the process whos associated timer has expired
|
/// @param pid PID of the process whos associated timer has expired
|
||||||
void alarm_timeout(unsigned long pid)
|
void alarm_timeout(unsigned long pid)
|
||||||
{
|
{
|
||||||
sys_kill(pid, SIGALRM);
|
sys_kill(pid, SIGALRM);
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ void *kmem_cache_alloc(kmem_cache_t *cachep, gfp_t flags)
|
|||||||
list_head_add(slab_full_elem, &cachep->slabs_full);
|
list_head_add(slab_full_elem, &cachep->slabs_full);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_CACHE_TRACE
|
#ifdef ENABLE_CACHE_TRACE
|
||||||
pr_notice("kmem_cache_alloc : (%-16s:%3d)[%-16s] : 0x%p\n", file, line, cachep->name, ptr);
|
pr_notice("CHACE-ALLOC 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line);
|
||||||
#endif
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ void kmem_cache_free(void *ptr)
|
|||||||
kmem_cache_t *cachep = slab_page->container.slab_cache;
|
kmem_cache_t *cachep = slab_page->container.slab_cache;
|
||||||
|
|
||||||
#ifdef ENABLE_CACHE_TRACE
|
#ifdef ENABLE_CACHE_TRACE
|
||||||
pr_notice("kmem_cache_free : (%-16s:%3d)[%-16s] : 0x%p\n", file, line, cachep->name, ptr);
|
pr_notice("CHACE-FREE 0x%p in %-20s at %s:%d\n", ptr, cachep->name, file, line);
|
||||||
#endif
|
#endif
|
||||||
if (cachep->dtor)
|
if (cachep->dtor)
|
||||||
cachep->dtor(ptr);
|
cachep->dtor(ptr);
|
||||||
@@ -332,7 +332,7 @@ void *kmalloc(unsigned int size)
|
|||||||
ptr = kmem_cache_alloc(malloc_blocks[order], GFP_KERNEL);
|
ptr = kmem_cache_alloc(malloc_blocks[order], GFP_KERNEL);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_ALLOC_TRACE
|
#ifdef ENABLE_ALLOC_TRACE
|
||||||
pr_notice("kmalloc : (%-16s:%3d) : 0x%p\n", file, line, ptr);
|
pr_notice("KMALLOC 0x%p at %s:%d\n", ptr, file, line);
|
||||||
#endif
|
#endif
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ void kfree(void *ptr)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_ALLOC_TRACE
|
#ifdef ENABLE_ALLOC_TRACE
|
||||||
pr_notice("kfree : (%-16s:%3d) : 0x%p\n", file, line, ptr);
|
pr_notice("KFREE 0x%p at %s:%d\n", ptr, file, line);
|
||||||
#endif
|
#endif
|
||||||
page_t *page = get_lowmem_page_from_address((uint32_t)ptr);
|
page_t *page = get_lowmem_page_from_address((uint32_t)ptr);
|
||||||
|
|
||||||
|
|||||||
@@ -360,7 +360,7 @@ static void __do_signal_stop(struct task_struct *current, struct pt_regs *f, int
|
|||||||
// the SA_NOCLDSTOP flag of SIGCHLD.
|
// the SA_NOCLDSTOP flag of SIGCHLD.
|
||||||
if (!(SA_NOCLDSTOP & current->parent->sighand.action[SIGCHLD - 1].sa_flags))
|
if (!(SA_NOCLDSTOP & current->parent->sighand.action[SIGCHLD - 1].sa_flags))
|
||||||
if (__notify_parent(current, SIGCHLD) != 0)
|
if (__notify_parent(current, SIGCHLD) != 0)
|
||||||
pr_debug("Failed to notify parent with signal: %d", signr);
|
pr_warning("Failed to notify parent with signal: %d", signr);
|
||||||
|
|
||||||
// The state is now TASK_UNINTERRUPTABLE
|
// The state is now TASK_UNINTERRUPTABLE
|
||||||
sleep_on(&stopped_queue);
|
sleep_on(&stopped_queue);
|
||||||
@@ -410,7 +410,7 @@ int do_signal(struct pt_regs *f)
|
|||||||
// If its value is 0, it means that all pending signals have been
|
// If its value is 0, it means that all pending signals have been
|
||||||
// handled and do_signal( ) can finish.
|
// handled and do_signal( ) can finish.
|
||||||
if (signr == 0) {
|
if (signr == 0) {
|
||||||
pr_notice("There are no more signals to handle.\n");
|
pr_debug("There are no more signals to handle.\n");
|
||||||
__unlock_task_sighand(current);
|
__unlock_task_sighand(current);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -633,7 +633,7 @@ int sys_kill(pid_t pid, int sig)
|
|||||||
|
|
||||||
sighandler_t sys_signal(int signum, sighandler_t handler)
|
sighandler_t sys_signal(int signum, sighandler_t handler)
|
||||||
{
|
{
|
||||||
pr_notice("sys_signal(%d, %p)\n", signum, handler);
|
pr_debug("sys_signal(%d, %p)\n", signum, handler);
|
||||||
// Check the signal that we want to send.
|
// Check the signal that we want to send.
|
||||||
if ((signum < 0) || (signum >= NSIG)) {
|
if ((signum < 0) || (signum >= NSIG)) {
|
||||||
pr_err("sys_signal(%d, %p): Wrong signal number!\n", signum, handler);
|
pr_err("sys_signal(%d, %p): Wrong signal number!\n", signum, handler);
|
||||||
@@ -645,7 +645,7 @@ sighandler_t sys_signal(int signum, sighandler_t handler)
|
|||||||
assert(current && "There is no running process.");
|
assert(current && "There is no running process.");
|
||||||
// Skip the `init` process, always.
|
// Skip the `init` process, always.
|
||||||
if (current->pid == 1) {
|
if (current->pid == 1) {
|
||||||
pr_err("sys_signal(%d, %p): Cannot signal number!\n", signum, handler);
|
pr_err("sys_signal(%d, %p): Cannot signal init!\n", signum, handler);
|
||||||
return SIG_ERR;
|
return SIG_ERR;
|
||||||
}
|
}
|
||||||
// Create a new signal action.
|
// Create a new signal action.
|
||||||
@@ -677,7 +677,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
|||||||
pr_debug("sys_sigaction(%d, %p, %p)\n", signum, act, oldact);
|
pr_debug("sys_sigaction(%d, %p, %p)\n", signum, act, oldact);
|
||||||
// Check the signal that we want to send.
|
// Check the signal that we want to send.
|
||||||
if ((signum < 0) || (signum >= NSIG)) {
|
if ((signum < 0) || (signum >= NSIG)) {
|
||||||
pr_debug("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact);
|
pr_err("sys_sigaction(%d, %p, %p): Wrong signal number!\n", signum, act, oldact);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
// The do_signal() function is usually only invoked when the CPU is going
|
// The do_signal() function is usually only invoked when the CPU is going
|
||||||
@@ -686,7 +686,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
|||||||
assert(current && "There is no running process.");
|
assert(current && "There is no running process.");
|
||||||
// Skip the `init` process, always.
|
// Skip the `init` process, always.
|
||||||
if (current->pid == 1) {
|
if (current->pid == 1) {
|
||||||
pr_debug("sys_sigaction(%d, %p, %p): Cannot set signal for init!\n", signum, act, oldact);
|
pr_err("sys_sigaction(%d, %p, %p): Cannot set signal for init!\n", signum, act, oldact);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
// Lock the signal handling for the given task.
|
// Lock the signal handling for the given task.
|
||||||
@@ -708,7 +708,7 @@ int sys_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
|
|||||||
|
|
||||||
int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
||||||
{
|
{
|
||||||
pr_notice("sys_sigprocmask(%d, %p, %p)\n", how, set, oldset);
|
pr_debug("sys_sigprocmask(%d, %p, %p)\n", how, set, oldset);
|
||||||
if (!set && !oldset) {
|
if (!set && !oldset) {
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
@@ -721,7 +721,7 @@ int sys_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
|
|||||||
assert(current && "There is no running process.");
|
assert(current && "There is no running process.");
|
||||||
// Skip the `init` process, always.
|
// Skip the `init` process, always.
|
||||||
if (current->pid == 1) {
|
if (current->pid == 1) {
|
||||||
pr_notice("sys_sigprocmask(%d, %p, %p): Cannot set signal for init!\n", how, set, oldset);
|
pr_warning("sys_sigprocmask(%d, %p, %p): Cannot set signal for init!\n", how, set, oldset);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
// If `oldset` is not, return the old set.
|
// If `oldset` is not, return the old set.
|
||||||
|
|||||||
Reference in New Issue
Block a user