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