xref: /third_party/musl/src/stdio/ofl.c (revision 570af302)
1#include "stdio_impl.h"
2#include "lock.h"
3#include "fork_impl.h"
4#include <stdlib.h>
5
6#define DEFAULT_ALLOC_FILE (8)
7
8static FILE *ofl_head = NULL;
9static FILE *ofl_free = NULL;
10
11static volatile int ofl_lock[1];
12volatile int *const __stdio_ofl_lockptr = ofl_lock;
13
14FILE **__ofl_lock()
15{
16        LOCK(ofl_lock);
17#ifndef __LITEOS__
18    return &FILE_LIST_HEAD(ofl_head);
19#else
20        return &ofl_head;
21#endif
22}
23
24void __ofl_unlock()
25{
26        UNLOCK(ofl_lock);
27}
28
29FILE *__ofl_alloc()
30{
31#ifndef __LITEOS__
32        FILE *fsb = NULL;
33#else
34        unsigned char *fsb = NULL;
35#endif
36        size_t cnt = 0;
37        FILE *f = NULL;
38
39        LOCK(ofl_lock);
40#ifndef __LITEOS__
41        if (!FILE_LIST_EMPTY(ofl_free)) {
42                f = FILE_LIST_HEAD(ofl_free);
43                FILE_LIST_REMOVE(ofl_free);
44                UNLOCK(ofl_lock);
45
46                return f;
47        }
48#else
49        if (ofl_free) {
50                f = ofl_free;
51                ofl_free = ofl_free->next;
52                f->next = NULL;
53                f->prev = NULL;
54                UNLOCK(ofl_lock);
55
56                return f;
57        }
58#endif
59        UNLOCK(ofl_lock);
60
61        /* alloc new FILEs(8) */
62#ifndef __LITEOS__
63        fsb = (FILE *)malloc(DEFAULT_ALLOC_FILE * sizeof(FILE));
64#else
65        fsb = (unsigned char *)malloc(DEFAULT_ALLOC_FILE * sizeof(FILE));
66#endif
67        if (!fsb) {
68                return NULL;
69        }
70
71        LOCK(ofl_lock);
72#ifndef __LITEOS__
73        for (cnt = 0; cnt < DEFAULT_ALLOC_FILE; cnt++) {
74                FILE_LIST_INSERT_HEAD(ofl_free, &fsb[cnt]);
75        }
76
77        /* retrieve fist and move to next free FILE */
78        f = FILE_LIST_HEAD(ofl_free);
79        FILE_LIST_REMOVE(ofl_free);
80#else
81        ofl_free = (FILE*)fsb;
82        ofl_free->prev = NULL;
83        f = ofl_free;
84
85        for (cnt = 1; cnt < DEFAULT_ALLOC_FILE; cnt++) {
86                FILE *tmp = (FILE*)(fsb + cnt * sizeof(FILE));
87                tmp->next = NULL;
88                f->next = tmp;
89                tmp->prev = f;
90                f = f->next;
91        }
92
93        /* reset and move to next free FILE */
94        f = ofl_free;
95        ofl_free = ofl_free->next;
96        if (ofl_free) {
97                ofl_free->prev = NULL;
98        }
99        f->next = NULL;
100        f->prev = NULL;
101#endif
102
103        UNLOCK(ofl_lock);
104        return f;
105}
106
107void __ofl_free(FILE *f)
108{
109        LOCK(ofl_lock);
110        if (!f) {
111#ifndef __LITEOS__
112                UNLOCK(ofl_lock);
113#endif
114                return;
115        }
116
117#ifndef __LITEOS__
118        /* remove from head list */
119        FILE_LIST_REMOVE(f);
120
121        /* push to free list */
122        FILE_LIST_INSERT_HEAD(ofl_free, f);
123#else
124        /* remove from head list */
125        if (f->prev) {
126                f->prev->next = f->next;
127        }
128        if (f->next) {
129                f->next->prev = f->prev;
130        }
131        if (f == ofl_head) {
132                ofl_head = f->next;
133        }
134
135        /* push to free list */
136        f->next = ofl_free;
137        if (ofl_free) {
138                ofl_free->prev = f;
139        }
140        ofl_free = f;
141#endif
142
143        UNLOCK(ofl_lock);
144}
145