1*94c3dad2SToomas Soome /* 2*94c3dad2SToomas Soome * This file and its contents are supplied under the terms of the 3*94c3dad2SToomas Soome * Common Development and Distribution License ("CDDL"), version 1.0. 4*94c3dad2SToomas Soome * You may only use this file in accordance with the terms of version 5*94c3dad2SToomas Soome * 1.0 of the CDDL. 6*94c3dad2SToomas Soome * 7*94c3dad2SToomas Soome * A full copy of the text of the CDDL should have accompanied this 8*94c3dad2SToomas Soome * source. A copy of the CDDL is also available via the Internet at 9*94c3dad2SToomas Soome * http://www.illumos.org/license/CDDL. 10*94c3dad2SToomas Soome */ 11*94c3dad2SToomas Soome 12*94c3dad2SToomas Soome /* 13*94c3dad2SToomas Soome * Copyright 2017 Toomas Soome <tsoome@me.com> 14*94c3dad2SToomas Soome */ 15*94c3dad2SToomas Soome 16*94c3dad2SToomas Soome #ifndef _SYS_CONTAINEROF_H 17*94c3dad2SToomas Soome #define _SYS_CONTAINEROF_H 18*94c3dad2SToomas Soome 19*94c3dad2SToomas Soome /* 20*94c3dad2SToomas Soome * __containerof macro for private use in illumos. 21*94c3dad2SToomas Soome * 22*94c3dad2SToomas Soome * __containerof(ptr, type, member) will return pointer to the data 23*94c3dad2SToomas Soome * structure of given type, calculated based on the offset of 'member' 24*94c3dad2SToomas Soome * in the structure 'type'. 25*94c3dad2SToomas Soome * 26*94c3dad2SToomas Soome * For this macro to work, we should be certain of the pointer type. 27*94c3dad2SToomas Soome */ 28*94c3dad2SToomas Soome 29*94c3dad2SToomas Soome #include <sys/stddef.h> 30*94c3dad2SToomas Soome 31*94c3dad2SToomas Soome #ifdef __cplusplus 32*94c3dad2SToomas Soome extern "C" { 33*94c3dad2SToomas Soome #endif 34*94c3dad2SToomas Soome 35*94c3dad2SToomas Soome #if !defined(__containerof) 36*94c3dad2SToomas Soome 37*94c3dad2SToomas Soome /* 38*94c3dad2SToomas Soome * The extension to support statements and declarations in expressions, 39*94c3dad2SToomas Soome * https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html, is available 40*94c3dad2SToomas Soome * in gcc >= 3.1. 41*94c3dad2SToomas Soome * We perform the assignment below to try and provide additional type safety. 42*94c3dad2SToomas Soome */ 43*94c3dad2SToomas Soome #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) 44*94c3dad2SToomas Soome #define __containerof(m, s, name) ( \ 45*94c3dad2SToomas Soome { \ 46*94c3dad2SToomas Soome const volatile __typeof(((s *)0)->name) *__m = (m); \ 47*94c3dad2SToomas Soome (void *)((uintptr_t)__m - (uintptr_t)offsetof(s, name)); \ 48*94c3dad2SToomas Soome }) 49*94c3dad2SToomas Soome #else 50*94c3dad2SToomas Soome #define __containerof(m, s, name) \ 51*94c3dad2SToomas Soome (void *)((uintptr_t)(m) - (uintptr_t)offsetof(s, name)) 52*94c3dad2SToomas Soome #endif 53*94c3dad2SToomas Soome #endif 54*94c3dad2SToomas Soome 55*94c3dad2SToomas Soome #ifdef __cplusplus 56*94c3dad2SToomas Soome } 57*94c3dad2SToomas Soome #endif 58*94c3dad2SToomas Soome 59*94c3dad2SToomas Soome #endif /* _SYS_CONTAINEROF_H */ 60