xref: /third_party/musl/porting/linux/user/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	return &FILE_LIST_HEAD(ofl_head);
18}
19
20void __ofl_unlock()
21{
22	UNLOCK(ofl_lock);
23}
24
25FILE *__ofl_alloc()
26{
27	FILE *fsb = NULL;
28	size_t cnt = 0;
29	FILE *f = NULL;
30
31	LOCK(ofl_lock);
32	if (!FILE_LIST_EMPTY(ofl_free)) {
33		f = FILE_LIST_HEAD(ofl_free);
34		FILE_LIST_REMOVE(ofl_free);
35		UNLOCK(ofl_lock);
36
37		return f;
38	}
39	UNLOCK(ofl_lock);
40
41	/* alloc new FILEs(8) */
42	fsb = (FILE *)malloc(DEFAULT_ALLOC_FILE * sizeof(FILE));
43	if (!fsb) {
44		return NULL;
45	}
46
47	LOCK(ofl_lock);
48
49	for (cnt = 0; cnt < DEFAULT_ALLOC_FILE; cnt++) {
50		FILE_LIST_INSERT_HEAD(ofl_free, &fsb[cnt]);
51	}
52
53	/* retrieve fist and move to next free FILE */
54	f = FILE_LIST_HEAD(ofl_free);
55	FILE_LIST_REMOVE(ofl_free);
56
57	UNLOCK(ofl_lock);
58	return f;
59}
60
61void __ofl_free(FILE *f)
62{
63	LOCK(ofl_lock);
64	if (!f) {
65		UNLOCK(ofl_lock);
66		return;
67	}
68
69	/* remove from head list */
70	FILE_LIST_REMOVE(f);
71
72	/* push to free list */
73	FILE_LIST_INSERT_HEAD(ofl_free, f);
74
75	UNLOCK(ofl_lock);
76}
77