1 /* $OpenBSD: cancel.h,v 1.5 2017/09/05 02:40:54 guenther Exp $ */ 2 /* 3 * Copyright (c) 2015 Philip Guenther <guenther@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifndef _CANCEL_H_ 19 #define _CANCEL_H_ 20 21 #include <tib.h> 22 #include "thread_private.h" 23 24 /* process a cancel request at a cancel point */ 25 __dead void _thread_canceled(void); 26 27 #ifdef __LIBC__ 28 PROTO_NORMAL(_thread_canceled); 29 #endif 30 31 #if defined(__LIBC__) && !defined(TCB_HAVE_MD_GET) 32 /* 33 * Override TIB_GET macro to use the caching callback 34 */ 35 #undef TIB_GET 36 #define TIB_GET() TCB_TO_TIB(_thread_cb.tc_tcb()) 37 #endif 38 39 #define PREP_CANCEL_POINT(tib) \ 40 int _cantcancel = (tib)->tib_cantcancel 41 42 #define ENTER_CANCEL_POINT_INNER(tib, can_cancel, delay) \ 43 if (_cantcancel == 0) { \ 44 (tib)->tib_cancel_point = (delay) ? \ 45 CANCEL_POINT_DELAYED : CANCEL_POINT; \ 46 if (can_cancel) { \ 47 __asm volatile("":::"memory"); \ 48 if (__predict_false((tib)->tib_canceled)) \ 49 _thread_canceled(); \ 50 } \ 51 } 52 53 #define LEAVE_CANCEL_POINT_INNER(tib, can_cancel) \ 54 if (_cantcancel == 0) { \ 55 (tib)->tib_cancel_point = 0; \ 56 if (can_cancel) { \ 57 __asm volatile("":::"memory"); \ 58 if (__predict_false((tib)->tib_canceled)) \ 59 _thread_canceled(); \ 60 } \ 61 } 62 63 /* 64 * Enter or leave a cancelation point, optionally processing pending 65 * cancelation requests. Note that ENTER_CANCEL_POINT opens a block 66 * and LEAVE_CANCEL_POINT must close that same block. 67 */ 68 #define ENTER_CANCEL_POINT(can_cancel) \ 69 { \ 70 struct tib *_tib = TIB_GET(); \ 71 PREP_CANCEL_POINT(_tib); \ 72 ENTER_CANCEL_POINT_INNER(_tib, can_cancel, 0) 73 74 #define LEAVE_CANCEL_POINT(can_cancel) \ 75 LEAVE_CANCEL_POINT_INNER(_tib, can_cancel); \ 76 } 77 78 #endif /* _CANCEL_H_ */ 79