VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/util/bufpool.c@ 71930

Last change on this file since 71930 was 63199, checked in by vboxsync, 8 years ago

GuestHost/OpenGL: warnings (gcc).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "cr_mem.h"
8#include "cr_error.h"
9#include "cr_bufpool.h"
10#include <limits.h>
11
12/*
13 * New (version 1.4) buffer pool implementation.
14 *
15 * Now, each buffer in the pool can be a different size.
16 * We only return a buffer from crBufferPoolPop() if we have exactly
17 * the right size buffer.
18 *
19 * Note: the old implementation had a 'max buffers' parameter but it
20 * really wasn't good for anything since we always grew the buffer pool
21 * if we pushed a new buffer that would cause use to exceed the limit.
22 * That's gone now.
23 *
24 * We're just using a simple linked list here. Since we seldom have
25 * more than about 10-15 buffers in the pool, that's OK. A binary tree
26 * would be nicer though.
27 *
28 * MCH: BufferPoolPop will now return the smallest buffer in the pool that
29 * is >= to the size required. This fixes BufferPool overruns with lots
30 * of MTUs.
31 */
32
33
34#ifndef NULL
35#define NULL ((void *) 0)
36#endif
37
38
39typedef struct buffer
40{
41 void *address;
42 unsigned int size;
43 struct buffer *next;
44} Buffer;
45
46
47struct CRBufferPool_t
48{
49 unsigned int maxBuffers;
50 int numBuffers;
51 struct buffer *head;
52};
53
54
55int
56crBufferPoolGetNumBuffers( CRBufferPool *pool )
57{
58 if ( pool )
59 return pool->numBuffers;
60 return 0;
61}
62
63int
64crBufferPoolGetMaxBuffers( CRBufferPool *pool )
65{
66 if ( pool )
67 return pool->maxBuffers;
68 return 0;
69}
70
71CRBufferPool *
72crBufferPoolInit( unsigned int maxBuffers )
73{
74 CRBufferPool *pool = crCalloc(sizeof(CRBufferPool));
75 if (pool) {
76 pool->head = NULL;
77 pool->maxBuffers = maxBuffers;
78 pool->numBuffers = 0;
79 }
80 return pool;
81}
82
83void
84crBufferPoolFree( CRBufferPool *pool )
85{
86 Buffer *b, *next;
87
88 for (b = pool->head; b; b = next) {
89 next = b->next;
90 crFree(b->address);
91 crFree(b);
92 }
93}
94
95void
96crBufferPoolCallbackFree(CRBufferPool *pool, CRBufferPoolDeleteCallback pfnDelete)
97{
98 Buffer *b, *next;
99
100 CRASSERT(pfnDelete);
101
102 for (b = pool->head; b; b = next) {
103 next = b->next;
104 (*pfnDelete)(b->address);
105 crFree(b);
106 }
107}
108
109void
110crBufferPoolPush( CRBufferPool *pool, void *buf, unsigned int bytes )
111{
112 Buffer *b = crCalloc(sizeof(Buffer));
113 if (b) {
114#ifdef DEBUG
115 /* check that the buffer to push isn't already in the pool! */
116 {
117 const Buffer *bd;
118 for (bd = pool->head; bd; bd = bd->next) {
119 CRASSERT(bd->address != buf);
120 }
121 }
122#endif
123
124 b->address = buf;
125 b->size = bytes;
126 b->next = pool->head;
127 pool->head = b;
128 pool->numBuffers++;
129 }
130}
131
132void *
133crBufferPoolPop( CRBufferPool *pool, unsigned int bytes )
134{
135 Buffer *b, *prev, *prev_smallest;
136 unsigned int smallest = UINT_MAX; /* size of smallest buffer >= bytes */
137 int i;
138
139 prev = NULL;
140 prev_smallest = NULL;
141 for (b = pool->head, i=0; i<pool->numBuffers; b = b->next, i++) {
142 if (b->size == bytes) {
143 /* we found an exact size match! */
144 void *p = b->address;
145 if (prev) {
146 prev->next = b->next;
147 }
148 else {
149 pool->head = b->next;
150 }
151 crFree(b);
152 pool->numBuffers--;
153 CRASSERT(pool->numBuffers >= 0);
154 return p;
155 }
156 else if (b->size >= bytes){
157 /* We found a buffer that's large enough, but keep looking
158 * for a smaller one that's large enough.
159 */
160 if (b->size < smallest) {
161 prev_smallest = prev; /* save ptr to previous! */
162 smallest = b->size;
163 }
164 }
165 prev = b;
166 }
167
168 if (smallest < UINT_MAX) {
169 /* we found the smallest buffer whose size is > bytes */
170 void *p;
171 if (prev_smallest) {
172 b = prev_smallest->next;
173 }
174 else {
175 b = pool->head;
176 }
177 CRASSERT(b->size == smallest);
178 CRASSERT(b->size >= bytes);
179 p = b->address;
180 if (prev_smallest) {
181 prev_smallest->next = b->next;
182 }
183 else {
184 pool->head = b->next;
185 }
186 crFree(b);
187 pool->numBuffers--;
188 CRASSERT(pool->numBuffers >= 0);
189 return p;
190 }
191
192 /* found no buffer large enough */
193 return NULL;
194}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette