You are expected to understand this. CS 111 Operating Systems Principles, Fall 2006
You are here: CS111: [[2006fall:lab2functions]]
 
 
 

Useful Kernel Functions

Descriptions of kernel functions you may be unfamiliar with and may find helpful in implementing your lab. Implementation files are given as a helpful pointer for authoritative information on the workings of the functions, their locations are given relative to a linux kernel source tree, e.g. /usr/src/linux/. You may also find the Linux Cross Reference a helpful reference for Linux types and functions (search: Linux Cross Reference identifier search).

1. Mutex locking and unlocking. We provide our own version of Linux's spin_lock mutex type, because on the lab machines, Linux's implementation won't help you find bugs. But for Linux's implementation, see include/linux/spinlock.h.

void osp_spin_lock_init(osp_spinlock_t *mutex); Initialize a mutex
void osp_spin_lock(osp_spinlock_t *lock); Acquire a mutex (lock the mutex)
void osp_spin_unlock(osp_spinlock_t *lock); Release (unlock) the mutex

Do not call a scheduling function, such as schedule(), while holding a spin lock! That is a recipe for disaster: your entire kernel might deadlock.

2. Signals, implementation in include/linux/sched.h and kernel/signal.c.

int signal_pending(struct task_struct *process); Returns boolean indicating whether the given process has any pending signals. You will probably pass current for the process argument; current is Linux's name for the current process structure.
int send_sig(int sig, struct task_struct *p, int priv); Send a signal sig to the process specified by p (the linux kernel has a task_struct for each process), we'll set priv to 0. Returns < 0 on error.

3. Wait queues, implementation in kernel/wait.c and include/linux/wait.h. These functions change a process's state from TASK_RUNNABLE to a blocked state, and allow other processes or kernel code to wake up blocked processes.

DEFINE_WAIT(wait); Defines a wait_queue_t object named wait. This object will be passed to prepare_to_wait and finish_wait.
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state); Add the current task to the wait queue, using the named wait_queue_t object. The state member is the process's new state. Use TASK_INTERRUPTIBLE, which is a type of blocking that can be interrupted by signals. This function only adds the task to the queue; a later call to schedule will actually block. This allows you to avoid sleep/wakeup races: first, add the task to the wait queue; second, release any mutexes; and third, call schedule.
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait); Remove the current task from the wait queue.
void wake_up_all(wait_queue_head_t *q); Wake up all tasks in the wait queue by setting their states to TASK_RUNNABLE.

4. CPU releasing/scheduling, implementation in kernel/timer.c.

void schedule(void); Release control of the CPU. If the current task's state is TASK_RUNNABLE, then the task might run again soon. If it is TASK_INTERRUPTIBLE, then the task will block until it is woken up by a signal or by wake_up_all.
long schedule_timeout(long timeout); Release control of the CPU for at most timeout time, which is measured in "jiffies". (There are HZ jiffies per second; often HZ is 1000.) Returns the amount of time remaining until timeout is returned, 0 is returned if the call timed out.

5. Block device requests, implementation in include/linux/blkdev.h.

unsigned int rq_data_dir(struct request *req); Returns the value indicating the given request's type, 0 for reads and 1 for writes.

6. File flags.

Your osprd_open and osprd_release functions will need to check whether your device file was opened for reading or writing, and whether your device file was opened with the O_EXCL flag or not. Given a struct file *filp variable:

(filp->f_mode & FMODE_WRITE) This expression is true (non-zero) if the file was opened for writing (O_WRONLY or O_RDWR).
(filp->f_flags & O_EXCL) This expression is true (non-zero) if the file was opened with the O_EXCL flag.

7. Helper functions for Lab 2.

osprd_device_t *file2osprd(struct file *filp); Linux's struct file object type corresponds to open files. This function takes an open file and returns the corresponding OSP ramdisk structure, osprd_device_t. This type is defined at the top of osprd.c. If filp is not actually an OSP ramdisk file, returns NULL.
void for_each_file(struct task_struct *task, void (*hook)(struct file *filp, osprd_info_t *d), osprd_info_t *d); Calls the hook function for each of task's open files. The function is called like hook(filp, d), where filp is the open file and d is the 3rd argument to for_each_file. You will probably pass current for the task argument; current is Linux's name for the current process structure.
 
2006fall/lab2functions.txt · Last modified: 2006/11/02 09:24 (external edit)
 
Recent changes RSS feed Driven by DokuWiki