4 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; only
9 * version 2.1 of the License.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
30 __attribute__((weak
)) __thread
volatile struct rseq __rseq_abi
= {
34 /* Own state, not shared with other libs. */
35 static __thread
int rseq_registered
;
37 static pthread_key_t rseq_key
;
41 static int sys_rseq(volatile struct rseq
*rseq_abi
, int flags
)
43 return syscall(__NR_rseq
, rseq_abi
, flags
);
46 static int sys_rseq(volatile struct rseq
*rseq_abi
, int flags
)
53 static void signal_off_save(sigset_t
*oldset
)
59 ret
= pthread_sigmask(SIG_BLOCK
, &set
, oldset
);
64 static void signal_restore(sigset_t oldset
)
68 ret
= pthread_sigmask(SIG_SETMASK
, &oldset
, NULL
);
73 int rseq_unregister_current_thread(void)
78 signal_off_save(&oldset
);
79 if (rseq_registered
) {
80 rc
= sys_rseq(NULL
, 0);
82 fprintf(stderr
, "Error: sys_rseq(...) failed(%d): %s\n",
83 errno
, strerror(errno
));
90 signal_restore(oldset
);
94 static void destroy_rseq_key(void *key
)
96 if (rseq_unregister_current_thread())
100 int rseq_register_current_thread(void)
105 signal_off_save(&oldset
);
106 if (caa_likely(!rseq_registered
)) {
107 rc
= sys_rseq(&__rseq_abi
, 0);
109 fprintf(stderr
, "Error: sys_rseq(...) failed(%d): %s\n",
110 errno
, strerror(errno
));
111 __rseq_abi
.u
.e
.cpu_id
= -2;
116 assert(rseq_current_cpu_raw() >= 0);
118 * Register destroy notifier. Pointer needs to
121 if (pthread_setspecific(rseq_key
, (void *)0x1))
125 signal_restore(oldset
);
133 ret
= pthread_key_create(&rseq_key
, destroy_rseq_key
);
136 perror("pthread_key_create");
141 void rseq_destroy(void)
145 ret
= pthread_key_delete(rseq_key
);
148 perror("pthread_key_delete");
This page took 0.055978 seconds and 5 git commands to generate.