📄 sysdep-cancel.h
字号:
/* 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; \ ldr lr, [sp], $4; \ b PLTJMP(SYSCALL_ERROR)# undef PSEUDO# define PSEUDO(name, syscall_name, args) \ .section ".text"; \ PSEUDO_PROLOGUE; \ ENTRY (name) \ SINGLE_THREAD_P_INT; \ 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 ldmfd sp, {r0-r3}; str r4, [sp, #-4]!; ldr r4, [sp, #24]# 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_INT \ ldr ip, =__local_multiple_threads; \ ldr ip, [ip]; \ teq ip, #0;# define SINGLE_THREAD_P SINGLE_THREAD_P_INT# 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_PIC(reg) \ ldr ip, 1b; \ ldr reg, 2b; \3: \ add ip, pc, ip; \ ldr ip, [ip, lr]; \ teq ip, #0;# define SINGLE_THREAD_P_INT \ str lr, [sp, $-4]!; \ SINGLE_THREAD_P_PIC(lr)# define SINGLE_THREAD_P \ SINGLE_THREAD_P_INT; \ ldr lr, [sp], $4# 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -