2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
7 * AROS-thread-safe versions of libc memory allocation routines
8 * This does not work with Android's bionic.
14 Forbid-locking is needed because AROS must protect calls to Linux memory
15 allocation functions against reentrancy. Linux malloc's pthread mutex
16 protection (or whatever it uses) will not work, because that one protects
17 Linux thread #1 against other Linux threads. However AROS tasks are all
18 inside the same Linux thread.
20 So if AROS task #1 is in the middle of Linux malloc, AROS task #2 may end
21 up doing Linux malloc call as well and when it hits Linux malloc's
22 pthread mutex (or whatever protection), that one will see that lock is being
23 held, but by same thread. If the used Linux locking allows nesting it causes
24 havoc (2 malloc's running at the same time). If it doesn't allow nesting,
27 The locking is only valid inside the AROS Linux thread. Other threads within
28 AROS process do not need it, because it will be handled by Linux malloc's
29 pthread mutex. Moreover, calling Forbid() from multiple Linux threads will
30 cause the TDNestCnt to become damaged.
32 TDNestCnt is "per task" and while other Linux thread calls Forbid() the AROS
33 Linux thread may be running AROS task #1. Then when that other Linux thread
34 does matching Permit(), AROS Linux thread may have already switched to
35 another AROS task. So the effect is like AROS task #1 calling Forbid() and
36 AROS task #2 calling Permit().
40 This code is compiled with the kernel compiler but calls code
41 from exec.library. This can only work if function calling
42 convention for kernel and target compiler are the same.
43 Up to now this seems to be the case for all linux hosted ports
44 as UNIX calling is often taken as reference for the AROS
50 #include <proto/exec.h>
51 #include <sys/types.h>
59 #define THREADID pid_t thistid = syscall(SYS_gettid);
60 #define MEMLOCK if (SysBase != NULL && thistid == arostid) Forbid();
61 #define MEMUNLOCK if (SysBase != NULL && thistid == arostid) Permit();
63 extern struct ExecBase
*SysBase
;
64 extern void * __libc_malloc(size_t);
65 extern void __libc_free(void *);
66 extern void * __libc_calloc(size_t, size_t);
67 extern void * __libc_realloc(void * mem
, size_t newsize
);
69 void * malloc(size_t size
)
76 res
= __libc_malloc(size
);
83 void free(void * addr
)
94 void * calloc(size_t n
, size_t size
)
101 res
= __libc_calloc(n
, size
);
108 void *realloc(void *ptr
, size_t size
)
115 res
= __libc_realloc(ptr
, size
);