about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/sparc
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-11-12 14:01:36 -0200
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2017-08-24 14:58:35 -0300
commitebd6f0076a83bb25a9853773fbfbcff00b4c9a32 (patch)
tree07b02599002f24fd7fa37e1ddfa332f6a236ec99 /sysdeps/unix/sysv/linux/sparc
parent8aa48656bb00074f3f422d805f15d07d786970ba (diff)
downloadglibc-ebd6f0076a83bb25a9853773fbfbcff00b4c9a32.tar.gz
glibc-ebd6f0076a83bb25a9853773fbfbcff00b4c9a32.tar.xz
glibc-ebd6f0076a83bb25a9853773fbfbcff00b4c9a32.zip
Remove cancellation support for syscall generation
This patch removes the cancellation mark from the auto-generation syscall
script.  Now all the cancellable syscalls are done throught C code using
the SYSCALL_CANCEL macro.  It simplifies the assembly required to each
architecture port, since the SYSCALL_CANCEL uses the already defined
INLINE_SYSCALL macros, and allows a more straigh fix on cancellation
machanism (since no more specific assembly fixes will be required).

Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32,
aarch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu.A
Also with build-many-glibc.py with remaning touched architectures.

	* sysdeps/unix/make-syscalls.sh: Remove cancellable tagging for
	syscall definitions.
	* sysdeps/unix/syscall-template.S (SYSCALL_CANCELLABLE): Remove
	definition.
	* sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (__local_enable_asynccancel): Likewise.
	[IS_IN (libpthread)] (__local_disable_asynccancel): Likewise.
	[IS_IN (libc)] (__local_enable_asynccancel): Likewise.
	[IS_IN (libc)] (__local_enable_asynccancel): Likewise.
	[IS_IN (librt)] (__local_disable_asynccancel): Likewise.
	[IS_IN (librt)] (__local_disable_asynccancel): Likewise.
	(CENABLE): Likewise.
	(CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO): Remove
	defintion.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h (PSEUDO):
	Remove definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	(SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/mips/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/nios2/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Remove file.
	* sysdeps/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sysdep-cancel.h: New file.
	* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Remove file.
	* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h: New file.
	* sysdeps/unix/sysv/linux/tile/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
	* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Remove
	definition.
	(PSEUDO_END): Likewise.
	[IS_IN (libpthread)] (CENABLE): Likewise.
	[IS_IN (libpthread)] (CDISABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (libc)] (CENABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[IS_IN (librt)] (CDISABLE): Likewise.
	[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
Diffstat (limited to 'sysdeps/unix/sysv/linux/sparc')
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h111
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h109
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h36
3 files changed, 36 insertions, 220 deletions
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
deleted file mode 100644
index c513212f1e..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <tls.h>
-#ifndef __ASSEMBLER__
-# include <nptl/pthreadP.h>
-#endif
-
-#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
-
-# undef PSEUDO
-# define PSEUDO(name, syscall_name, args)	\
-	.text;					\
-	.globl		__syscall_error;	\
-ENTRY(name)					\
-	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
-	cmp %g1, 0;				\
-	bne 1f;					\
-.type	__##syscall_name##_nocancel,@function;	\
-.globl	__##syscall_name##_nocancel;		\
-__##syscall_name##_nocancel:			\
-	 mov SYS_ify(syscall_name), %g1;	\
-	ta 0x10;				\
-	bcc 8f;					\
-	 mov %o7, %g1;				\
-	call __syscall_error;			\
-	 mov %g1, %o7;				\
-8:	jmpl %o7 + 8, %g0;			\
-	 nop;					\
-.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
-1:	save %sp, -96, %sp;			\
-	cfi_def_cfa_register(%fp);		\
-	cfi_window_save;			\
-	cfi_register(%o7, %i7);			\
-	CENABLE;				\
-	 nop;					\
-	mov %o0, %l0;				\
-	COPY_ARGS_##args			\
-	mov SYS_ify(syscall_name), %g1;		\
-	ta 0x10;				\
-	bcc 1f;					\
-	 mov %o0, %l1;				\
-	CDISABLE;				\
-	 mov %l0, %o0;				\
-	call __syscall_error;			\
-	 mov %l1, %o0;				\
-	b 2f;					\
-	 mov -1, %l1;				\
-1:	CDISABLE;				\
-	 mov %l0, %o0;				\
-2:	jmpl %i7 + 8, %g0;			\
-	 restore %g0, %l1, %o0;
-
-
-# if IS_IN (libpthread)
-#  define CENABLE	call __pthread_enable_asynccancel
-#  define CDISABLE	call __pthread_disable_asynccancel
-# elif IS_IN (libc)
-#  define CENABLE	call __libc_enable_asynccancel
-#  define CDISABLE	call __libc_disable_asynccancel
-# elif IS_IN (librt)
-#  define CENABLE	call __librt_enable_asynccancel
-#  define CDISABLE	call __librt_disable_asynccancel
-# else
-#  error Unsupported library
-# endif
-
-#define COPY_ARGS_0	/* Nothing */
-#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0;
-#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1;
-#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2;
-#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3;
-#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4;
-#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5;
-
-# ifndef __ASSEMBLER__
-#  define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
-				   header.multiple_threads) == 0, 1)
-# else
-#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
-# endif
-
-#elif !defined __ASSEMBLER__
-
-# define SINGLE_THREAD_P (1)
-# define NO_CANCELLATION 1
-
-#endif
-
-#ifndef __ASSEMBLER__
-# define RTLD_SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
-				   header.multiple_threads) == 0, 1)
-#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
deleted file mode 100644
index 45fbd737e0..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <tls.h>
-#ifndef __ASSEMBLER__
-# include <nptl/pthreadP.h>
-#endif
-
-#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
-
-# undef PSEUDO
-# define PSEUDO(name, syscall_name, args)	\
-	.text;					\
-	.globl		__syscall_error;	\
-ENTRY(name)					\
-	ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
-	brnz,pn %g1, 1f;			\
-.type	__##syscall_name##_nocancel,@function;	\
-.globl	__##syscall_name##_nocancel;		\
-__##syscall_name##_nocancel:			\
-	 mov SYS_ify(syscall_name), %g1;	\
-	ta 0x6d;				\
-	bcc,pt %xcc, 8f;			\
-	 mov %o7, %g1;				\
-	call __syscall_error;			\
-	 mov %g1, %o7;				\
-8:	jmpl %o7 + 8, %g0;			\
-	 nop;					\
-.size	__##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
-1:	save %sp, -192, %sp;			\
-	cfi_def_cfa_register(%fp);		\
-	cfi_window_save;			\
-	cfi_register(%o7, %i7);			\
-	CENABLE;				\
-	 nop;					\
-	mov %o0, %l0;				\
-	COPY_ARGS_##args			\
-	mov SYS_ify(syscall_name), %g1;		\
-	ta 0x6d;				\
-	bcc,pt %xcc, 1f;			\
-	 mov %o0, %l1;				\
-	CDISABLE;				\
-	 mov %l0, %o0;				\
-	call __syscall_error;			\
-	 mov %l1, %o0;				\
-	ba,pt %xcc, 2f;				\
-	 mov -1, %l1;				\
-1:	CDISABLE;				\
-	 mov %l0, %o0;				\
-2:	jmpl %i7 + 8, %g0;			\
-	 restore %g0, %l1, %o0;
-
-# if IS_IN (libpthread)
-#  define CENABLE	call __pthread_enable_asynccancel
-#  define CDISABLE	call __pthread_disable_asynccancel
-# elif IS_IN (libc)
-#  define CENABLE	call __libc_enable_asynccancel
-#  define CDISABLE	call __libc_disable_asynccancel
-# elif IS_IN (librt)
-#  define CENABLE	call __librt_enable_asynccancel
-#  define CDISABLE	call __librt_disable_asynccancel
-# else
-#  error Unsupported library
-# endif
-
-#define COPY_ARGS_0	/* Nothing */
-#define COPY_ARGS_1	COPY_ARGS_0 mov %i0, %o0;
-#define COPY_ARGS_2	COPY_ARGS_1 mov %i1, %o1;
-#define COPY_ARGS_3	COPY_ARGS_2 mov %i2, %o2;
-#define COPY_ARGS_4	COPY_ARGS_3 mov %i3, %o3;
-#define COPY_ARGS_5	COPY_ARGS_4 mov %i4, %o4;
-#define COPY_ARGS_6	COPY_ARGS_5 mov %i5, %o5;
-
-# ifndef __ASSEMBLER__
-#  define SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF,				      \
-				   header.multiple_threads) == 0, 1)
-# else
-#  define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
-# endif
-
-#elif !defined __ASSEMBLER__
-
-# define SINGLE_THREAD_P (1)
-# define NO_CANCELLATION 1
-
-#endif
-
-#ifndef __ASSEMBLER__
-# define RTLD_SINGLE_THREAD_P \
-  __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
-				   header.multiple_threads) == 0, 1)
-#endif
diff --git a/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h b/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
new file mode 100644
index 0000000000..412b31af10
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
@@ -0,0 +1,36 @@
+/* Cancellable system call stubs.  Linux/Sparc version.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+#include <tls.h>
+#include <nptl/pthreadP.h>
+
+#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
+
+# define SINGLE_THREAD_P \
+  __glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
+
+#else
+
+# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
+
+#endif
+
+#define RTLD_SINGLE_THREAD_P \
+  __glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)