1 /* $Id: completion.h,v 1.1 2009/02/28 16:48:11 fredette Exp $ */ 2 3 /* tme/completion.h - header file for completions: */ 4 5 /* 6 * Copyright (c) 2008 Matt Fredette 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Matt Fredette. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef _TME_COMPLETION_H 37 #define _TME_COMPLETION_H 38 39 #include <tme/common.h> 40 _TME_RCSID("$Id: completion.h,v 1.1 2009/02/28 16:48:11 fredette Exp $"); 41 42 /* includes: */ 43 #include <tme/memory.h> 44 45 /* macros: */ 46 47 /* this initializes a completion: */ 48 #define tme_completion_init(completion) \ 49 do { \ 50 tme_memory_atomic_init_flag(&(completion)->tme_completion_valid, FALSE);\ 51 } while (/* CONSTCOND */ 0) 52 53 /* this returns nonzero if the completion is valid: */ 54 /* NB: this does not make any barrier ordering its read of the valid 55 flag with any reads of completion state protected by the flag. it 56 is up to callers to make these barriers: */ 57 #define tme_completion_is_valid(completion) \ 58 (__tme_predict_true(tme_memory_atomic_read_flag(&(completion)->tme_completion_valid))) 59 60 /* this validates a completion: */ 61 /* NB: this does not necessarily make any barrier ordering its write 62 of the valid flag with any writes of completion state protected by 63 the flag. it is up to the callers to guarantee that a barrier is 64 made before validating a completion. 65 66 a caller may be able to piggyback on the barrier made by one of its 67 own tme_mutex_unlock(). tme_mutex_unlock() must make a barrier 68 from the compiler's perspective (the compiler must not schedule 69 instructions across it) and a barrier from the processor's 70 perspective (the processor must not reorder earlier reads or writes 71 across it). 72 73 for example, an element with a central mutex could delay using 74 tme_completion_validate() until after an unlock of that mutex: */ 75 #define tme_completion_validate(completion) \ 76 do { \ 77 tme_memory_atomic_write_flag(&(completion)->tme_completion_valid, TRUE);\ 78 } while (/* CONSTCOND */ 0) 79 80 /* this invalidates a completion: */ 81 #define tme_completion_invalidate(completion) \ 82 do { \ 83 tme_memory_atomic_write_flag(&(completion)->tme_completion_valid, FALSE);\ 84 } while (/* CONSTCOND */ 0) 85 86 /* types: */ 87 88 /* a completion: */ 89 struct tme_completion { 90 91 /* if this is nonzero, the completion is valid: */ 92 tme_memory_atomic_flag_t tme_completion_valid; 93 94 /* an error code: */ 95 int tme_completion_error; 96 97 /* various scalar completion values: */ 98 union { 99 tme_int8_t _tme_completion_scalar_u_int8; 100 #define tme_completion_scalar_int8 tme_completion_scalar._tme_completion_scalar_u_int8 101 tme_uint8_t _tme_completion_scalar_u_uint8; 102 #define tme_completion_scalar_uint8 tme_completion_scalar._tme_completion_scalar_u_uint8 103 tme_int16_t _tme_completion_scalar_u_int16; 104 #define tme_completion_scalar_int16 tme_completion_scalar._tme_completion_scalar_u_int16 105 tme_uint16_t _tme_completion_scalar_u_uint16; 106 #define tme_completion_scalar_uint16 tme_completion_scalar._tme_completion_scalar_u_uint16 107 tme_int32_t _tme_completion_scalar_u_int32; 108 #define tme_completion_scalar_int32 tme_completion_scalar._tme_completion_scalar_u_int32 109 tme_uint32_t _tme_completion_scalar_u_uint32; 110 #define tme_completion_scalar_uint32 tme_completion_scalar._tme_completion_scalar_u_uint32 111 #ifdef TME_HAVE_INT64_T 112 tme_int64_t _tme_completion_scalar_u_int64; 113 #define tme_completion_scalar_int64 tme_completion_scalar._tme_completion_scalar_u_int64 114 tme_uint64_t _tme_completion_scalar_u_uint64; 115 #define tme_completion_scalar_uint64 tme_completion_scalar._tme_completion_scalar_u_uint64 116 #endif /* TME_HAVE_INT64_T */ 117 } tme_completion_scalar; 118 }; 119 120 #endif /* !_TME_COMPLETION_H */ 121