This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

sysdep-cancel for arm


This patch implements sysdep-cancel.h for ARM.

p.

2003-01-06  Philip Blundell  <philb@gnu.org>

	* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: New file.

--- /dev/null	2002-09-01 12:52:15.000000000 +0100
+++ sysdeps/unix/sysv/linux/arm/sysdep-cancel.h	2003-01-06 23:17:04.000000000 +0000
@@ -0,0 +1,127 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Phil Blundell <pb@nexus.co.uk>, 2003.
+
+   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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#ifndef __ASSEMBLER__
+# include <linuxthreads/internals.h>
+#endif
+
+#if !defined NOT_IN_libc || defined IS_IN_libpthread
+
+# undef PSEUDO_RET
+# define PSEUDO_RET						        \
+    ldrcc pc, [sp], $4;						        \
+    b PLTJMP(SYSCALL_ERROR)
+
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)				\
+  .section ".text";							\
+    PSEUDO_PROLOGUE;							\
+  ENTRY (name)								\
+    SINGLE_THREAD_P;							\
+    bne .Lpseudo_cancel;						\
+    DO_CALL (syscall_name, args);					\
+    cmn r0, $4096;							\
+    PSEUDO_RET_MOV;							\
+  .Lpseudo_cancel:							\
+    MAYBE_SAVE_LR;							\
+    DOCARGS_##args;	/* save syscall args around CENABLE.  */	\
+    CENABLE;								\
+    mov ip, r0;		/* put mask in safe place.  */			\
+    UNDOCARGS_##args;	/* restore syscall args.  */			\
+    swi SYS_ify (syscall_name);	/* do the call.  */			\
+    str r0, [sp, $-4]!; /* save syscall return value.  */		\
+    mov r0, ip;		/* get mask back.  */				\
+    CDISABLE;								\
+    ldr r0, [sp], $4;	/* retrieve return value.  */			\
+    UNDOC2ARGS_##args;	/* fix register damage.  */			\
+    cmn r0, $4096;
+
+# define DOCARGS_0
+# define UNDOCARGS_0
+# define UNDOC2ARGS_0
+
+# define DOCARGS_1	str r0, [sp, #-4]!;
+# define UNDOCARGS_1	ldr r0, [sp], #4;
+# define UNDOC2ARGS_1
+
+# define DOCARGS_2	str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_2	ldr r0, [sp], #4; ldr r1, [sp], #4;
+# define UNDOC2ARGS_2
+
+# define DOCARGS_3	str r2, [sp, #-4]!; str r1, [sp, #-4]!; str r0, [sp, #-4]!;
+# define UNDOCARGS_3	ldr r0, [sp], #4; ldr r1, [sp], #4; ldr r2, [sp], #4
+# define UNDOC2ARGS_3
+
+# define DOCARGS_4	stmfd sp!, {r0-r3}
+# define UNDOCARGS_4	ldmfd sp!, {r0-r3}
+# define UNDOC2ARGS_4
+
+# define DOCARGS_5	stmfd sp!, {r0-r3}
+# define UNDOCARGS_5	str r4, [sp, #-4]!; ldmfd sp, {r0-r4}
+# define UNDOC2ARGS_5   ldr r4, [sp], #20
+
+# ifdef IS_IN_libpthread
+#  define CENABLE	bl PLTJMP(__pthread_enable_asynccancel)
+#  define CDISABLE	bl PLTJMP(__pthread_disable_asynccancel)
+#  define __local_multiple_threads __pthread_multiple_threads
+# else
+#  define CENABLE	bl PLTJMP(__libc_enable_asynccancel)
+#  define CDISABLE	bl PLTJMP(__libc_disable_asynccancel)
+#  define __local_multiple_threads __libc_multiple_threads
+# endif
+
+# ifndef __ASSEMBLER__
+extern int __local_multiple_threads attribute_hidden;
+#  define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
+# else
+#  if !defined PIC
+#   define SINGLE_THREAD_P						\
+  ldr ip, =__local_multiple_threads;					\
+  ldr ip, [ip];								\
+  teq ip, #0;
+#   define MAYBE_SAVE_LR						\
+  str lr, [sp, $-4]!;
+#   define PSEUDO_RET_MOV						\
+  RETINSTR(movcc, pc, lr);						\
+  b PLTJMP(SYSCALL_ERROR)
+#   define PSEUDO_PROLOGUE
+#  else
+#   define SINGLE_THREAD_P						\
+  str lr, [sp, $-4]!;							\
+  ldr ip, 1b;								\
+  ldr lr, 2b;								\
+3:									\
+  add ip, pc, ip;							\
+  ldr ip, [ip, lr];							\
+  teq ip, #0;
+#   define PSEUDO_PROLOGUE						\
+  1:  .word _GLOBAL_OFFSET_TABLE_ - 3f - 8;				\
+  2:  .word __local_multiple_threads(GOTOFF);
+#   define MAYBE_SAVE_LR	/* lr already saved */
+#   define PSEUDO_RET_MOV PSEUDO_RET
+#  endif
+# endif
+
+#elif !defined __ASSEMBLER__
+
+/* This code should never be used but we define it anyhow.  */
+# define SINGLE_THREAD_P (1)
+
+#endif


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]