-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprintm.c
140 lines (120 loc) · 2.4 KB
/
printm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include "printm.h"
#include <stdarg.h>
#ifdef __KERNEL__
#include <linux/version.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#else
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#endif
static list_element_t *head;
static list_element_t *tail;
size_t queue_size;
#ifdef __KERNEL__
DEFINE_SPINLOCK(head_lock);
DEFINE_SPINLOCK(tail_lock);
EXPORT_SYMBOL(printm);
#endif
void init_printm(void) {
head = NULL;
tail = NULL;
queue_size = 0;
}
int printm(char *format, ...) {
va_list parameter;
char *buffer = NULL;
size_t size = 0;
va_start(parameter, format);
//kmalloc buffer and write to buffer
#ifdef __KERNEL__
buffer = kmalloc(sizeof(char) * 1024, __GFP_NORETRY);
#else
buffer = malloc(sizeof(char) * 1024);
#endif
if(!buffer) {
return -1;
}
size = vsnprintf(buffer, 1023, format, parameter);
va_end(parameter);
enqueue(buffer);
return size;
}
void enqueue(char *message) {
//lock...
#ifdef __KERNEL__
list_element_t *new_element = kmalloc(sizeof(list_element_t), __GFP_NORETRY);
#else
list_element_t *new_element = malloc(sizeof(list_element_t));
#endif
if(!new_element) {
//kmalloc went wrong
return;
}
//init new element
new_element->message = message;
new_element->next = NULL;
//TODO check for max size and dequeue stuff
if(!head) {
#ifdef __KERNEL__
spin_lock(&head_lock);
#endif
head = new_element;
#ifdef __KERNEL__
spin_unlock(&head_lock);
#endif
#ifdef __KERNEL__
spin_lock(&tail_lock);
#endif
tail = new_element;
#ifdef __KERNEL__
spin_unlock(&tail_lock);
#endif
} else {
#ifdef __KERNEL__
spin_lock(&tail_lock);
#endif
tail->next = new_element;
tail = new_element;
#ifdef __KERNEL__
spin_unlock(&tail_lock);
#endif
}
}
char *dequeue(void) {
//locking...
char *tmp_message = NULL;
list_element_t *tmp_element;
if(!head)
return NULL;
#ifdef __KERNEL__
spin_lock(&head_lock);
#endif
tmp_message = head->message;
tmp_element = head;
if(head == tail) {
tail = NULL;
head = NULL;
} else {
head = head->next;
}
#ifdef __KERNEL__
spin_unlock(&head_lock);
#endif
#ifdef __KERNEL__
kfree(tmp_element);
#else
free(tmp_element);
#endif
if(tmp_message)
printk("dequeuingasf %s\n", tmp_message);
return tmp_message;
}
#ifdef __KERNEL__
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daniel Sparka");
MODULE_DESCRIPTION("Bla alles super hui");
#endif