atmel_serial: fix bugs in probe() error path and remove()
[pv_ops_mirror.git] / arch / mn10300 / kernel / semaphore.c
blob9153c4039fd2b98ba8d38719da0b2a2e1bae9bc3
1 /* MN10300 Semaphore implementation
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
11 #include <linux/sched.h>
12 #include <linux/module.h>
13 #include <asm/semaphore.h>
15 struct sem_waiter {
16 struct list_head list;
17 struct task_struct *task;
20 #if SEMAPHORE_DEBUG
21 void semtrace(struct semaphore *sem, const char *str)
23 if (sem->debug)
24 printk(KERN_DEBUG "[%d] %s({%d,%d})\n",
25 current->pid,
26 str,
27 atomic_read(&sem->count),
28 list_empty(&sem->wait_list) ? 0 : 1);
30 #else
31 #define semtrace(SEM, STR) do { } while (0)
32 #endif
35 * wait for a token to be granted from a semaphore
36 * - entered with lock held and interrupts disabled
38 void __down(struct semaphore *sem, unsigned long flags)
40 struct task_struct *tsk = current;
41 struct sem_waiter waiter;
43 semtrace(sem, "Entering __down");
45 /* set up my own style of waitqueue */
46 waiter.task = tsk;
47 get_task_struct(tsk);
49 list_add_tail(&waiter.list, &sem->wait_list);
51 /* we don't need to touch the semaphore struct anymore */
52 spin_unlock_irqrestore(&sem->wait_lock, flags);
54 /* wait to be given the semaphore */
55 set_task_state(tsk, TASK_UNINTERRUPTIBLE);
57 for (;;) {
58 if (!waiter.task)
59 break;
60 schedule();
61 set_task_state(tsk, TASK_UNINTERRUPTIBLE);
64 tsk->state = TASK_RUNNING;
65 semtrace(sem, "Leaving __down");
67 EXPORT_SYMBOL(__down);
70 * interruptibly wait for a token to be granted from a semaphore
71 * - entered with lock held and interrupts disabled
73 int __down_interruptible(struct semaphore *sem, unsigned long flags)
75 struct task_struct *tsk = current;
76 struct sem_waiter waiter;
77 int ret;
79 semtrace(sem, "Entering __down_interruptible");
81 /* set up my own style of waitqueue */
82 waiter.task = tsk;
83 get_task_struct(tsk);
85 list_add_tail(&waiter.list, &sem->wait_list);
87 /* we don't need to touch the semaphore struct anymore */
88 set_task_state(tsk, TASK_INTERRUPTIBLE);
90 spin_unlock_irqrestore(&sem->wait_lock, flags);
92 /* wait to be given the semaphore */
93 ret = 0;
94 for (;;) {
95 if (!waiter.task)
96 break;
97 if (unlikely(signal_pending(current)))
98 goto interrupted;
99 schedule();
100 set_task_state(tsk, TASK_INTERRUPTIBLE);
103 out:
104 tsk->state = TASK_RUNNING;
105 semtrace(sem, "Leaving __down_interruptible");
106 return ret;
108 interrupted:
109 spin_lock_irqsave(&sem->wait_lock, flags);
110 list_del(&waiter.list);
111 spin_unlock_irqrestore(&sem->wait_lock, flags);
113 ret = 0;
114 if (!waiter.task) {
115 put_task_struct(current);
116 ret = -EINTR;
118 goto out;
120 EXPORT_SYMBOL(__down_interruptible);
123 * release a single token back to a semaphore
124 * - entered with lock held and interrupts disabled
126 void __up(struct semaphore *sem)
128 struct task_struct *tsk;
129 struct sem_waiter *waiter;
131 semtrace(sem, "Entering __up");
133 /* grant the token to the process at the front of the queue */
134 waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
136 /* We must be careful not to touch 'waiter' after we set ->task = NULL.
137 * It is an allocated on the waiter's stack and may become invalid at
138 * any time after that point (due to a wakeup from another source).
140 list_del_init(&waiter->list);
141 tsk = waiter->task;
142 smp_mb();
143 waiter->task = NULL;
144 wake_up_process(tsk);
145 put_task_struct(tsk);
147 semtrace(sem, "Leaving __up");
149 EXPORT_SYMBOL(__up);