Skip to content

Commit d7734c0

Browse files
committed
sync done
1 parent adeaaa4 commit d7734c0

File tree

6 files changed

+210
-29
lines changed

6 files changed

+210
-29
lines changed

assignment03/driver_dev/Makefile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
NAME = eosi_barrier
22
TESTER_NAME = $(NAME)-test
3-
TESTER_FLAGS = -Wall -g -lpthread -std=c99
3+
TESTER_FLAGS = -Wall -g -lpthread
44

55
IOT_HOME = /opt/iot-devkit/1.7.3/sysroots
66
#KDIR := /root/source/galileo/galileo-linux-stable_backup
@@ -26,14 +26,15 @@ $(TESTER_NAME): $(TESTER_NAME).c $(NAME)_user.h $(NAME)_common.h $(NAME)_kernel.
2626

2727
.PHONY: install uninstall dellog reinstall
2828
install:
29-
cp -f `pwd`/hc_sr04.ko /lib/modules/3.8.7-yocto-standard/kernel/drivers/hc_sr04/hc_sr04.ko
30-
modprobe hc_sr04
29+
cp -f `pwd`/eosi_barrier.ko /lib/modules/3.8.7-yocto-standard/kernel/drivers/eosi_barrier/eosi_barrier.ko
30+
modprobe eosi_barrier
3131
uninstall:
32-
modprobe -r hc_sr04
32+
modprobe -r eosi_barrier
3333

3434
reinstall:
35-
modprobe -r hc_sr04
36-
modprobe hc_sr04
35+
modprobe -r eosi_barrier
36+
cp -f `pwd`/eosi_barrier.ko /lib/modules/3.8.7-yocto-standard/kernel/drivers/eosi_barrier/eosi_barrier.ko
37+
modprobe eosi_barrier
3738

3839
dellog:
3940
cat /dev/null > /var/log/kern.log

assignment03/driver_dev/eosi_barrier-test.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include<sys/wait.h>
99
#include<sys/types.h>
1010
#include<errno.h>
11+
#include<features.h>
1112
#include"eosi_barrier_user.h"
1213
static unsigned int sleep_time = 1;
1314

@@ -18,18 +19,17 @@ void* pfunction(void* datain) {
1819
printf("pid: 0x%x, tid: 0x%x\n", (int)getpid(), (unsigned int)pthread_self());
1920

2021
re_cnt:
21-
if(cnt == 100) return NULL;
22+
if(cnt++ == 3) return 0;
23+
sleep(1);
2224
barrier_wait(barrier_id);
23-
cnt++;
2425
goto re_cnt;
2526

2627
return NULL;
2728
}
2829

