Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
tmpbuf.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30
31#include "podarray.h" // for __rw_aligned_buffer
32#include <rw/_allocator.h> // for __rw_allocate(), ...
33#include <rw/_mutex.h> // for _RWSTD_THREAD_XXX()
34#include <rw/_defs.h>
35
36
38
39// make sure buffer size is greater than zero
40typedef char _CharBuf [_RWSTD_TMPBUF_SIZE + !_RWSTD_TMPBUF_SIZE];
41
42// use `aligned_buffer' to guarantee proper buffer alignment
43static _RWSTD_THREAD __rw_aligned_buffer<_CharBuf>
44__rw_buffer;
45
46static _RWSTD_THREAD unsigned long
47__rw_buffer_busy /* = 0 */; // > 0 when buffer in use
48
49
50// extern "C" to avoid binary incompatibility due to changes
51// in function arguments (e.g., their sign)
52extern "C" {
53
54
55// used by std::get_temporary_buffer<>()
56_RWSTD_EXPORT _RWSTD_SIZE_T
57__rw_tmpbuf (void **pptr, _RWSTD_PTRDIFF_T nelems, _RWSTD_SIZE_T size)
58{
59 _RWSTD_ASSERT (0 != pptr);
60 _RWSTD_ASSERT (0 != size);
61
62 // detect overflow and fail
63 _RWSTD_SIZE_T nbytes = nelems * size;
64
65 if ( nelems < 0
66 || nbytes / size != _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, nelems)
67 || nelems && nbytes / nelems != size) {
68 *pptr = 0;
69 return 0;
70 }
71
72 // implicit initialization used to prevent a g++ 2.95.2 warning on Tru64
73 // sorry: semantics of inline function static data are wrong (you'll wind
74 // up with multiple copies)
75
76 void* const buffer = __rw_buffer._C_data ();
77
78 if (*pptr == buffer) {
79
80 // static buffer being returned, decrement its usage counter
81 _RWSTD_THREAD_PREDECREMENT (__rw_buffer_busy, false);
82
83 return 0;
84 }
85
86 if (*pptr) {
87 // dynamically allocated buffer being returned
88 __rw_deallocate (*pptr, 0);
89 return 0;
90 }
91
92 // allocating a new buffer
93
94 if (!nbytes) {
95 // don't waste memory for 0-size requests
96 *pptr = 0;
97 return 0;
98 }
99
100 if (nbytes <= _RWSTD_TMPBUF_SIZE) {
101
102 if (1 == _RWSTD_THREAD_PREINCREMENT (__rw_buffer_busy, false)) {
103
104 *pptr = buffer;
105
106 // static buffer used, its usage counter stays non-zero
107 return _RWSTD_TMPBUF_SIZE / size;
108 }
109
110 // static buffer not used, decrement its usage counter
111 _RWSTD_THREAD_PREDECREMENT (__rw_buffer_busy, false);
112 }
113
114 _TRY {
115 *pptr = __rw_allocate (nbytes, 0);
116 }
117 _CATCH (...) {
118 *pptr = 0;
119 nbytes = 0;
120 }
121
122 return nbytes / size;
123}
124
125} // extern "C"
126
127
128} // namespace __rw
#define buffer
Definition 17.names.cpp:453
#define _RWSTD_THREAD
Definition TLS.cpp:30
#define _RWSTD_THREAD_PREDECREMENT(x, mutex)
Definition _defs.h:728
#define _RWSTD_THREAD_PREINCREMENT(x, mutex)
Definition _defs.h:723
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _TRY
Definition _defs.h:850
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _CATCH(ex)
Definition _defs.h:851
#define _RWSTD_TMPBUF_SIZE
Definition _defs.h:1309