OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [frv/] [kernel/] [semaphore.c] - Blame information for rev 19

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* semaphore.c: FR-V semaphores
2
 *
3
 * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
4
 * Written by David Howells (dhowells@redhat.com)
5
 * - Derived from lib/rwsem-spinlock.c
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version
10
 * 2 of the License, or (at your option) any later version.
11
 */
12
 
13
#include <linux/sched.h>
14
#include <linux/module.h>
15
#include <asm/semaphore.h>
16
 
17
struct sem_waiter {
18
        struct list_head        list;
19
        struct task_struct      *task;
20
};
21
 
22
#ifdef CONFIG_DEBUG_SEMAPHORE
23
void semtrace(struct semaphore *sem, const char *str)
24
{
25
        if (sem->debug)
26
                printk("[%d] %s({%d,%d})\n",
27
                       current->pid,
28
                       str,
29
                       sem->counter,
30
                       list_empty(&sem->wait_list) ? 0 : 1);
31
}
32
#else
33
#define semtrace(SEM,STR) do { } while(0)
34
#endif
35
 
36
/*
37
 * wait for a token to be granted from a semaphore
38
 * - entered with lock held and interrupts disabled
39
 */
40
void __down(struct semaphore *sem, unsigned long flags)
41
{
42
        struct task_struct *tsk = current;
43
        struct sem_waiter waiter;
44
 
45
        semtrace(sem, "Entering __down");
46
 
47
        /* set up my own style of waitqueue */
48
        waiter.task = tsk;
49
        get_task_struct(tsk);
50
 
51
        list_add_tail(&waiter.list, &sem->wait_list);
52
 
53
        /* we don't need to touch the semaphore struct anymore */
54
        spin_unlock_irqrestore(&sem->wait_lock, flags);
55
 
56
        /* wait to be given the semaphore */
57
        set_task_state(tsk, TASK_UNINTERRUPTIBLE);
58
 
59
        for (;;) {
60
                if (list_empty(&waiter.list))
61
                        break;
62
                schedule();
63
                set_task_state(tsk, TASK_UNINTERRUPTIBLE);
64
        }
65
 
66
        tsk->state = TASK_RUNNING;
67
        semtrace(sem, "Leaving __down");
68
}
69
 
70
EXPORT_SYMBOL(__down);
71
 
72
/*
73
 * interruptibly wait for a token to be granted from a semaphore
74
 * - entered with lock held and interrupts disabled
75
 */
76
int __down_interruptible(struct semaphore *sem, unsigned long flags)
77
{
78
        struct task_struct *tsk = current;
79
        struct sem_waiter waiter;
80
        int ret;
81
 
82
        semtrace(sem,"Entering __down_interruptible");
83
 
84
        /* set up my own style of waitqueue */
85
        waiter.task = tsk;
86
        get_task_struct(tsk);
87
 
88
        list_add_tail(&waiter.list, &sem->wait_list);
89
 
90
        /* we don't need to touch the semaphore struct anymore */
91
        set_task_state(tsk, TASK_INTERRUPTIBLE);
92
 
93
        spin_unlock_irqrestore(&sem->wait_lock, flags);
94
 
95
        /* wait to be given the semaphore */
96
        ret = 0;
97
        for (;;) {
98
                if (list_empty(&waiter.list))
99
                        break;
100
                if (unlikely(signal_pending(current)))
101
                        goto interrupted;
102
                schedule();
103
                set_task_state(tsk, TASK_INTERRUPTIBLE);
104
        }
105
 
106
 out:
107
        tsk->state = TASK_RUNNING;
108
        semtrace(sem, "Leaving __down_interruptible");
109
        return ret;
110
 
111
 interrupted:
112
        spin_lock_irqsave(&sem->wait_lock, flags);
113
 
114
        if (!list_empty(&waiter.list)) {
115
                list_del(&waiter.list);
116
                ret = -EINTR;
117
        }
118
 
119
        spin_unlock_irqrestore(&sem->wait_lock, flags);
120
        if (ret == -EINTR)
121
                put_task_struct(current);
122
        goto out;
123
}
124
 
125
EXPORT_SYMBOL(__down_interruptible);
126
 
127
/*
128
 * release a single token back to a semaphore
129
 * - entered with lock held and interrupts disabled
130
 */
131
void __up(struct semaphore *sem)
132
{
133
        struct task_struct *tsk;
134
        struct sem_waiter *waiter;
135
 
136
        semtrace(sem,"Entering __up");
137
 
138
        /* grant the token to the process at the front of the queue */
139
        waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
140
 
141
        /* We must be careful not to touch 'waiter' after we set ->task = NULL.
142
         * It is allocated on the waiter's stack and may become invalid at
143
         * any time after that point (due to a wakeup from another source).
144
         */
145
        list_del_init(&waiter->list);
146
        tsk = waiter->task;
147
        mb();
148
        waiter->task = NULL;
149
        wake_up_process(tsk);
150
        put_task_struct(tsk);
151
 
152
        semtrace(sem,"Leaving __up");
153
}
154
 
155
EXPORT_SYMBOL(__up);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.