Skip to content

Commit

Permalink
homework: linked lists task code
Browse files Browse the repository at this point in the history
  • Loading branch information
eabatalov committed Feb 17, 2016
1 parent 5b77e04 commit 1ecedfc
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tasks/linked_lists/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
MOD_NAME := linked_lists

ifneq ($(KERNELRELEASE),)
obj-m := $(MOD_NAME).o
$(MOD_NAME)-objs := module.o stack.o
else
KDIR := ../../linux/
VM_PATH := ../../../vm/
all:
$(MAKE) -C $(KDIR) M=$$PWD
cp $(MOD_NAME).ko $(VM_PATH)/share/

clean:
$(MAKE) -C $(KDIR) M=$$PWD clean
endif
10 changes: 10 additions & 0 deletions tasks/linked_lists/assert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#ifndef _LL_ASSERT_H
#define _LL_ASSERT_H

#define assert(expr) \
if(unlikely(!(expr))) { \
panic("Assertion failed! %s,%s,%s,line=%d\n", \
#expr, __FILE__, __FUNCTION__, __LINE__); \
}

#endif //_LL_ASSERT_H
60 changes: 60 additions & 0 deletions tasks/linked_lists/module.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>

#include "stack.h"
#include "assert.h"

static void __init test_stack(void)
{
LIST_HEAD(data_stack);
stack_entry_t *tos = NULL;
const char *tos_data = NULL;
const char* test_data[] = { "1", "2", "3", "4" };
unsigned long i = 0;

pr_alert("Testing basic stack");

for (i = 0; i != ARRAY_SIZE(test_data); ++i) {
stack_push(&data_stack,
create_stack_entry((void*)test_data[i])
);
}

for (i = ARRAY_SIZE(test_data) - 1; i >= 0; --i) {
tos = stack_pop(&data_stack);
tos_data = STACK_ENTRY_DATA(tos, const char*);
delete_stack_entry(tos);
printk(KERN_ALERT "%s == %s\n", tos_data, test_data[i]);
assert(!strcmp(tos_data, test_data[i]));
}

assert(stack_empty(&data_stack));
}

static void __init print_processes_backwards(void)
{
// TODO
}

static int __init ll_init(void)
{
printk(KERN_ALERT "Hello, linked_lists\n");
test_stack();
print_processes_backwards();
return 0;
}

static void __exit ll_exit(void)
{
printk(KERN_ALERT "Goodbye, linked_lists!\n");
}

module_init(ll_init);
module_exit(ll_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Linked list exercise module");
MODULE_AUTHOR("Kernel hacker!");
28 changes: 28 additions & 0 deletions tasks/linked_lists/stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "stack.h"

stack_entry_t* create_stack_entry(void *data)
{
// TODO
(void)data;
return NULL;
}

void delete_stack_entry(stack_entry_t *entry)
{
// TODO
(void)entry;
}

void stack_push(struct list_head *stack, stack_entry_t *entry)
{
// TODO
(void)stack;
(void)entry;
}

stack_entry_t* stack_pop(struct list_head *stack)
{
// TODO
(void)stack;
return NULL;
}
25 changes: 25 additions & 0 deletions tasks/linked_lists/stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef _LL_STACK_H
#define _LL_STACK_H
#include <linux/list.h>

typedef struct stack_entry {
struct list_head lh;
void *data;
} stack_entry_t;

stack_entry_t* create_stack_entry(void *data);
void delete_stack_entry(stack_entry_t *entry);

void stack_push(struct list_head *stack, stack_entry_t *entry);
stack_entry_t* stack_pop(struct list_head *stack);
#define stack_empty(stack) list_empty((stack))

#define STACK_ENTRY_DATA(stack_entry, data_ptr_type) \
((data_ptr_type)(stack_entry)->data)

#define STACK_ENTRY_DATA_RESET(stack_entry, new_data) \
do { \
(stack_entry)->data = new_data; \
} while(0)

#endif //_LL_STACK_H
19 changes: 19 additions & 0 deletions tasks/linked_lists/task.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
1. Реализовать в файле stack.c интерфейс стека,
описанный в файле stack.h. Вам поможет тест test_stack().
Используйте динамическую аллокацию памяти функцией kmalloc с флагом
GFP_KERNEL. Для деаллокации используйте парную ей kfree.
Включите header'ы linux/slab.h, linux/gfp.h.

2. В функции print_processes_backwards() необходимо
обойти все процессы, запущенные в ОС в данный момент
в порядке, обратном к обходу макросом for_each_process().
В процессе обхода нужно печатать название исполняемого файла
каждого процесса в ядерный лог.
Названия исполняемого файла получать с помощью get_task_comm(...).
Процессы можно обходить только с помощью for_each_process().
Обратный порядок вывода нужно реализовать не меняя порядка обхода.
Не забывайте, что вы используете глобальный список процессов
и на каждой итерации for_each_process вам доступен только текущий процесс
и его данные.

Полезные материалы: Linux Device Drivers third edition page 295 - 299

0 comments on commit 1ecedfc

Please sign in to comment.