10
10
#include <linux/version.h>
11
11
#include <linux/workqueue.h>
12
12
13
+ #include "game.h"
14
+
13
15
MODULE_LICENSE ("Dual MIT/GPL" );
14
16
MODULE_AUTHOR ("National Cheng Kung University, Taiwan" );
15
17
MODULE_DESCRIPTION ("A device that simulates interrupts" );
@@ -38,6 +40,8 @@ static int major;
38
40
static struct class * simrupt_class ;
39
41
static struct cdev simrupt_cdev ;
40
42
43
+ static char draw_buffer [DRAWBUFFER_SIZE ];
44
+
41
45
/* Data are stored into a kfifo buffer before passing them to the userspace */
42
46
static DECLARE_KFIFO_PTR (rx_fifo , unsigned char ) ;
43
47
@@ -58,14 +62,25 @@ static inline int update_simrupt_data(void)
58
62
}
59
63
60
64
/* Insert a value into the kfifo buffer */
61
- static void produce_data (unsigned char val )
65
+ // static void produce_data(unsigned char val)
66
+ // {
67
+ // /* Implement a kind of circular FIFO here (skip oldest element if kfifo
68
+ // * buffer is full).
69
+ // */
70
+ // unsigned int len = kfifo_in(&rx_fifo, &val, sizeof(val));
71
+ // if (unlikely(len < sizeof(val)) && printk_ratelimit())
72
+ // pr_warn("%s: %zu bytes dropped\n", __func__, sizeof(val) - len);
73
+
74
+ // pr_debug("simrupt: %s: in %u/%u bytes\n", __func__, len,
75
+ // kfifo_len(&rx_fifo));
76
+ // }
77
+
78
+ /* Insert the whole chess board into the kfifo buffer */
79
+ static void produce_board (void )
62
80
{
63
- /* Implement a kind of circular FIFO here (skip oldest element if kfifo
64
- * buffer is full).
65
- */
66
- unsigned int len = kfifo_in (& rx_fifo , & val , sizeof (val ));
67
- if (unlikely (len < sizeof (val )) && printk_ratelimit ())
68
- pr_warn ("%s: %zu bytes dropped\n" , __func__ , sizeof (val ) - len );
81
+ unsigned int len = kfifo_in (& rx_fifo , draw_buffer , sizeof (draw_buffer ));
82
+ if (unlikely (len < sizeof (draw_buffer )) && printk_ratelimit ())
83
+ pr_warn ("%s: %zu bytes dropped\n" , __func__ , sizeof (draw_buffer ) - len );
69
84
70
85
pr_debug ("simrupt: %s: in %u/%u bytes\n" , __func__ , len ,
71
86
kfifo_len (& rx_fifo ));
@@ -84,55 +99,89 @@ static DEFINE_MUTEX(consumer_lock);
84
99
*/
85
100
static struct circ_buf fast_buf ;
86
101
87
- static int fast_buf_get (void )
88
- {
89
- struct circ_buf * ring = & fast_buf ;
102
+ // static int fast_buf_get(void)
103
+ // {
104
+ // struct circ_buf *ring = &fast_buf;
90
105
91
- /* prevent the compiler from merging or refetching accesses for tail */
92
- unsigned long head = READ_ONCE (ring -> head ), tail = ring -> tail ;
93
- int ret ;
106
+ // /* prevent the compiler from merging or refetching accesses for tail */
107
+ // unsigned long head = READ_ONCE(ring->head), tail = ring->tail;
108
+ // int ret;
94
109
95
- if (unlikely (!CIRC_CNT (head , tail , PAGE_SIZE )))
96
- return - ENOENT ;
110
+ // if (unlikely(!CIRC_CNT(head, tail, PAGE_SIZE)))
111
+ // return -ENOENT;
97
112
98
- /* read index before reading contents at that index */
99
- smp_rmb ();
113
+ // /* read index before reading contents at that index */
114
+ // smp_rmb();
100
115
101
- /* extract item from the buffer */
102
- ret = ring -> buf [tail ];
116
+ // /* extract item from the buffer */
117
+ // ret = ring->buf[tail];
103
118
104
- /* finish reading descriptor before incrementing tail */
105
- smp_mb ();
119
+ // /* finish reading descriptor before incrementing tail */
120
+ // smp_mb();
106
121
107
- /* increment the tail pointer */
108
- ring -> tail = (tail + 1 ) & (PAGE_SIZE - 1 );
122
+ // /* increment the tail pointer */
123
+ // ring->tail = (tail + 1) & (PAGE_SIZE - 1);
109
124
110
- return ret ;
111
- }
125
+ // return ret;
126
+ // }
112
127
113
- static int fast_buf_put (unsigned char val )
128
+ /* Draw the board into draw_buffer */
129
+ static int draw_board (int pos )
114
130
{
115
- struct circ_buf * ring = & fast_buf ;
116
- unsigned long head = ring -> head ;
131
+ WRITE_ONCE ( pos , pos % N_GRIDS ) ;
132
+ WRITE_ONCE ( pos , 2 + ( pos >> 2 ) * 16 + (( pos & 3 ) << 1 )) ;
117
133
118
- /* prevent the compiler from merging or refetching accesses for tail */
119
- unsigned long tail = READ_ONCE (ring -> tail );
134
+ pr_info ("%d" , pos );
120
135
121
- /* is circular buffer full? */
122
- if (unlikely (!CIRC_SPACE (head , tail , PAGE_SIZE )))
123
- return - ENOMEM ;
124
-
125
- ring -> buf [ring -> head ] = val ;
126
-
127
- /* commit the item before incrementing the head */
136
+ int i = 0 ;
137
+ draw_buffer [i ++ ] = '\n' ;
138
+ smp_wmb ();
139
+ draw_buffer [i ++ ] = '\n' ;
128
140
smp_wmb ();
129
141
130
- /* update header pointer */
131
- ring -> head = (ring -> head + 1 ) & (PAGE_SIZE - 1 );
142
+ while (i < DRAWBUFFER_SIZE ) {
143
+ for (int j = 0 ; j < (BOARD_SIZE << 1 ) - 1 ; j ++ ) {
144
+ draw_buffer [i ++ ] = j & 1 ? '|' : ' ' ;
145
+ smp_wmb ();
146
+ }
147
+ draw_buffer [i ++ ] = '\n' ;
148
+ smp_wmb ();
149
+ for (int j = 0 ; j < (BOARD_SIZE << 1 ) - 1 ; j ++ ) {
150
+ draw_buffer [i ++ ] = '-' ;
151
+ smp_wmb ();
152
+ }
153
+ draw_buffer [i ++ ] = '\n' ;
154
+ smp_wmb ();
155
+ }
156
+
157
+ WRITE_ONCE (draw_buffer [pos ], 'O' );
132
158
133
159
return 0 ;
134
160
}
135
161
162
+ // static int fast_buf_put(unsigned char val)
163
+ // {
164
+ // struct circ_buf *ring = &fast_buf;
165
+ // unsigned long head = ring->head;
166
+
167
+ // /* prevent the compiler from merging or refetching accesses for tail */
168
+ // unsigned long tail = READ_ONCE(ring->tail);
169
+
170
+ // /* is circular buffer full? */
171
+ // if (unlikely(!CIRC_SPACE(head, tail, PAGE_SIZE)))
172
+ // return -ENOMEM;
173
+
174
+ // ring->buf[ring->head] = val;
175
+
176
+ // /* commit the item before incrementing the head */
177
+ // smp_wmb();
178
+
179
+ // /* update header pointer */
180
+ // ring->head = (ring->head + 1) & (PAGE_SIZE - 1);
181
+
182
+ // return 0;
183
+ // }
184
+
136
185
/* Clear all data from the circular buffer fast_buf */
137
186
static void fast_buf_clear (void )
138
187
{
@@ -142,7 +191,7 @@ static void fast_buf_clear(void)
142
191
/* Workqueue handler: executed by a kernel thread */
143
192
static void simrupt_work_func (struct work_struct * w )
144
193
{
145
- int val , cpu ;
194
+ int cpu ;
146
195
147
196
/* This code runs from a kernel thread, so softirqs and hard-irqs must
148
197
* be enabled.
@@ -157,20 +206,11 @@ static void simrupt_work_func(struct work_struct *w)
157
206
pr_info ("simrupt: [CPU#%d] %s\n" , cpu , __func__ );
158
207
put_cpu ();
159
208
160
- while (1 ) {
161
- /* Consume data from the circular buffer */
162
- mutex_lock (& consumer_lock );
163
- val = fast_buf_get ();
164
- mutex_unlock (& consumer_lock );
209
+ /* Store data to the kfifo buffer */
210
+ mutex_lock (& producer_lock );
211
+ produce_board ();
212
+ mutex_unlock (& producer_lock );
165
213
166
- if (val < 0 )
167
- break ;
168
-
169
- /* Store data to the kfifo buffer */
170
- mutex_lock (& producer_lock );
171
- produce_data (val );
172
- mutex_unlock (& producer_lock );
173
- }
174
214
wake_up_interruptible (& rx_wait );
175
215
}
176
216
@@ -214,7 +254,9 @@ static void process_data(void)
214
254
WARN_ON_ONCE (!irqs_disabled ());
215
255
216
256
pr_info ("simrupt: [CPU#%d] produce data\n" , smp_processor_id ());
217
- fast_buf_put (update_simrupt_data ());
257
+ mutex_lock (& producer_lock );
258
+ draw_board (update_simrupt_data ());
259
+ mutex_unlock (& producer_lock );
218
260
219
261
pr_info ("simrupt: [CPU#%d] scheduling tasklet\n" , smp_processor_id ());
220
262
tasklet_schedule (& simrupt_tasklet );
0 commit comments