mirror of
https://git.musl-libc.org/git/musl
synced 2025-03-23 02:53:07 +03:00
implement "low hanging fruit" from C11
based on Gregor's patch sent to the list. includes: - stdalign.h - removing gets in C11 mode - adding aligned_alloc and adjusting other functions to use it - adding 'x' flag to fopen for exclusive mode
This commit is contained in:
parent
b5289fd749
commit
9bff7c133e
15
include/stdalign.h
Normal file
15
include/stdalign.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _STDALIGN_H
|
||||||
|
#define _STDALIGN_H
|
||||||
|
|
||||||
|
/* this whole header only works in C11 or with compiler extensions */
|
||||||
|
#if __STDC_VERSION__ < 201112L && defined( __GNUC__)
|
||||||
|
#define _Alignas(t) __attribute__((__aligned__(t)))
|
||||||
|
#define _Alignof(t) __alignof__(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define alignas _Alignas
|
||||||
|
#define alignof _Alignof
|
||||||
|
#define __alignas_is_defined 1
|
||||||
|
#define __alignof_is_defined 1
|
||||||
|
|
||||||
|
#endif
|
@ -90,7 +90,9 @@ int putc(int, FILE *);
|
|||||||
int putchar(int);
|
int putchar(int);
|
||||||
|
|
||||||
char *fgets(char *, int, FILE *);
|
char *fgets(char *, int, FILE *);
|
||||||
|
#if __STDC_VERSION__ < 201112L
|
||||||
char *gets(char *);
|
char *gets(char *);
|
||||||
|
#endif
|
||||||
|
|
||||||
int fputs(const char *, FILE *);
|
int fputs(const char *, FILE *);
|
||||||
int puts(const char *);
|
int puts(const char *);
|
||||||
|
@ -38,6 +38,7 @@ void *malloc (size_t);
|
|||||||
void *calloc (size_t, size_t);
|
void *calloc (size_t, size_t);
|
||||||
void *realloc (void *, size_t);
|
void *realloc (void *, size_t);
|
||||||
void free (void *);
|
void free (void *);
|
||||||
|
void *aligned_alloc(size_t alignment, size_t size);
|
||||||
|
|
||||||
void abort (void);
|
void abort (void);
|
||||||
int atexit (void (*) (void));
|
int atexit (void (*) (void));
|
||||||
|
51
src/malloc/aligned_alloc.c
Normal file
51
src/malloc/aligned_alloc.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* This function should work with most dlmalloc-like chunk bookkeeping
|
||||||
|
* systems, but it's only guaranteed to work with the native implementation
|
||||||
|
* used in this library. */
|
||||||
|
|
||||||
|
void *aligned_alloc(size_t align, size_t len)
|
||||||
|
{
|
||||||
|
unsigned char *mem, *new, *end;
|
||||||
|
size_t header, footer;
|
||||||
|
|
||||||
|
if ((align & -align & -sizeof(void *)) != align) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > SIZE_MAX - align) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (align <= 4*sizeof(size_t)) {
|
||||||
|
if (!(mem = malloc(len)))
|
||||||
|
return NULL;
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(mem = malloc(len + align-1)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
header = ((size_t *)mem)[-1];
|
||||||
|
end = mem + (header & -8);
|
||||||
|
footer = ((size_t *)end)[-2];
|
||||||
|
new = (void *)((uintptr_t)mem + align-1 & -align);
|
||||||
|
|
||||||
|
if (!(header & 7)) {
|
||||||
|
((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
|
||||||
|
((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
((size_t *)mem)[-1] = header&7 | new-mem;
|
||||||
|
((size_t *)new)[-2] = footer&7 | new-mem;
|
||||||
|
((size_t *)new)[-1] = header&7 | end-new;
|
||||||
|
((size_t *)end)[-2] = footer&7 | end-new;
|
||||||
|
|
||||||
|
if (new != mem) free(mem);
|
||||||
|
return new;
|
||||||
|
}
|
@ -3,11 +3,5 @@
|
|||||||
|
|
||||||
void *memalign(size_t align, size_t len)
|
void *memalign(size_t align, size_t len)
|
||||||
{
|
{
|
||||||
void *mem;
|
return aligned_alloc(align, len);
|
||||||
int ret;
|
|
||||||
if ((ret = posix_memalign(&mem, align, len))) {
|
|
||||||
errno = ret;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return mem;
|
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* This function should work with most dlmalloc-like chunk bookkeeping
|
|
||||||
* systems, but it's only guaranteed to work with the native implementation
|
|
||||||
* used in this library. */
|
|
||||||
|
|
||||||
int posix_memalign(void **res, size_t align, size_t len)
|
int posix_memalign(void **res, size_t align, size_t len)
|
||||||
{
|
{
|
||||||
unsigned char *mem, *new, *end;
|
void *mem = aligned_alloc(align, len);
|
||||||
size_t header, footer;
|
if (!mem) return errno;
|
||||||
|
|
||||||
if ((align & -align & -sizeof(void *)) != align) return EINVAL;
|
|
||||||
if (len > SIZE_MAX - align) return ENOMEM;
|
|
||||||
|
|
||||||
if (align <= 4*sizeof(size_t)) {
|
|
||||||
if (!(mem = malloc(len)))
|
|
||||||
return errno;
|
|
||||||
*res = mem;
|
*res = mem;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (!(mem = malloc(len + align-1)))
|
|
||||||
return errno;
|
|
||||||
|
|
||||||
header = ((size_t *)mem)[-1];
|
|
||||||
end = mem + (header & -8);
|
|
||||||
footer = ((size_t *)end)[-2];
|
|
||||||
new = (void *)((uintptr_t)mem + align-1 & -align);
|
|
||||||
|
|
||||||
if (!(header & 7)) {
|
|
||||||
((size_t *)new)[-2] = ((size_t *)mem)[-2] + (new-mem);
|
|
||||||
((size_t *)new)[-1] = ((size_t *)mem)[-1] - (new-mem);
|
|
||||||
*res = new;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
((size_t *)mem)[-1] = header&7 | new-mem;
|
|
||||||
((size_t *)new)[-2] = footer&7 | new-mem;
|
|
||||||
((size_t *)new)[-1] = header&7 | end-new;
|
|
||||||
((size_t *)end)[-2] = footer&7 | end-new;
|
|
||||||
|
|
||||||
if (new != mem) free(mem);
|
|
||||||
*res = new;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ FILE *fopen(const char *filename, const char *mode)
|
|||||||
FILE *f;
|
FILE *f;
|
||||||
int fd;
|
int fd;
|
||||||
int flags;
|
int flags;
|
||||||
int plus = !!strchr(mode, '+');
|
|
||||||
|
|
||||||
/* Check for valid initial mode character */
|
/* Check for valid initial mode character */
|
||||||
if (!strchr("rwa", *mode)) {
|
if (!strchr("rwa", *mode)) {
|
||||||
@ -14,9 +13,10 @@ FILE *fopen(const char *filename, const char *mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the flags to pass to open() */
|
/* Compute the flags to pass to open() */
|
||||||
if (plus) flags = O_RDWR;
|
if (strchr(mode, '+')) flags = O_RDWR;
|
||||||
else if (*mode == 'r') flags = O_RDONLY;
|
else if (*mode == 'r') flags = O_RDONLY;
|
||||||
else flags = O_WRONLY;
|
else flags = O_WRONLY;
|
||||||
|
if (strchr(mode, 'x')) flags |= O_EXCL;
|
||||||
if (*mode != 'r') flags |= O_CREAT;
|
if (*mode != 'r') flags |= O_CREAT;
|
||||||
if (*mode == 'w') flags |= O_TRUNC;
|
if (*mode == 'w') flags |= O_TRUNC;
|
||||||
if (*mode == 'a') flags |= O_APPEND;
|
if (*mode == 'a') flags |= O_APPEND;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user