4,436
社区成员
发帖
与我相关
我的任务
分享
#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
#include <linux/rwsem-spinlock.h> /* use a generic implementation */
#else
/* All arch specific implementations share the same struct */
struct rw_semaphore {
long count;
raw_spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
};
#ifdef CONFIG_X86_64
# define RWSEM_ACTIVE_MASK 0xffffffffL
#else
# define RWSEM_ACTIVE_MASK 0x0000ffffL
#endif
#define RWSEM_UNLOCKED_VALUE 0x00000000L
#define RWSEM_ACTIVE_BIAS 0x00000001L
#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/rwsem.h>
MODULE_LICENSE("Dual BSD/GPL");
static struct rw_semaphore sem;
static void print_sem(struct rw_semaphore *sem)
{
printk(KERN_DEBUG "sem.count=0x%016lx\n", sem->count);
}
static void get_read_lock(struct rw_semaphore *sem, char *name)
{
printk(KERN_DEBUG "%s is waiting for read\n", name);
down_read(sem);
printk(KERN_DEBUG "%s got read lock\n", name);
}
static void release_read_lock(struct rw_semaphore *sem, char *name)
{
printk(KERN_DEBUG "%s releses read lock\n", name);
up_read(sem);
}
static void get_write_lock(struct rw_semaphore *sem, char *name)
{
printk(KERN_DEBUG "%s is waiting for write\n", name);
down_write(sem);
printk(KERN_DEBUG "%s got write lock\n", name);
}
static void release_write_lock(struct rw_semaphore *sem, char *name)
{
printk(KERN_DEBUG "%s releses write lock\n", name);
up_write(sem);
}
int reader(void *data)
{
char *name = (char *)data;
printk(KERN_DEBUG "%s is running\n", name);
msleep(100);
get_read_lock(&sem, name);
print_sem(&sem);
printk(KERN_DEBUG "%s is sleeping 200\n", name);
msleep(200);
release_read_lock(&sem, name);
do_exit(0);
}
int writer(void *data)
{
char *name = (char *)data;
printk(KERN_DEBUG "%s is running\n", name);
msleep(10);
get_write_lock(&sem, name);
print_sem(&sem);
printk(KERN_DEBUG "%s is sleeping 200\n", name);
msleep(200);
print_sem(&sem);
release_write_lock(&sem, name);
do_exit(0);
}
static int hello_init(void)
{
struct task_struct *task = NULL;
printk(KERN_ALERT "Hello, world\n");
init_rwsem(&sem);
task = kthread_create(reader, "reader_1", "reader");
if (IS_ERR(task)) {
printk(KERN_DEBUG "failed to create task\n");
return 1;
}
wake_up_process(task);
task = kthread_create(reader, "reader_2", "reader");
if (IS_ERR(task)) {
printk(KERN_DEBUG "failed to create task\n");
return 1;
}
wake_up_process(task);
task = kthread_create(writer, "writer", "reader");
if (IS_ERR(task)) {
printk(KERN_DEBUG "failed to create task\n");
return 1;
}
wake_up_process(task);
msleep(100);
task = kthread_create(writer, "writer_2", "reader");
if (IS_ERR(task)) {
printk(KERN_DEBUG "failed to create task\n");
return 1;
}
wake_up_process(task);
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);