1 /*
2  * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3  */
4 
5 #ifndef _SPINLOCK_H_
6 #define _SPINLOCK_H_
7 
8 #include <stdio.h>
9 #include <drivers/u_mode.h>
10 
11 #ifdef CONFIG_PTHREAD_SPINLOCK_SUPPORT
12 #include <pthread.h>
13 
14 typedef struct spinlock {
15 	unsigned int flag;
16 	pthread_spinlock_t ps;
17 } spinlock_t;
18 
19 #define __SPIN_LOCK_UNLOCKED(lock) { .flag = 0 }
20 
21 #define DEFINE_SPINLOCK(lock) struct spinlock lock = { \
22 	.flag = 0 \
23 }
24 
25 #define spin_lock_init(lock) do { \
26 	int ret = -1; \
27 	if ((lock)->flag == 1) \
28 		break; \
29 	ret = pthread_spin_init(&((lock)->ps), PTHREAD_PROCESS_PRIVATE); \
30 	if (ret) { \
31 		printf("pthread_spin_init failed, ret:%d\r\n", ret); \
32 	} \
33 	(lock)->flag = 1; \
34 } while (0)
35 
36 //TODO: how to guarantee this procedure is atomic?
37 #define spin_lock_irqsave(lock, flags) do { \
38 	(void)flags; \
39 	if (!(lock)->flag) { \
40 		spin_lock_init(lock); \
41 		(lock)->flag = 1; \
42 	} \
43 	pthread_spin_lock(&(lock)->ps); \
44 } while (0)
45 
46 #define spin_unlock_irqrestore(lock, flags) do { \
47 	(void)flags; \
48 	pthread_spin_unlock(&(lock)->ps); \
49 } while (0)
50 
51 
52 #define spin_lock(lock) do { \
53 	pthread_spin_lock(&((lock)->ps)); \
54 } while (0)
55 
56 #define spin_unlock(lock) do { \
57 	pthread_spin_unlock(&((lock)->ps)); \
58 } while (0)
59 
60 #define spin_lock_irq(lock) \
61 unsigned long flags; \
62 do { \
63 	pthread_spin_lock(&((lock)->ps)); \
64 } while(0)
65 
66 #define spin_unlock_irq(lock) do { \
67 	pthread_spin_unlock(&((lock)->ps)); \
68 } while(0)
69 
70 #define spin_lock_destroy(lock) do { \
71 	pthread_spin_destroy(&((lock)->ps)); \
72 } while(0)
73 #else
74 #include <aos/kernel.h>
75 
76 typedef struct spinlock {
77 	unsigned int flag;
78 	aos_spinlock_t as;
79 } spinlock_t;
80 
81 #define __SPIN_LOCK_UNLOCKED(lock) { .flag = 0 }
82 
83 #define DEFINE_SPINLOCK(lock) struct spinlock lock = { \
84 	.flag = 0 \
85 }
86 
87 #define spin_lock_init(lock) do { \
88 	int ret = -1; \
89 	if ((lock)->flag == 1) \
90 		break; \
91 	aos_spin_lock_init(&((lock)->as)); \
92 	(lock)->flag = 1; \
93 } while (0)
94 
95 #define spin_lock_irqsave(lock, flags) do { \
96 	if (!(lock)->flag) { \
97 		aos_spin_lock_init(&((lock)->as)); \
98 		(lock)->flag = 1; \
99 	} \
100 	flags = aos_spin_lock_irqsave(&(lock)->as); \
101 } while (0)
102 
103 #define spin_unlock_irqrestore(lock, flags) do { \
104 	(void)flags; \
105 	aos_spin_unlock_irqrestore(&(lock)->as, flags); \
106 } while (0)
107 
108 
109 #define spin_lock(lock) do { \
110 	aos_spin_lock(&((lock)->as)); \
111 } while (0)
112 
113 #define spin_unlock(lock) do { \
114 	aos_spin_unlock(&((lock)->as)); \
115 } while (0)
116 
117 #define spin_lock_irq(lock) \
118 unsigned long flags; \
119 do { \
120 	aos_spin_lock(&((lock)->as)); \
121 } while(0)
122 
123 #define spin_unlock_irq(lock) do { \
124 	aos_spin_unlock(&((lock)->as)); \
125 } while(0)
126 
127 #define spin_lock_destroy(lock) do { \
128 	(lock)->flag = 0; \
129 } while(0)
130 #endif
131 
132 typedef spinlock_t raw_spinlock_t;
133 
134 #define __RAW_SPIN_LOCK_UNLOCKED(lock) { \
135 	.flag = 0 \
136 }
137 #define raw_spin_lock_init(lock) spin_lock_init(lock)
138 
139 #define raw_spin_lock_irqsave(lock, flags) spin_lock_irqsave(lock, flags)
140 #define raw_spin_unlock_irqrestore(lock, flags)  spin_unlock_irqrestore(lock, flags)
141 
142 #define raw_spin_lock_irq(lock) spin_lock_irq(lock)
143 #define raw_spin_unlock_irq(lock)  spin_unlock_irq(lock)
144 
145 
146 #endif //_SPINLOCK_H_
147