Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102103094
D41150.id125346.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D41150.id125346.diff
View Options
diff --git a/lib/libthr/thread/thr_malloc.c b/lib/libthr/thread/thr_malloc.c
--- a/lib/libthr/thread/thr_malloc.c
+++ b/lib/libthr/thread/thr_malloc.c
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <sys/mman.h>
+#include <string.h>
#include <rtld_malloc.h>
#include "thr_private.h"
@@ -136,6 +137,28 @@
return (res);
}
+void *
+__thr_calloc_aligned_cacheline(size_t nitems, size_t nbytes)
+{
+ struct pthread *curthread;
+ void *res;
+ size_t cnt;
+
+ cnt = nitems * nbytes;
+ if (nbytes != 0 && cnt / nbytes != nitems) {
+ /* size_t overflow. */
+ return (NULL);
+ }
+
+ curthread = _get_curthread();
+ thr_malloc_lock(curthread);
+ res = __crt_aligned_alloc_offset(CACHE_LINE_SIZE, cnt, 0);
+ thr_malloc_unlock(curthread);
+ if (res != NULL)
+ memset(res, 0, cnt);
+ return (res);
+}
+
void
__thr_malloc_prefork(struct pthread *curthread)
{
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -291,8 +291,8 @@
if (error != 0)
return (error);
}
- if ((pmutex = (pthread_mutex_t)calloc_cb(1,
- sizeof(struct pthread_mutex))) == NULL)
+ pmutex = calloc_cb(1, sizeof(struct pthread_mutex));
+ if (pmutex == NULL)
return (ENOMEM);
mutex_init_body(pmutex, attr);
*mutex = pmutex;
@@ -308,10 +308,10 @@
if (*mutex == THR_MUTEX_INITIALIZER)
ret = mutex_init(mutex, &_pthread_mutexattr_default,
- __thr_calloc);
+ __thr_calloc_aligned_cacheline);
else if (*mutex == THR_ADAPTIVE_MUTEX_INITIALIZER)
ret = mutex_init(mutex, &_pthread_mutexattr_adaptive_default,
- __thr_calloc);
+ __thr_calloc_aligned_cacheline);
else
ret = 0;
THR_LOCK_RELEASE(thread, &_mutex_static_lock);
@@ -395,7 +395,7 @@
(*mutex_attr)->m_pshared == PTHREAD_PROCESS_PRIVATE) {
__thr_malloc_init();
return (mutex_init(mutex, mutex_attr ? *mutex_attr : NULL,
- __thr_calloc));
+ __thr_calloc_aligned_cacheline));
}
pmtx = __thr_pshared_offpage(__DECONST(void *, mutex), 1);
if (pmtx == NULL)
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -1022,6 +1022,7 @@
void *__thr_malloc(size_t nbytes);
void *__thr_realloc(void *cp, size_t nbytes);
void __thr_malloc_init(void);
+void *__thr_calloc_aligned_cacheline(size_t nitmes, size_t nbytes);
void __thr_malloc_prefork(struct pthread *curthread);
void __thr_malloc_postfork(struct pthread *curthread);
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -363,8 +363,7 @@
void *xcalloc(size_t, size_t);
void *xmalloc(size_t);
char *xstrdup(const char *);
-void *malloc_aligned(size_t size, size_t align, size_t offset);
-void free_aligned(void *ptr);
+void *xmalloc_aligned(size_t size, size_t align, size_t offset);
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
extern Elf_Sym sym_zero; /* For resolving undefined weak refs. */
extern bool ld_bind_not;
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -5256,13 +5256,13 @@
tls_block_size += pre_size + tls_static_space - TLS_TCB_SIZE - post_size;
/* Allocate whole TLS block */
- tls_block = malloc_aligned(tls_block_size, maxalign, 0);
+ tls_block = xmalloc_aligned(tls_block_size, maxalign, 0);
tcb = (Elf_Addr **)(tls_block + pre_size + extra_size);
if (oldtcb != NULL) {
memcpy(tls_block, get_tls_block_ptr(oldtcb, tcbsize),
tls_static_space);
- free_aligned(get_tls_block_ptr(oldtcb, tcbsize));
+ free(get_tls_block_ptr(oldtcb, tcbsize));
/* Adjust the DTV. */
dtv = tcb[0];
@@ -5326,7 +5326,7 @@
}
}
free(dtv);
- free_aligned(get_tls_block_ptr(tcb, tcbsize));
+ free(get_tls_block_ptr(tcb, tcbsize));
}
#endif /* TLS_VARIANT_I */
@@ -5352,7 +5352,7 @@
size = roundup(tls_static_space, ralign) + roundup(tcbsize, ralign);
assert(tcbsize >= 2*sizeof(Elf_Addr));
- tls = malloc_aligned(size, ralign, 0 /* XXX */);
+ tls = xmalloc_aligned(size, ralign, 0 /* XXX */);
dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr));
segbase = (Elf_Addr)(tls + roundup(tls_static_space, ralign));
@@ -5431,11 +5431,11 @@
for (i = 0; i < dtvsize; i++) {
if (dtv[i + 2] != 0 && (dtv[i + 2] < tlsstart ||
dtv[i + 2] > tlsend)) {
- free_aligned((void *)dtv[i + 2]);
+ free((void *)dtv[i + 2]);
}
}
- free_aligned((void *)tlsstart);
+ free((void *)tlsstart);
free((void *)dtv);
}
@@ -5472,7 +5472,7 @@
obj->tls_dynamic = true;
- p = malloc_aligned(obj->tlssize, obj->tlsalign, obj->tlspoffset);
+ p = xmalloc_aligned(obj->tlssize, obj->tlsalign, obj->tlspoffset);
memcpy(p, obj->tlsinit, obj->tlsinitsize);
memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
return (p);
diff --git a/libexec/rtld-elf/rtld_malloc.h b/libexec/rtld-elf/rtld_malloc.h
--- a/libexec/rtld-elf/rtld_malloc.h
+++ b/libexec/rtld-elf/rtld_malloc.h
@@ -34,6 +34,7 @@
#ifndef RTLD_MALLOC_H
#define RTLD_MALLOC_H
+void *__crt_aligned_alloc_offset(size_t align, size_t size, size_t offset);
void *__crt_calloc(size_t num, size_t size);
void __crt_free(void *cp);
void *__crt_malloc(size_t nbytes);
diff --git a/libexec/rtld-elf/rtld_malloc.c b/libexec/rtld-elf/rtld_malloc.c
--- a/libexec/rtld-elf/rtld_malloc.c
+++ b/libexec/rtld-elf/rtld_malloc.c
@@ -75,8 +75,8 @@
union overhead {
union overhead *ov_next; /* when free */
struct {
- u_char ovu_magic; /* magic number */
- u_char ovu_index; /* bucket # */
+ uint16_t ovu_index; /* bucket # */
+ uint8_t ovu_magic; /* magic number */
} ovu;
#define ov_magic ovu.ovu_magic
#define ov_index ovu.ovu_index
@@ -86,13 +86,15 @@
static int morepages(int n);
#define MAGIC 0xef /* magic # on accounting info */
+#define AMAGIC 0xdf /* magic # for aligned alloc */
/*
* nextf[i] is the pointer to the next free block of size
* (FIRST_BUCKET_SIZE << i). The overhead information precedes the data
* area returned to the user.
*/
-#define FIRST_BUCKET_SIZE 8
+#define LOW_BITS 3
+#define FIRST_BUCKET_SIZE (1U << LOW_BITS)
#define NBUCKETS 30
static union overhead *nextf[NBUCKETS];
@@ -106,10 +108,10 @@
* increasing order.
*/
-static union overhead *
+static void *
cp2op(void *cp)
{
- return ((union overhead *)((caddr_t)cp - sizeof(union overhead)));
+ return (((caddr_t)cp - sizeof(union overhead)));
}
void *
@@ -169,6 +171,28 @@
return (ret);
}
+void *
+__crt_aligned_alloc_offset(size_t align, size_t size, size_t offset)
+{
+ void *mem, *ov;
+ union overhead ov1;
+ uintptr_t x;
+
+ if (align < FIRST_BUCKET_SIZE)
+ align = FIRST_BUCKET_SIZE;
+ offset &= align - 1;
+ mem = __crt_malloc(size + align + offset + sizeof(union overhead));
+ if (mem == NULL)
+ return (NULL);
+ x = roundup((uintptr_t)mem + sizeof(union overhead), align);
+ x += offset;
+ ov = cp2op((void *)x);
+ ov1.ov_magic = AMAGIC;
+ ov1.ov_index = x - (uintptr_t)mem - sizeof(union overhead);
+ memcpy(ov, &ov1, sizeof(ov1));
+ return ((void *)x);
+}
+
/*
* Allocate more memory to the indicated bucket.
*/
@@ -210,12 +234,16 @@
void
__crt_free(void *cp)
{
+ union overhead *op, op1;
+ void *opx;
int size;
- union overhead *op;
if (cp == NULL)
return;
- op = cp2op(cp);
+ opx = cp2op(cp);
+ memcpy(&op1, opx, sizeof(op1));
+ op = op1.ov_magic == AMAGIC ? (void *)((caddr_t)cp - op1.ov_index) :
+ opx;
if (op->ov_magic != MAGIC)
return; /* sanity */
size = op->ov_index;
diff --git a/libexec/rtld-elf/xmalloc.c b/libexec/rtld-elf/xmalloc.c
--- a/libexec/rtld-elf/xmalloc.c
+++ b/libexec/rtld-elf/xmalloc.c
@@ -77,34 +77,18 @@
}
void *
-malloc_aligned(size_t size, size_t align, size_t offset)
+xmalloc_aligned(size_t size, size_t align, size_t offset)
{
- char *mem, *res;
- uintptr_t x;
+ void *res;
offset &= align - 1;
if (align < sizeof(void *))
align = sizeof(void *);
- mem = xmalloc(size + 3 * align + offset);
- x = roundup((uintptr_t)mem + sizeof(void *), align);
- x += offset;
- res = (void *)x;
- x -= sizeof(void *);
- memcpy((void *)x, &mem, sizeof(mem));
+ res = __crt_aligned_alloc_offset(align, size, offset);
+ if (res == NULL) {
+ rtld_fdputstr(STDERR_FILENO, "Out of memory\n");
+ _exit(1);
+ }
return (res);
}
-
-void
-free_aligned(void *ptr)
-{
- void *mem;
- uintptr_t x;
-
- if (ptr == NULL)
- return;
- x = (uintptr_t)ptr;
- x -= sizeof(void *);
- memcpy(&mem, (void *)x, sizeof(mem));
- free(mem);
-}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 8, 3:51 PM (1 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14537891
Default Alt Text
D41150.id125346.diff (8 KB)
Attached To
Mode
D41150: Implement __crt_aligned_alloc().
Attached
Detach File
Event Timeline
Log In to Comment