1 /*
2 * Copyright (c) 2011 Aeroflex Gaisler
3 *
4 * BSD license:
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25
26 #include <asm-leon/queue.h>
27 /*#include <sys/fsu_pthread_queue.h>*/
28 #include <asm-leon/contextswitch.h>
29 #include <asm-leon/leonbare_kernel.h>
30 #include <asm-leon/leonbare_debug.h>
31 #include <asm-leon/stack.h>
32 #include <asm-leon/leonstack.h>
33 #include <asm-leon/irq.h>
34
35 leonbare_mutex_t
leonbare_mutex_init(leonbare_mutex_t m)36 leonbare_mutex_init (leonbare_mutex_t m)
37 {
38 m->mx_owner_cnt = 0;
39 m->mx_owner = 0;
40 LBTAILQ_INIT (&(m->mx_threads));
41
42 LEONBARE_PROTECT_KERNEL_START ();
43 {
44 LBTAILQ_INSERT_TAIL (LEONBARE_KR_ALLM, m, mx_allm);
45 }
46 LEONBARE_PROTECT_KERNEL_END ();
47
48 }
49
50 int
_self__leonbare_mutex_lock(leonbare_mutex_t m,int wait)51 _self__leonbare_mutex_lock (leonbare_mutex_t m, int wait)
52 {
53 int ret = LEONBARE_MUTEX_LOCK_OK;
54 leonbare_thread_t c;
55
56 LEONBARE_PROTECT_MUTEXSTRUCT_START (m);
57 while (1)
58 {
59 if (LEONBARE_MUTEX_OWNER_GET (m) == 0)
60 {
61 LEONBARE_MUTEX_OWNER_SET (m, LEONBARE_KR_CURRENT);
62 LEONBARE_MUTEX_OWNER_CNT_SET (m, 0);
63 LBTAILQ_INSERT_TAIL (&c->th_mutex_locked, m, mx_locked);
64 ret = LEONBARE_MUTEX_LOCK_OK;
65 break;
66 }
67 else if (m->mx_owner == LEONBARE_KR_CURRENT)
68 {
69 m->mx_owner_cnt++;
70 ret = LEONBARE_MUTEX_LOCK_OK;
71 break;
72 }
73 LBTAILQ_INSERT_TAIL (&m->mx_threads, c, th_mutex);
74 current_suspend ();
75 }
76 LEONBARE_PROTECT_MUTEXSTRUCT_END (m);
77 return ret;
78 }
79
80 int
leonbare_mutex_unlock(leonbare_mutex_t m)81 leonbare_mutex_unlock (leonbare_mutex_t m)
82 {
83 int ret = LEONBARE_MUTEX_UNLOCK_ERROR;
84 leonbare_thread_t c, h;
85
86 LEONBARE_PROTECT_MUTEXSTRUCT_START (m);
87 {
88 c = LEONBARE_KR_CURRENT;
89 if (m->mx_owner != c)
90 {
91 ret = LEONBARE_MUTEX_UNLOCK_OK;
92 }
93 else if (m->mx_owner == c && m->mx_owner_cnt)
94 {
95 m->mx_owner_cnt--;
96 ret = LEONBARE_MUTEX_UNLOCK_OK;
97 }
98 else if ((h = LBTAILQ_FIRST (&m->mx_threads)))
99 {
100 LBTAILQ_REMOVE (&m->mx_threads, h, th_mutex);
101 leonbare_thread_resume (h);
102 ret = LEONBARE_MUTEX_UNLOCK_OK;
103 }
104 }
105 LEONBARE_PROTECT_MUTEXSTRUCT_END (m);
106 return ret;
107 }
108