123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- /*
- * Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
- *
- * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
- */
- #include <tls.h>
- #include <sysdep.h>
- #ifndef __ASSEMBLER__
- # include <pthreadP.h>
- #endif
- #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
- #ifdef __ASSEMBLER__
- #undef ret
- #define ret
- # undef PSEUDO
- # define PSEUDO(name, syscall_name, nargs) \
- /* vanilla version */ ` \
- ENTRY(name##_nocancel) ` \
- DO_CALL (__NR_##syscall_name) ` \
- jls [blink] ` \
- b __syscall_error@plt ` \
- END(name##_nocancel) ` \
- /* thread cancellation variant */ ` \
- ENTRY(name) ` \
- SINGLE_THREAD_P ` \
- bz name##_nocancel ` \
- DOCARGS_##nargs /* stash syscall args */ ` \
- CENABLE /* call enable_asynccancel */ ` \
- mov r9, r0 /* Safe-keep mask */ ` \
- UNDOCARGS_##nargs /* restore syscall args */ ` \
- DO_CALL (__NR_##syscall_name) ` \
- push r0 /* save syscall return value */ ` \
- mov r0, r9 /* prep mask for disable_asynccancel */ ` \
- CDISABLE ` \
- pop r0 /* get syscall ret value back */ ` \
- cmp r0, -1024 ` \
- jls [blink] ` \
- b __syscall_error@plt ` \
- END(name)
- #undef PSEUDO_END
- #define PSEUDO_END(name) \
- # ifdef IS_IN_libpthread
- # define CENABLE bl __pthread_enable_asynccancel
- # define CDISABLE bl __pthread_disable_asynccancel
- # define __local_multiple_threads __pthread_multiple_threads
- # elif !defined NOT_IN_libc
- # define CENABLE bl __libc_enable_asynccancel
- # define CDISABLE bl __libc_disable_asynccancel
- # define __local_multiple_threads __libc_multiple_threads
- # elif defined IS_IN_librt
- # define CENABLE bl __librt_enable_asynccancel
- # define CDISABLE bl __librt_disable_asynccancel
- # else
- # error Unsupported library
- # endif
- #define DO_CALL(num) \
- mov r8, num ` \
- ARC_TRAP_INSN ` \
- cmp r0, -1024
- .macro push reg
- st.a \reg, [sp, -4]
- .endm
- .macro pop reg
- ld.ab \reg, [sp, 4]
- .endm
- #define DOCARGS_0 push blink
- #define UNDOCARGS_0 pop blink
- #define DOCARGS_1 DOCARGS_0` push r0
- #define UNDOCARGS_1 pop r0` UNDOCARGS_0
- #define DOCARGS_2 DOCARGS_1` push r1
- #define UNDOCARGS_2 pop r1` UNDOCARGS_1
- #define DOCARGS_3 DOCARGS_2` push r2
- #define UNDOCARGS_3 pop r2` UNDOCARGS_2
- #define DOCARGS_4 DOCARGS_3` push r3
- #define UNDOCARGS_4 pop r3` UNDOCARGS_3
- #define DOCARGS_5 DOCARGS_4` push r4
- #define UNDOCARGS_5 pop r4` UNDOCARGS_4
- #define DOCARGS_6 DOCARGS_5` push r5
- #define UNDOCARGS_6 pop r5` UNDOCARGS_5
- #define DOCARGS_7 DOCARGS_6` push r6
- #define UNDOCARGS_7 pop r6` UNDOCARGS_6
- # define SINGLE_THREAD_P \
- THREAD_SELF r1 ` \
- ld r2, [r1, MULTIPLE_THREADS_OFFSET]` \
- cmp r2, 0
- /* ld r2, [r1, -TLS_PRE_TCB_SIZE + MULTIPLE_THREADS_OFFSET] */
- #else /* !__ASSEMBLER__ */
- /* TBD: Can use @__local_multiple_threads for libc/libpthread like ARM */
- # define SINGLE_THREAD_P \
- likely(THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
- #endif /* __ASSEMBLER__ */
- #endif
|