Merge "implement pthread mutex deadlock detection"
diff --git a/libc/Android.mk b/libc/Android.mk
index 71c721b..3043e62 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -512,11 +512,13 @@
endif
else # !arm
ifeq ($(TARGET_ARCH),x86)
- libc_crt_target_cflags := -m32
-
- # Enable recent IA friendly memory routines (such as for Atom)
- # These will not work on the earlier x86 machines
- libc_common_cflags += -mtune=i686 -DUSE_SSSE3 -DUSE_SSE2
+ libc_crt_target_cflags :=
+ ifeq ($(ARCH_X86_HAVE_SSE2),true)
+ libc_crt_target_cflags += -DUSE_SSE2=1
+ endif
+ ifeq ($(ARCH_X86_HAVE_SSSE3),true)
+ libc_crt_target_cflags += -DUSE_SSSE3=1
+ endif
endif # x86
endif # !arm
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index fa02edc..800726a 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -50,6 +50,7 @@
uid_t getresuid:getresuid32 () 209
gid_t getresgid:getresgid32 () 211
pid_t gettid() 224
+ssize_t readahead(int, off64_t, size_t) 225
int getgroups:getgroups32(int, gid_t *) 205
pid_t getpgid(pid_t) 132
pid_t getppid() 64
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index e6c84f6..1f2a1cd 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -14,6 +14,7 @@
syscall_src += arch-arm/syscalls/getresuid.S
syscall_src += arch-arm/syscalls/getresgid.S
syscall_src += arch-arm/syscalls/gettid.S
+syscall_src += arch-arm/syscalls/readahead.S
syscall_src += arch-arm/syscalls/getgroups.S
syscall_src += arch-arm/syscalls/getpgid.S
syscall_src += arch-arm/syscalls/getppid.S
diff --git a/libc/arch-arm/syscalls/readahead.S b/libc/arch-arm/syscalls/readahead.S
new file mode 100644
index 0000000..6aa8265
--- /dev/null
+++ b/libc/arch-arm/syscalls/readahead.S
@@ -0,0 +1,16 @@
+/* autogenerated by gensyscalls.py */
+#include <machine/asm.h>
+#include <sys/linux-syscalls.h>
+
+ENTRY(readahead)
+ mov ip, sp
+ .save {r4, r5, r6, r7}
+ stmfd sp!, {r4, r5, r6, r7}
+ ldmfd ip, {r4, r5, r6}
+ ldr r7, =__NR_readahead
+ swi #0
+ ldmfd sp!, {r4, r5, r6, r7}
+ movs r0, r0
+ bxpl lr
+ b __set_syscall_errno
+END(readahead)
diff --git a/libc/arch-sh/syscalls.mk b/libc/arch-sh/syscalls.mk
index d4e4583..e6fba58 100644
--- a/libc/arch-sh/syscalls.mk
+++ b/libc/arch-sh/syscalls.mk
@@ -15,6 +15,7 @@
syscall_src += arch-sh/syscalls/getresuid.S
syscall_src += arch-sh/syscalls/getresgid.S
syscall_src += arch-sh/syscalls/gettid.S
+syscall_src += arch-sh/syscalls/readahead.S
syscall_src += arch-sh/syscalls/getgroups.S
syscall_src += arch-sh/syscalls/getpgid.S
syscall_src += arch-sh/syscalls/getppid.S
diff --git a/libc/arch-sh/syscalls/readahead.S b/libc/arch-sh/syscalls/readahead.S
new file mode 100644
index 0000000..df64b5f
--- /dev/null
+++ b/libc/arch-sh/syscalls/readahead.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type readahead, @function
+ .globl readahead
+ .align 4
+
+readahead:
+
+ /* invoke trap */
+ mov.l 0f, r3 /* trap num */
+ trapa #(4 + 0x10)
+
+ /* check return value */
+ cmp/pz r0
+ bt __NR_readahead_end
+
+ /* keep error number */
+ sts.l pr, @-r15
+ mov.l 1f, r1
+ jsr @r1
+ mov r0, r4
+ lds.l @r15+, pr
+
+__NR_readahead_end:
+ rts
+ nop
+
+ .align 2
+0: .long __NR_readahead
+1: .long __set_syscall_errno
diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk
index 13edeb0..f263470 100644
--- a/libc/arch-x86/syscalls.mk
+++ b/libc/arch-x86/syscalls.mk
@@ -15,6 +15,7 @@
syscall_src += arch-x86/syscalls/getresuid.S
syscall_src += arch-x86/syscalls/getresgid.S
syscall_src += arch-x86/syscalls/gettid.S
+syscall_src += arch-x86/syscalls/readahead.S
syscall_src += arch-x86/syscalls/getgroups.S
syscall_src += arch-x86/syscalls/getpgid.S
syscall_src += arch-x86/syscalls/getppid.S
diff --git a/libc/arch-x86/syscalls/readahead.S b/libc/arch-x86/syscalls/readahead.S
new file mode 100644
index 0000000..b89314f
--- /dev/null
+++ b/libc/arch-x86/syscalls/readahead.S
@@ -0,0 +1,32 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+ .text
+ .type readahead, @function
+ .globl readahead
+ .align 4
+
+readahead:
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %esi
+ mov 20(%esp), %ebx
+ mov 24(%esp), %ecx
+ mov 28(%esp), %edx
+ mov 32(%esp), %esi
+ movl $__NR_readahead, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ ret
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
index 8c75e9c..496cd1c 100644
--- a/libc/bionic/dlmalloc.c
+++ b/libc/bionic/dlmalloc.c
@@ -774,6 +774,22 @@
void* dlmemalign(size_t, size_t);
/*
+ int posix_memalign(void **memptr, size_t alignment, size_t size);
+ Places a pointer to a newly allocated chunk of size bytes, aligned
+ in accord with the alignment argument, in *memptr.
+
+ The return value is 0 on success, and ENOMEM on failure.
+
+ The alignment argument should be a power of two. If the argument is
+ not a power of two, the nearest greater power is used.
+ 8-byte alignment is guaranteed by normal malloc calls, so don't
+ bother calling memalign with an argument of 8 or less.
+
+ Overreliance on posix_memalign is a sure way to fragment space.
+*/
+int posix_memalign(void **memptr, size_t alignment, size_t size);
+
+/*
valloc(size_t n);
Equivalent to memalign(pagesize, n), where pagesize is the page
size of the system. If the pagesize is unknown, 4096 is used.
@@ -4507,6 +4523,18 @@
return internal_memalign(gm, alignment, bytes);
}
+int posix_memalign(void **memptr, size_t alignment, size_t size) {
+ int ret = 0;
+
+ *memptr = dlmemalign(alignment, size);
+
+ if (*memptr == 0) {
+ ret = ENOMEM;
+ }
+
+ return ret;
+}
+
void** dlindependent_calloc(size_t n_elements, size_t elem_size,
void* chunks[]) {
size_t sz = elem_size; /* serves as 1-element array */
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 5dc8a87..e5caadd 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -67,6 +67,8 @@
extern unsigned long long strtoull(const char *, char **, int);
extern double strtod(const char *nptr, char **endptr);
+extern int posix_memalign(void **memptr, size_t alignment, size_t size);
+
static __inline__ float strtof(const char *nptr, char **endptr)
{
return (float)strtod(nptr, endptr);
diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h
index 930508a..5361ace 100644
--- a/libc/include/sys/linux-syscalls.h
+++ b/libc/include/sys/linux-syscalls.h
@@ -20,6 +20,7 @@
#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209)
#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211)
#define __NR_gettid (__NR_SYSCALL_BASE + 224)
+#define __NR_readahead (__NR_SYSCALL_BASE + 225)
#define __NR_getgroups32 (__NR_SYSCALL_BASE + 205)
#define __NR_getpgid (__NR_SYSCALL_BASE + 132)
#define __NR_getppid (__NR_SYSCALL_BASE + 64)
diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h
index f463127..867cfe6 100644
--- a/libc/include/sys/linux-unistd.h
+++ b/libc/include/sys/linux-unistd.h
@@ -20,6 +20,7 @@
uid_t getresuid (void);
gid_t getresgid (void);
pid_t gettid (void);
+ssize_t readahead (int, off64_t, size_t);
int getgroups (int, gid_t *);
pid_t getpgid (pid_t);
pid_t getppid (void);
diff --git a/libc/kernel/common/video/dsscomp.h b/libc/kernel/common/video/dsscomp.h
index 92fd789..575071f 100644
--- a/libc/kernel/common/video/dsscomp.h
+++ b/libc/kernel/common/video/dsscomp.h
@@ -228,129 +228,145 @@
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
OMAP_DSS_BUFTYPE_TILER_PAGE,
};
-struct dss2_ovl_info {
- struct dss2_ovl_cfg cfg;
+enum omapdss_buffer_addressing_type {
+ OMAP_DSS_BUFADDR_DIRECT,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ OMAP_DSS_BUFADDR_BYTYPE,
+ OMAP_DSS_BUFADDR_ION,
+ OMAP_DSS_BUFADDR_GRALLOC,
+ OMAP_DSS_BUFADDR_OVL_IX,
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ OMAP_DSS_BUFADDR_LAYER_IX,
+ OMAP_DSS_BUFADDR_FB,
+};
+struct dss2_ovl_info {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dss2_ovl_cfg cfg;
+ enum omapdss_buffer_addressing_type addressing;
union {
struct {
- void *address;
- __u16 ba_type;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
- __u16 uv_type;
+ void *address;
+ void *uv_address;
};
struct {
- __u32 ba;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum omapdss_buffer_type ba_type;
+ enum omapdss_buffer_type uv_type;
+ };
+ struct {
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 ba;
__u32 uv;
};
};
-};
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
struct dss2_mgr_info {
__u32 ix;
__u32 default_color;
- enum omap_dss_trans_key_type trans_key_type;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum omap_dss_trans_key_type trans_key_type;
__u32 trans_key;
struct omap_dss_cpr_coefs cpr_coefs;
__u8 trans_enabled;
- __u8 interlaced;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u8 interlaced;
__u8 alpha_blending;
__u8 cpr_enabled;
__u8 swap_rb;
-} __attribute__ ((aligned(4)));
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+} __attribute__ ((aligned(4)));
enum dsscomp_setup_mode {
DSSCOMP_SETUP_MODE_APPLY = (1 << 0),
DSSCOMP_SETUP_MODE_DISPLAY = (1 << 1),
- DSSCOMP_SETUP_MODE_CAPTURE = (1 << 2),
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ DSSCOMP_SETUP_MODE_CAPTURE = (1 << 2),
DSSCOMP_SETUP_APPLY = DSSCOMP_SETUP_MODE_APPLY,
DSSCOMP_SETUP_DISPLAY =
DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_DISPLAY,
- DSSCOMP_SETUP_CAPTURE =
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ DSSCOMP_SETUP_CAPTURE =
DSSCOMP_SETUP_MODE_APPLY | DSSCOMP_SETUP_MODE_CAPTURE,
DSSCOMP_SETUP_DISPLAY_CAPTURE =
DSSCOMP_SETUP_DISPLAY | DSSCOMP_SETUP_CAPTURE,
-};
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
struct dsscomp_setup_mgr_data {
__u32 sync_id;
struct dss2_rect_t win;
- enum dsscomp_setup_mode mode;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum dsscomp_setup_mode mode;
__u16 num_ovls;
__u16 get_sync_obj;
struct dss2_mgr_info mgr;
- struct dss2_ovl_info ovls[0];
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dss2_ovl_info ovls[0];
};
struct dsscomp_check_ovl_data {
enum dsscomp_setup_mode mode;
- struct dss2_mgr_info mgr;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dss2_mgr_info mgr;
struct dss2_ovl_info ovl;
};
struct dsscomp_setup_dispc_data {
- __u32 sync_id;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 sync_id;
enum dsscomp_setup_mode mode;
__u16 num_ovls;
__u16 num_mgrs;
- __u16 get_sync_obj;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u16 get_sync_obj;
struct dss2_mgr_info mgrs[3];
struct dss2_ovl_info ovls[5];
};
-struct dsscomp_wb_copy_data {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct dsscomp_wb_copy_data {
struct dss2_ovl_info ovl, wb;
};
struct dsscomp_display_info {
- __u32 ix;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 ix;
__u32 overlays_available;
__u32 overlays_owned;
enum omap_channel channel;
- enum omap_dss_display_state state;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ enum omap_dss_display_state state;
__u8 enabled;
struct omap_video_timings timings;
struct s3d_disp_info s3d_info;
- struct dss2_mgr_info mgr;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dss2_mgr_info mgr;
__u16 width_in_mm;
__u16 height_in_mm;
__u32 modedb_len;
- struct dsscomp_videomode modedb[];
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dsscomp_videomode modedb[];
};
struct dsscomp_setup_display_data {
__u32 ix;
- struct dsscomp_videomode mode;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct dsscomp_videomode mode;
};
enum dsscomp_wait_phase {
DSSCOMP_WAIT_PROGRAMMED = 1,
- DSSCOMP_WAIT_DISPLAYED,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ DSSCOMP_WAIT_DISPLAYED,
DSSCOMP_WAIT_RELEASED,
};
struct dsscomp_wait_data {
- __u32 timeout_us;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 timeout_us;
enum dsscomp_wait_phase phase;
};
-#define DSSCOMP_SETUP_MGR _IOW('O', 128, struct dsscomp_setup_mgr_data)
-#define DSSCOMP_CHECK_OVL _IOWR('O', 129, struct dsscomp_check_ovl_data)
+#define DSSCIOC_SETUP_MGR _IOW('O', 128, struct dsscomp_setup_mgr_data)
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define DSSCOMP_WB_COPY _IOW('O', 130, struct dsscomp_wb_copy_data)
-#define DSSCOMP_QUERY_DISPLAY _IOWR('O', 131, struct dsscomp_display_info)
-#define DSSCOMP_WAIT _IOW('O', 132, struct dsscomp_wait_data)
-#define DSSCOMP_SETUP_DISPC _IOW('O', 133, struct dsscomp_setup_dispc_data)
+#define DSSCIOC_CHECK_OVL _IOWR('O', 129, struct dsscomp_check_ovl_data)
+#define DSSCIOC_WB_COPY _IOW('O', 130, struct dsscomp_wb_copy_data)
+#define DSSCIOC_QUERY_DISPLAY _IOWR('O', 131, struct dsscomp_display_info)
+#define DSSCIOC_WAIT _IOW('O', 132, struct dsscomp_wait_data)
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#define DSSCOMP_SETUP_DISPLAY _IOW('O', 134, struct dsscomp_setup_display_data)
+#define DSSCIOC_SETUP_DISPC _IOW('O', 133, struct dsscomp_setup_dispc_data)
+#define DSSCIOC_SETUP_DISPLAY _IOW('O', 134, struct dsscomp_setup_display_data)
#endif
diff --git a/libc/unistd/opendir.c b/libc/unistd/opendir.c
index afa3ea0..f178bc6 100644
--- a/libc/unistd/opendir.c
+++ b/libc/unistd/opendir.c
@@ -92,6 +92,9 @@
_readdir_unlocked(DIR* dir)
{
struct dirent* entry;
+#ifndef NDEBUG
+ unsigned reclen;
+#endif
if ( !dir->_DIR_avail )
{
@@ -115,15 +118,18 @@
if (((long)(void*)entry & 3) != 0)
return NULL;
- if ( (unsigned)entry->d_reclen > sizeof(*entry) ||
- entry->d_reclen <= offsetof(struct dirent, d_name) )
+#ifndef NDEBUG
+ // paranoid testing of the interface with the kernel getdents64 system call
+ reclen = offsetof(struct dirent, d_name) + strlen(entry->d_name) + 1;
+ if ( reclen > sizeof(*entry) || reclen <= offsetof(struct dirent, d_name) )
goto Bad;
- if ( (char*)entry + entry->d_reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) )
+ if ( (char*)entry + reclen > (char*)dir->_DIR_buff + sizeof(dir->_DIR_buff) )
goto Bad;
- if ( !memchr( entry->d_name, 0, entry->d_reclen - offsetof(struct dirent, d_name)) )
+ if ( !memchr( entry->d_name, 0, reclen - offsetof(struct dirent, d_name)) )
goto Bad;
+#endif
dir->_DIR_next = (struct dirent*)((char*)entry + entry->d_reclen);
dir->_DIR_avail -= entry->d_reclen;
diff --git a/libc/unistd/pathconf.c b/libc/unistd/pathconf.c
index 032f918..26b580f 100644
--- a/libc/unistd/pathconf.c
+++ b/libc/unistd/pathconf.c
@@ -70,13 +70,12 @@
};
int nn = 0;
- for (;;) {
- if ( known64[nn] == EOL_MAGIC )
- return 32;
-
- if ( known64[nn] == s->f_type )
+ for (; known64[nn] != EOL_MAGIC; ++nn) {
+ if (known64[nn] == s->f_type) {
return 64;
+ }
}
+ return 32;
}
@@ -99,12 +98,10 @@
};
int nn = 0;
- for (;;) {
- if ( knownMax[nn].type == EOL_MAGIC )
- return LINK_MAX;
-
- if ( knownMax[nn].type == s->f_type )
+ for (; knownMax[nn].type != EOL_MAGIC; ++nn) {
+ if (knownMax[nn].type == s->f_type) {
return knownMax[nn].max;
+ }
}
return LINK_MAX;
}
@@ -121,12 +118,12 @@
};
int nn = 0;
- for (;;) {
- if (knownNoSymlinks[nn] == 0)
- return 1;
- if (knownNoSymlinks[nn] == s->f_type)
+ for (; knownNoSymlinks[nn] != EOL_MAGIC; ++nn) {
+ if (knownNoSymlinks[nn] == s->f_type) {
return 0;
+ }
}
+ return 1;
}
static long