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