25
25
****************************************************************************/
26
26
27
27
#include <nuttx/config.h>
28
- #include <nuttx/spinlock .h>
28
+ #include <nuttx/atomic .h>
29
29
#include <nuttx/lib/lib.h>
30
30
31
31
#include <stdlib.h>
41
41
42
42
struct pathbuffer_s
43
43
{
44
- spinlock_t lock ; /* Lock for the buffer */
45
- unsigned long free_bitmap ; /* Bitmap of free buffer */
44
+ atomic_t free_bitmap ; /* Bitmap of free buffer */
46
45
char buffer [CONFIG_LIBC_PATHBUFFER_MAX ][PATH_MAX ];
47
46
};
48
47
@@ -52,7 +51,6 @@ struct pathbuffer_s
52
51
53
52
static struct pathbuffer_s g_pathbuffer =
54
53
{
55
- SP_UNLOCKED ,
56
54
(1u << CONFIG_LIBC_PATHBUFFER_MAX ) - 1 ,
57
55
};
58
56
@@ -82,22 +80,24 @@ static struct pathbuffer_s g_pathbuffer =
82
80
83
81
FAR char * lib_get_pathbuffer (void )
84
82
{
85
- irqstate_t flags ;
86
- int index ;
87
-
88
- /* Try to find a free buffer */
89
-
90
- flags = spin_lock_irqsave (& g_pathbuffer .lock );
91
- index = ffsl (g_pathbuffer .free_bitmap ) - 1 ;
92
- if (index >= 0 && index < CONFIG_LIBC_PATHBUFFER_MAX )
83
+ for (; ; )
93
84
{
94
- g_pathbuffer .free_bitmap &= ~(1u << index );
95
- spin_unlock_irqrestore (& g_pathbuffer .lock , flags );
96
- return g_pathbuffer .buffer [index ];
85
+ int32_t update ;
86
+ int32_t free_bitmap = atomic_read (& g_pathbuffer .free_bitmap );
87
+ int index = ffsl (free_bitmap ) - 1 ;
88
+ if (index < 0 || index >= CONFIG_LIBC_PATHBUFFER_MAX )
89
+ {
90
+ break ;
91
+ }
92
+
93
+ update = free_bitmap & ~(1u << index );
94
+ if (atomic_cmpxchg (& g_pathbuffer .free_bitmap , & free_bitmap ,
95
+ update ))
96
+ {
97
+ return g_pathbuffer .buffer [index ];
98
+ }
97
99
}
98
100
99
- spin_unlock_irqrestore (& g_pathbuffer .lock , flags );
100
-
101
101
/* If no free buffer is found, allocate a new one if
102
102
* CONFIG_LIBC_PATHBUFFER_MALLOC is enabled
103
103
*/
@@ -125,17 +125,12 @@ FAR char *lib_get_pathbuffer(void)
125
125
126
126
void lib_put_pathbuffer (FAR char * buffer )
127
127
{
128
- irqstate_t flags ;
129
- int index ;
130
-
131
- index = (buffer - & g_pathbuffer .buffer [0 ][0 ]) / PATH_MAX ;
128
+ int index = (buffer - & g_pathbuffer .buffer [0 ][0 ]) / PATH_MAX ;
132
129
if (index >= 0 && index < CONFIG_LIBC_PATHBUFFER_MAX )
133
130
{
134
- /* Mark the corresponding bit as free */
135
-
136
- flags = spin_lock_irqsave (& g_pathbuffer .lock );
137
- g_pathbuffer .free_bitmap |= 1u << index ;
138
- spin_unlock_irqrestore (& g_pathbuffer .lock , flags );
131
+ DEBUGASSERT ((atomic_read (& g_pathbuffer .free_bitmap ) &
132
+ (1u << index )) == 0 );
133
+ atomic_fetch_or_acquire (& g_pathbuffer .free_bitmap , 1u << index );
139
134
return ;
140
135
}
141
136
0 commit comments