starting to come together

git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@222 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2010-02-28 00:25:36 +00:00
parent 182b3de789
commit d231f92742
3 changed files with 83 additions and 15 deletions

View File

@ -29,6 +29,7 @@ clean:
update: all update: all
rmmod kqueue rmmod kqueue
insmod ./kqueue.ko insmod ./kqueue.ko
sleep 2
chmod 777 /dev/kqueue chmod 777 /dev/kqueue
modtest: test.c modtest: test.c

View File

@ -31,6 +31,7 @@
/* Portions based on /* Portions based on
$FreeBSD: src/sys/kern/kern_event.c,v 1.126.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $ $FreeBSD: src/sys/kern/kern_event.c,v 1.126.2.1.2.1 2009/10/25 01:10:29 kensmith Exp $
$FreeBSD: src/sys/sys/eventvar.h,v 1.6.30.1.2.1 2009/10/25 01:10:29 kensmith Exp $
*/ */
#include <linux/cdev.h> #include <linux/cdev.h>
@ -40,12 +41,17 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/rbtree.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include "../include/sys/event.h" #include "../include/sys/event.h"
#include "queue.h" #include "queue.h"
struct kqueue;
struct kfilter;
struct knote;
static int kqueue_open (struct inode *inode, struct file *file); static int kqueue_open (struct inode *inode, struct file *file);
static int kqueue_release (struct inode *inode, struct file *file); static int kqueue_release (struct inode *inode, struct file *file);
static int kqueue_ioctl(struct inode *inode, struct file *file, static int kqueue_ioctl(struct inode *inode, struct file *file,
@ -64,14 +70,54 @@ struct file_operations fops = {
.write = kqueue_write, .write = kqueue_write,
}; };
struct kqueue_data { struct kfilter {
spinlock_t kq_lock; struct rb_root kf_note;
}; };
struct kqueue {
spinlock_t kq_lock;
int kq_count; /* number of pending events */
struct kfilter kq_filt[EVFILT_SYSCOUNT];
};
#ifdef TODO
struct filterops {
int f_isfd; /* true if ident == filedescriptor */
int (*f_attach)(struct knote *kn);
void (*f_detach)(struct knote *kn);
int (*f_event)(struct knote *kn, long hint);
};
static struct kfilter {
struct filterops kf_fop;
int for_refcnt;
} sysfilt_ops[EVFILT_SYSCOUNT];
= {
{ &file_filtops }, /* EVFILT_READ */
{ &file_filtops }, /* EVFILT_WRITE */
{ &null_filtops }, /* EVFILT_AIO */
{ &file_filtops }, /* EVFILT_VNODE */
{ &proc_filtops }, /* EVFILT_PROC */
{ &sig_filtops }, /* EVFILT_SIGNAL */
{ &timer_filtops }, /* EVFILT_TIMER */
{ &file_filtops }, /* EVFILT_NETDEV */
{ &fs_filtops }, /* EVFILT_FS */
{ &null_filtops }, /* EVFILT_LIO */
};
#endif
static int major; static int major;
static struct class *kqueue_class; static struct class *kqueue_class;
static struct task_struct *kq_thread; static struct task_struct *kq_thread;
static struct kfilter *
kfilter_lookup(struct kqueue *kq, int filt)
{
if (filt > 0 || filt + EVFILT_SYSCOUNT < 0)
return NULL;
return &kq->kq_filt[~filt];
}
//only for sleeping during testing //only for sleeping during testing
#include <linux/delay.h> #include <linux/delay.h>
static int kqueue_main(void *arg) static int kqueue_main(void *arg)
@ -88,7 +134,8 @@ static int kqueue_main(void *arg)
static int kqueue_open (struct inode *inode, struct file *file) static int kqueue_open (struct inode *inode, struct file *file)
{ {
struct kqueue_data *kq; struct kqueue *kq;
int i;
printk("kqueue_open\n"); printk("kqueue_open\n");
@ -98,11 +145,9 @@ static int kqueue_open (struct inode *inode, struct file *file)
return -1; return -1;
} }
spin_lock_init(&kq->kq_lock); spin_lock_init(&kq->kq_lock);
for (i = 0; i < EVFILT_SYSCOUNT; i++)
kq->kq_filt[i].kf_note = RB_ROOT;
file->private_data = kq; file->private_data = kq;
/* FIXME Unresolved symbols
kq->kq_fd[0] = epoll_create1(0);
kq->kq_fd[0] = sys_inotify_init();
*/
return 0; return 0;
} }
@ -131,7 +176,7 @@ static int kqueue_ioctl(struct inode *inode, struct file *file,
static ssize_t kqueue_read(struct file *file, char __user *buf, static ssize_t kqueue_read(struct file *file, char __user *buf,
size_t lbuf, loff_t *ppos) size_t lbuf, loff_t *ppos)
{ {
struct kqueue_data *kq = file->private_data; struct kqueue *kq = file->private_data;
spin_lock(&kq->kq_lock); spin_lock(&kq->kq_lock);
//STUB //STUB
@ -143,14 +188,31 @@ static ssize_t kqueue_read(struct file *file, char __user *buf,
static ssize_t kqueue_write(struct file *file, const char __user *buf, static ssize_t kqueue_write(struct file *file, const char __user *buf,
size_t lbuf, loff_t *ppos) size_t lbuf, loff_t *ppos)
{ {
struct kqueue_data *kq = file->private_data; struct kqueue *kq = file->private_data;
struct kevent kev;
struct kfilter *filt;
size_t i, nchanges;
char kbuf[4]; if ((lbuf % sizeof(struct kevent)) != 0)
return -EINVAL;
nchanges = lbuf / sizeof(struct kevent);
spin_lock(&kq->kq_lock); for (i = 0; i < nchanges; i++) {
copy_from_user(kbuf, buf, 4); if (copy_from_user(&kev, (struct kevent *) buf, sizeof(kev)))
printk("%zu bytes: %s", lbuf, kbuf); return -EFAULT;
spin_unlock(&kq->kq_lock);
filt = kfilter_lookup(kq, kev.filter);
if (filt == NULL)
return -EINVAL;
#ifdef DEADWOOD
spin_lock(&kq->kq_lock);
printk("%zu bytes, nchanges=%zu", lbuf, nchanges);
spin_unlock(&kq->kq_lock);
#endif
buf += sizeof(kev);
}
return sizeof(struct kevent); return sizeof(struct kevent);
} }

View File

@ -22,9 +22,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "../include/sys/event.h"
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
struct kevent kev;
int fd; int fd;
fd = open("/dev/kqueue", O_RDWR); fd = open("/dev/kqueue", O_RDWR);
@ -32,6 +35,7 @@ main(int argc, char **argv)
err(1, "open()"); err(1, "open()");
printf("kqfd = %d\n", fd); printf("kqfd = %d\n", fd);
EV_SET(&kev, 1, EVFILT_READ, EV_ADD, 0, 0, NULL);
#if OLD #if OLD
int x; int x;
@ -42,7 +46,8 @@ main(int argc, char **argv)
if (ioctl(fd, 1234, (char *) &x) < 0) if (ioctl(fd, 1234, (char *) &x) < 0)
err(1, "ioctl"); err(1, "ioctl");
#endif #endif
write(fd, "hi\n", 3); if (write(fd, &kev, sizeof(kev)) < 0)
err(1, "write");
close(fd); close(fd);
puts("ok"); puts("ok");