2930
void* run_barriers(void* datain) {
3031
int num_threads = *(int*)datain;
31-
pthread_t tids[num_threads];
32-
int idx = 0;
32+
pthread_t tids[num_threads]; int idx = 0;
3333
unsigned int barrier_id = 0;
3434

3535
barrier_init(num_threads, &barrier_id);
@@ -45,6 +45,7 @@ void* run_barriers(void* datain) {
4545
return NULL;
4646
}
4747

48+
//for official use
4849
void fork_run() {
4950
int t1_num = 5;
5051
int t2_num = 20;
@@ -57,6 +58,15 @@ void fork_run() {
5758
pthread_join(t1, NULL);
5859
pthread_join(t2, NULL);
5960
}
61+
62+
//for development use
63+
void dev_run() {
64+
pthread_t t1;
65+
int t_num = 2;
66+
pthread_create(&t1, NULL, run_barriers, &t_num);
67+
pthread_join(t1, NULL);
68+
}
69+
6070
int main(int argc, char*argv[]) {
6171
if(2 == argc) {
6272
sleep_time = atoi(argv[1]);
@@ -65,13 +75,17 @@ int main(int argc, char*argv[]) {
6575
return 0;
6676
}
6777

78+
eosi_barrer_fd = open("/dev/eosi_barrier_1", O_RDWR);
6879
if(0 == fork()) {
6980
//fork_run();
81+
dev_run();
7082
return 0;
7183
}
84+
sleep(5);
85+
puts("--------");
7286

7387
if(0 == fork()) {
74-
fork_run();
88+
//fork_run();
7589
return 0;
7690
}
7791

assignment03/driver_dev/eosi_barrier.c

Lines changed: 150 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#include<linux/kernel.h>
21
#include<linux/module.h>
32
#include<linux/init.h>
43
#include<linux/hashtable.h>
@@ -18,6 +17,7 @@
1817
#include<linux/kthread.h>
1918
#include<linux/ktime.h>
2019
#include<linux/sched.h>
20+
#include<linux/kernel.h>
2121
#include"eosi_barrier_kernel.h"
2222

2323
static struct file_operations eosi_barrier_fops = {
@@ -39,7 +39,7 @@ static struct miscdevice eosi_barrier_B = {
3939
.fops = &eosi_barrier_fops,
4040
};
4141

42-
static LIST_HEAD(barrier_list);
42+
static LIST_HEAD(tgid_list);
4343

4444

4545
struct barrier_struct* get_curr_barrier(struct inode* node) {
@@ -57,7 +57,8 @@ struct barrier_struct* get_curr_barrier(struct inode* node) {
5757

5858
//init
5959
static int eosi_barrier_open(struct inode* node, struct file* file) {
60-
printk(KERN_ALERT "eosi_barrier: Open\n");
60+
printk(KERN_ALERT "eosi_barrier2: Open\n");
61+
printk(KERN_ALERT "eosi_barrier: sizeof(unsigned long):%d sizeof(int):%d\n", sizeof(unsigned long long), sizeof(int));
6162
printk(KERN_ALERT "eosi_barrier: Open Done\n");
6263
return 0;
6364
}
@@ -68,16 +69,141 @@ static int eosi_barrier_release(struct inode* node, struct file* file) {
6869
printk(KERN_ALERT "eosi_barrier: Release Done\n"); return 0;
6970
}
7071

72+
barrier_struct* barray[10];
73+
static unsigned int basic_bid = 0;
74+
int barrier_init(barrier_info* binfo) {
75+
barrier_struct* barrier = NULL;
76+
77+
printk(KERN_ALERT "barrier_init\n");
78+
79+
if(0 > binfo->count) return -1;
80+
//search tgid linkedlist
81+
//if the tgid block does not exist, then allocate the new one tgid block.
82+
83+
binfo->barrier_id = basic_bid;
84+
basic_bid++;
85+
barrier = kmalloc(sizeof(barrier_struct), GFP_KERNEL);
86+
init_barrier_struct(barrier, binfo->count, binfo->barrier_id);
87+
88+
//link the corresponding barrier block.
89+
barray[basic_bid-1] = barrier;
90+
91+
printk(KERN_ALERT "barrier_init done\n");
92+
return 0;
93+
}
94+
95+
void printSYNC_start(char* fun, barrier_struct* barrier) {
96+
printk(KERN_ALERT "%s: tgid:%d, tid:%d, id:%d, curr(tgid, tid):(%d,%d)\n", fun, barrier->tgid, barrier->tid, barrier->id, task_tgid_vnr(current), task_pid_vnr(current));
97+
}
98+
99+
void printSYNC_done(char* fun, barrier_struct* barrier) {
100+
char s[30];
101+
snprintf(s, 30, "%s Done", fun);
102+
103+
printk(KERN_ALERT "%s: tgid:%d, tid:%d, id:%d, curr (tgid, tid):(%d, %d)\n", s, barrier->tgid, barrier->tid, barrier->id, task_tgid_vnr(current), task_pid_vnr(current));
104+
105+
}
106+
void wake_up_here (barrier_struct* barrier) {
107+
char*s = "wake_up_here";
108+
109+
printSYNC_start(s, barrier);
110+
wake_up_interruptible_all(&(barrier->waitQ));
111+
printSYNC_done(s, barrier);
112+
113+
}
114+
115+
void wait_here (barrier_struct* barrier) {
116+
char*s = "wait_here";
117+
DEFINE_WAIT(wait);
118+
119+
printSYNC_start(s, barrier);
120+
121+
prepare_to_wait(&(barrier->waitQ), &wait, TASK_INTERRUPTIBLE);
122+
schedule();
123+
finish_wait(&(barrier->waitQ), &wait);
124+
printSYNC_done(s, barrier);
125+
126+
}
127+
128+
int barrier_wait(unsigned int barrier_id) {
129+
barrier_struct* barrier = barray[barrier_id];
130+
char*s = "barrier_wait";
131+
132+
printSYNC_start(s, barrier);
133+
134+
spin_lock(&(barrier->lock_total));
135+
136+
while(barrier->total > BARRIER_FLAG) {
137+
spin_unlock(&(barrier->lock_total));
138+
wait_here(barrier);
139+
spin_lock(&(barrier->lock_total));
140+
}
141+
142+
if(BARRIER_FLAG == barrier->total) barrier->total = 0;
143+
144+
barrier->total++;
145+
146+
if(barrier->total == barrier->count) {
147+
barrier->total += BARRIER_FLAG - 1;
148+
wake_up_here(barrier);
149+
//spin_unlock(&(barrier->lock_total));
150+
151+
} else { //sleep here;
152+
while(barrier->total < BARRIER_FLAG) {
153+
spin_unlock(&(barrier->lock_total));
154+
wait_here(barrier);
155+
spin_lock(&(barrier->lock_total));
156+
}
157+
158+
barrier->total--;
159+
160+
if(barrier->total == BARRIER_FLAG) {
161+
wake_up_here(barrier);
162+
}
163+
164+
// spin_unlock(&(barrier->lock_total));
165+
}
166+
167+
spin_unlock(&(barrier->lock_total));
168+
printSYNC_done(s, barrier);
169+
return 0;
170+
}
171+
172+
int barrier_destroy(unsigned int barrier_id) {
173+
char* s = "barrier_destroy";
174+
barrier_struct* barrier = barray[barrier_id];
175+
176+
printSYNC_start(s, barrier);
177+
178+
spin_lock(&(barrier->lock_total));
179+
180+
while(barrier->total > BARRIER_FLAG) {
181+
spin_unlock(&(barrier->lock_total));
182+
wait_here(barrier);
183+
spin_lock(&(barrier->lock_total));
184+
}
185+
186+
spin_unlock(&(barrier->lock_total));
187+
188+
//Recycle HERE//
189+
190+
printSYNC_done(s, barrier);
191+
return 0;
192+
}
193+
71194
static long eosi_barrier_ioctl(struct file* file, unsigned int cmd, unsigned long arg) {
72-
int ret;
195+
int ret = 0;
73196

74197
printk(KERN_ALERT "ioctl\n");
75-
switch (arg) {
198+
switch (cmd) {
76199
case BARRIER_INIT:
200+
ret = barrier_init((barrier_info*)arg);
77201
break;
78202
case BARRIER_WAIT:
203+
ret = barrier_wait((unsigned int)arg);
79204
break;
80205
case BARRIER_DESTROY:
206+
ret = barrier_destroy((unsigned int)arg);
81207
break;
82208
default:
83209
return -EINVAL;
@@ -95,24 +221,38 @@ static int reg_misc(struct miscdevice* md) {
95221

96222
return error;
97223
}
224+
98225
static void dereg_misc(struct miscdevice* md) {
99226
misc_deregister(md);
100227
}
101228

102-
static void init_barrier_struct(barrier_struct* barrier, int count, int* id) {
229+
static void init_barrier_struct(barrier_struct* barrier, int count, unsigned int id) {
230+
barrier->count = count;
231+
barrier->total = BARRIER_FLAG;
232+
barrier->id = id;
233+
barrier->tgid = task_tgid_vnr(current);
234+
barrier->tid = task_pid_vnr(current);
235+
spin_lock_init(&(barrier->lock_total));
236+
init_waitqueue_head(&(barrier->waitQ));
237+
}
238+
239+
static void init_per_tgid(per_tgid* each_tgid) {
240+
each_tgid->tgid = task_tgid_vnr(current);
103241
}
242+
#ifndef _BARRIER_MGMT_
243+
#endif
104244

105245
static int __init eosi_barrier_init(void) {
106246
/*!!!!!*/
107247
//CHECK!!! INIT
108-
printk(KERN_ALERT "hc_sr04: INIT\n");
248+
printk(KERN_ALERT "eosi_barrier: INIT\n");
109249
if( reg_misc(&eosi_barrier_A) || reg_misc(&eosi_barrier_B) )
110250
return 0;
111251

112-
// init_hcsr_struct(&hcA, &hc_sr04_A, A_pins, A_pin_str);
113-
// init_hcsr_struct(&hcB, &hc_sr04_B, B_pins, B_pin_str);
252+
// init_hcsr_struct(&hcA, &eosi_barrier_A, A_pins, A_pin_str);
253+
// init_hcsr_struct(&hcB, &eosi_barrier_B, B_pins, B_pin_str);
114254

115-
printk(KERN_ALERT "hc_sr04: INIT DONE\n");
255+
printk(KERN_ALERT "eosi_barrier: INIT DONE\n");
116256
return 0;
117257
}
118258

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#ifndef _HC_SR04_COMMON_H_
22
#define _HC_SR04_COMMON_H_
3-
#define __DEUBG__
43
#include<linux/ioctl.h>
54
#define BARRIER_W_MAGIC ('B')
65
#define BARRIER_INIT _IOW (BARRIER_W_MAGIC, 1, char*)
76
#define BARRIER_WAIT _IOR (BARRIER_W_MAGIC, 2, char*)
87
#define BARRIER_DESTROY _IOW (BARRIER_W_MAGIC, 3, char*)
8+
typedef struct barrier_info {
9+
int count;
10+
unsigned int barrier_id;
11+
} barrier_info;
912
#endif
Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,34 @@
11
#ifndef _HC_SR04_KERNEL_H_
22
#define _HC_SR04_KERNEL_H_
33

4+
#define _BARRIER_MGMT_
45
#include "eosi_barrier_common.h"
56
#include <linux/spinlock.h>
67
#include <linux/semaphore.h>
78
#include <linux/wait.h>
8-
static int eosi_barrier_open(struct inode* node, struct file* file);
9-
static int eosi_barrier_release(struct inode* node, struct file* file);
10-
static long eosi_barrier_ioctl(struct file* file, unsigned int cmd, unsigned long arg);
9+
#define BARRIER_FLAG (1ULL<<63)
1110

1211
typedef struct barrier_struct {
13-
pid_t tgid;
14-
wait_queue_head_t waitQ;
15-
struct list_head list;
12+
unsigned int id;
13+
pid_t tgid;
14+
pid_t tid;
15+
unsigned long long count;
16+
unsigned long long total;
17+
spinlock_t lock_total;
18+
wait_queue_head_t waitQ;
19+
struct list_head list;
1620
} barrier_struct;
1721

18-
22+
typedef struct per_tgid {
23+
pid_t tgid;
24+
unsigned int bid_count;
25+
int barrier_size;
26+
barrier_struct barrier_dummy_head;
27+
struct list_head list;
28+
} per_tgid;
29+
static int eosi_barrier_open(struct inode* node, struct file* file);
30+
static int eosi_barrier_release(struct inode* node, struct file* file);
31+
static long eosi_barrier_ioctl(struct file* file, unsigned int cmd, unsigned long arg);
32+
static void init_barrier_struct(barrier_struct* barrier, int count, unsigned int id);
33+
static void init_per_tgid(per_tgid* each_tgid);
1934
#endif

assignment03/driver_dev/eosi_barrier_user.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,18 @@
33
#include"eosi_barrier_common.h"
44
#include <unistd.h>
55
#include<sys/ioctl.h>
6+
int eosi_barrer_fd;
7+
barrier_info b1info;
8+
barrier_info b2info;
69
int barrier_init(int count, unsigned int* barrier_id) {
10+
b1info.count = count;
11+
ioctl(eosi_barrer_fd, BARRIER_INIT, (unsigned long)&b1info);
12+
*barrier_id = b1info.barrier_id;
713
return 0;
814
}
15+
916
int barrier_wait(unsigned int barrier_id) {
17+
ioctl(eosi_barrer_fd, BARRIER_WAIT, barrier_id);
1018
return 0;
1119
}
1220

0 commit comments

Comments
 (0)