source: git/MP/MP/MP_Buffer.c @ 22b156

fieker-DuValspielwiese
Last change on this file since 22b156 was 341696, checked in by Hans Schönemann <hannes@…>, 15 years ago
Adding Id property to all files git-svn-id: file:///usr/local/Singular/svn/trunk@12231 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.7 KB
Line 
1/*******************************************************************
2 *
3 *                                                                 
4 *                    MP version 1.1.2:  Multi Protocol
5 *                    Kent State University, Kent, OH
6 *                 Authors:  S. Gray, N. Kajler, P. Wang
7 *          (C) 1993, 1994, 1995, 1996, 1997 All Rights Reserved
8 *
9 *                                 NOTICE
10 *
11 *  Permission to use, copy, modify, and distribute this software and
12 *  its documentation for non-commercial purposes and without fee is
13 *  hereby granted provided that the above copyright notice appear in all
14 *  copies and that both the copyright notice and this permission notice
15 *  appear in supporting documentation.
16 *
17 *  Neither Kent State University nor the Authors make any representations
18 *  about the suitability of this software for any purpose.  The MP Library
19 *  is distributed in the hope that it will be useful, but is provided  "as
20 *  is" and without any warranty of any kind and without even the implied
21 *  warranty of merchantability or fitness for a particular purpose.
22 *
23 *    IMPORTANT ADDITION: as of September 2006, MP is also licenced under GPL
24 *
25 ***************************************************************/
26
27#ifndef lint
28static char vcid[] = "@(#) $Id$";
29#endif /* lint */
30
31#include "MP.h"
32
33/*
34 * create_buffer() is used to create buffer handle and allocate memory to
35 * buffer. create_buffer() gaurantees that in the handle
36 *    1. the_buffer points to the begining of the memory block allocated to the
37 *        buffer.
38 *    2. buff points to the byte-aligned starting point at the begning of the
39 *       buffer.
40 *    3. next is NULL
41 * and the first long integer starting from buff is zeroed.
42 * create_buffer() returns NULL if failure.
43 */
44
45#ifdef __STDC__
46buffer_handle_pt create_buffer(buffer_pool_pt buff_pool)
47#else
48buffer_handle_pt create_buffer(buff_pool)
49    buffer_pool_pt buff_pool
50#endif
51{
52    buffer_handle_pt buff;
53
54#ifdef MP_DEBUG
55    fprintf(stderr, "create_buffer: entering\n");
56#endif
57
58    buff = (buffer_handle_pt)IMP_MemAllocFnc(sizeof(buffer_handle_t));
59    if (buff == NULL)
60        return NULL;
61
62    buff->buff
63        = buff->the_buffer
64        = (char *)IMP_MemAllocFnc(buff_pool->buff_size + MP_BytesPerMPUnit*2);
65
66    if (buff->the_buffer == NULL) {
67        IMP_MemFreeFnc(buff, sizeof(buffer_handle_t));
68        return NULL;
69    }
70
71    while ((unsigned int)buff->buff % MP_BytesPerMPUnit != 0)
72        buff->buff++;
73
74    *(long*)buff->buff = 0;
75    buff->next = NULL;
76
77#ifdef MP_DEBUG
78    fprintf(stderr, "create_buffer: exiting\n");
79#endif
80
81    return buff;
82}
83
84/*******************************************************************************
85 *
86 * destroy_buffer() frees the buffer and and its handle, buff.
87 *
88 ******************************************************************************/
89#ifdef __STDC__
90void destroy_buffer(buffer_handle_pt buff,
91                    long             buffsize)
92#else
93void destroy_buffer(buff, buffsize)
94    buffer_handle_pt buff;
95    long             buffsize;
96#endif
97{
98    if (buff == NULL)
99        return;
100
101    if (buff->the_buffer == NULL) {
102        IMP_MemFreeFnc(buff, sizeof(buffer_handle_t));
103        return;
104    }
105
106    IMP_MemFreeFnc(buff->the_buffer, buffsize + MP_BytesPerMPUnit*2);
107    IMP_MemFreeFnc(buff, sizeof(buffer_handle_t));
108
109    return;
110}
111
112
113/*******************************************************************************
114 *
115 * get_buffer() returns a free buffer's handle to the caller.
116 * get_buffer() gaurantees that the first byte-aligned long integer
117 * is zeroed and the next field in the handle is NULL.
118 * get_buffer() returns NULL if fail.
119 *
120 ******************************************************************************/
121#ifdef __STDC__
122buffer_handle_pt get_buffer(buffer_pool_pt buff_pool)
123#else
124buffer_handle_pt get_buffer(buff_pool)
125    buffer_pool_pt buff_pool;
126#endif
127{
128    buffer_handle_pt buff_hand;
129#ifdef MP_DEBUG
130    fprintf(stderr, "get_buffer: entering\n");
131#endif
132
133    if (buff_pool->buff != NULL && buff_pool->curr_free_buff != 0) {
134        buff_pool->curr_free_buff--;
135        buff_hand = buff_pool->buff;
136        buff_pool->buff = buff_hand->next;
137        buff_hand->next = NULL;
138        *(long*)buff_hand->buff = 0;
139        return buff_hand;
140    }
141
142    return create_buffer(buff_pool);
143}
144
145
146/*******************************************************************************
147 *
148 * free_buffer() reclaims the buffer, buff, returned by streams.
149 * if the number of free buffers already reached maximum,
150 * the returned buffer will be destroyed.
151 *
152 ******************************************************************************/
153#ifdef __STDC__
154void free_buffer(buffer_pool_pt   buff_pool,
155                 buffer_handle_pt buff)
156#else
157void free_buffer(buff_pool, buff)
158    buffer_pool_pt   buff_pool;
159    buffer_handle_pt buff;
160#endif
161{
162    if (buff == NULL)
163        return;
164
165    if (buff->the_buffer == NULL) {
166        IMP_MemFreeFnc(buff, sizeof(buffer_handle_t));
167        return;
168    }
169
170    if (buff_pool->curr_free_buff >= buff_pool->max_free_buff)
171        destroy_buffer(buff, buff_pool->buff_size);
172    else {
173        buff->next      = buff_pool->buff;
174        buff_pool->buff = buff;
175        buff_pool->curr_free_buff++;
176    }
177}
178
179
180/*******************************************************************************
181 *
182 * m_create_pool() creates and initializes a buffer pool global to
183 * a process. Returns either MP_Success or MP_Failure.
184 * arguments:
185 *     buffer_size: integer, size of each buffer./
186 *     max_free_buffer: maximum number of free buffers to be kept in
187 *                      pool at any time.
188 *     init_free_buffer: initial number of buffers to be made available
189 *                       upon the pool's creation.
190 *
191 ******************************************************************************/
192#ifdef __STDC__
193MP_Status_t m_create_pool(MP_Env_pt env,
194                          int       buffer_size,
195                          int       max_free_buffer,
196                          int       init_free_buffer)
197#else
198MP_Status_t m_create_pool(env, buffer_size, max_free_buffer, init_free_buffer)
199    MP_Env_pt env;
200    int       buffer_size;
201    int       max_free_buffer;
202    int       init_free_buffer;
203#endif
204{
205    buffer_handle_pt buff_hand, old_buff_hand;
206    int              buff_count;
207
208    /* create the pool structure */
209    env->buff_pool = (buffer_pool_pt)IMP_MemAllocFnc(sizeof(buffer_pool_t));
210    if (env->buff_pool == NULL)
211        return MP_Failure;
212
213    /* check parameter, use default values if necessary */
214    for ( ; buffer_size % MP_BytesPerMPUnit != 0; buffer_size++);
215
216    if (buffer_size < MP_MINIMUM_BUFF_SIZE)
217        env->buff_pool->buff_size = MP_DEFAULT_BUFF_SIZE;
218    else
219        env->buff_pool->buff_size = buffer_size;
220
221    if (max_free_buffer <= 0)
222        env->buff_pool->max_free_buff
223            = max_free_buffer
224            = MP_DEFAULT_MAX_FREE_BUFF;
225    else
226        env->buff_pool->max_free_buff = max_free_buffer;
227
228    if (init_free_buffer <= 0)
229        init_free_buffer = MP_DEFAULT_INIT_FREE_BUFF;
230
231    if (init_free_buffer > max_free_buffer)
232        init_free_buffer = max_free_buffer;
233
234    env->buff_pool->curr_free_buff = 0;
235
236    /* allocate buffers and make a list out of them */
237    env->buff_pool->buff = create_buffer(env->buff_pool);
238    if (env->buff_pool->buff == NULL)
239        return MP_Failure;
240
241    old_buff_hand = env->buff_pool->buff;
242
243    for (buff_count = 1; buff_count < init_free_buffer; buff_count++) {
244        buff_hand = create_buffer(env->buff_pool);
245        if (buff_hand == NULL) {
246            env->buff_pool->curr_free_buff = buff_count;
247            return MP_Failure;
248        }
249        old_buff_hand->next = buff_hand;
250        old_buff_hand = buff_hand;
251    }
252
253    env->buff_pool->curr_free_buff = buff_count;
254
255    return MP_Success;
256}
257
258
259/*******************************************************************************
260 *
261 * m_free_pool() frees all buffers and their handles.
262 *
263 ******************************************************************************/
264#ifdef __STDC__
265void m_free_pool(buffer_pool_pt buff_pool)
266#else
267void m_free_pool(buff_pool)
268    buffer_pool_pt buff_pool;
269#endif
270{
271    buffer_handle_pt buff;
272
273    if (buff_pool == NULL)
274        return;
275
276    for (buff = buff_pool->buff; buff != NULL; buff = buff_pool->buff) {
277        buff_pool->buff = buff->next;
278        destroy_buffer(buff, buff_pool->buff_size);
279    }
280
281    buff_pool->curr_free_buff = 0;
282    IMP_MemFreeFnc(buff_pool, sizeof(buffer_pool_t));
283
284    return;
285}
286
287
288/*******************************************************************************
289 *
290 * get_o_buff() provides the caller with an output buffer and sets up
291 * the pointers in the streams associated with that buffer properly.
292 * get_o_buff() first looks for output buffers alerady assigned to the stream,
293 * if there is none, it requests for one from the pool.
294 * if get_o_buff() fails to get a buffer, it returns NULL.
295 * argument:
296 *     link: the stream that needs to get an output buffer.
297 *
298 ******************************************************************************/
299#ifdef __STDC__
300buffer_handle_pt get_o_buff(MP_Link_pt link)
301#else
302buffer_handle_pt get_o_buff(link)
303    MP_Link_pt link;
304#endif
305{
306    buffer_handle_pt buff;
307    buffer_pool_pt   buff_pool;
308
309#ifdef MP_DEBUG
310    fprintf(stderr, "get_o_buff: entering\n");
311#endif
312
313    if (link == NULL)
314        return NULL;
315
316    buff_pool = link->env->buff_pool;
317    /* test if initial call from m_create_link */
318    if (link->curr_o_buff == NULL && link->o_buff == NULL) {
319        buff = get_buffer(buff_pool);
320        if (buff == NULL)
321            return NULL;
322    }
323    /* test if already at end of chain */
324    else
325        if (link->curr_o_buff->next == NULL) {
326            buff = get_buffer(buff_pool);
327            if (buff == NULL)
328                return NULL;
329            link->curr_o_buff->next = buff;
330        } else
331            /* last possibility: still have allocated free buffers in chain */
332            buff = link->curr_o_buff->next;
333
334    link->out_finger     = link->out_base = buff->buff;
335    link->out_finger    += sizeof(long);
336    link->o_frag_header  = (unsigned long *)buff->buff;
337    link->out_boundry    = link->out_finger + buff_pool->buff_size;
338
339    *link->o_frag_header = 0;
340
341#ifdef MP_DEBUG
342    fprintf(stderr, "get_o_buff: exiting\n");
343#endif
344
345    return buff;
346}
347
348
349/*******************************************************************************
350 *
351 * get_i_buff() provides the caller with an input buffer and sets up
352 * the pointers in the streams associated with that buffer properly.
353 * get_i_buff() first look for inpuy buffers alerady assigned to the stream,
354 * if there is none, it requests for one from the pool.
355 * if get_i_buff() fails to get a buffer, it returns NULL.
356 * argument:
357 *     link: the stream that needs to get an input buffer.
358 *
359 ******************************************************************************/
360#ifdef __STDC__
361buffer_handle_pt get_i_buff(MP_Link_pt link)
362#else
363buffer_handle_pt get_i_buff(link)
364    MP_Link_pt link;
365#endif
366{
367    buffer_handle_pt buff;
368    buffer_pool_pt   buff_pool;
369
370
371    if (link == NULL)
372        return NULL;
373
374    buff_pool = link->env->buff_pool;
375
376    /* test if initial call from m_create_link */
377    if (link->curr_i_buff == NULL && link->i_buff == NULL) {
378        buff = get_buffer(buff_pool);
379        if (buff == NULL)
380            return NULL;
381    } else
382        /* test if at the end of allocated chain */
383        if (link->curr_i_buff->next == NULL) {
384            buff = get_buffer(buff_pool);
385            if (buff == NULL)
386                return NULL;
387            link->curr_i_buff->next = buff;
388        } else
389            /* last possibility: still have allocated free buffers in chain */
390            buff = link->curr_i_buff->next;
391
392    link->in_finger      = link->in_base = buff->buff;
393    link->in_finger     += sizeof(long);
394    link->i_frag_header  = (unsigned long *)buff->buff;
395    link->in_boundry     = link->in_finger + buff_pool->buff_size;
396
397    *link->i_frag_header = 0;
398
399    return buff;
400}
401
402
403
404/*******************************************************************************
405 *
406 * m_free_in_bufs() frees all but the first input buffers of a stream.
407 * It then resets the in_???  pointers in the stream according to the first
408 * buffer.
409 * argument:
410 *      link: the stream whose input buffers need to be freed.
411 *
412 ******************************************************************************/
413#ifdef __STDC__
414void m_free_in_bufs(MP_Link_pt link)
415#else
416void m_free_in_bufs(link)
417    MP_Link_pt link;
418#endif
419{
420    buffer_handle_pt cur_buff, old_buff;
421    buffer_pool_pt   buff_pool;
422    int              counter;
423
424
425    if (link == NULL || link->i_buff == NULL)
426        return;
427
428    buff_pool = link->env->buff_pool;
429    cur_buff  = link->i_buff->next;
430
431    for (counter = 0; cur_buff != NULL; counter++) {
432        old_buff = cur_buff;
433        cur_buff = old_buff->next;
434        free_buffer(link->env->buff_pool, old_buff);
435    }
436
437    link->i_buff->next   = NULL;
438    link->curr_i_buff    = link->i_buff;
439    link->in_base        = link->i_buff->buff;
440    link->i_frag_header  = (unsigned long *)link->in_base;
441    link->in_boundry     = link->in_finger = link->in_base + sizeof(long);
442    link->in_boundry    += buff_pool->buff_size;
443
444    *link->i_frag_header = 0;
445}
446
447
448/*******************************************************************************
449 *
450 * MP_ResetLink() frees all but the first num_o_buff input buffers of a stream.
451 * It then resets the out_??? pointers in the stream according to the first
452 * buffer.
453 * argument:
454 *      link: the stream whose output buffers need to be freed.
455 *
456 ******************************************************************************/
457#ifdef __STDC__
458int MP_ResetLink(MP_Link_pt link)
459#else
460int MP_ResetLink(link)
461    MP_Link_pt link;
462#endif
463{
464    buffer_handle_pt cur_buff, old_buff, old_old_buff;
465    buffer_pool_pt   buff_pool;
466    int              counter;
467
468
469    if (link == NULL || link->o_buff == NULL)
470        return 0;
471
472    buff_pool    = link->env->buff_pool;
473    old_old_buff = link->o_buff;
474    cur_buff     = link->o_buff->next;
475
476    for (counter = 1; counter < link->num_o_buff && cur_buff != NULL;
477         counter++) {
478        old_old_buff = cur_buff;
479        cur_buff     = cur_buff->next;
480    }
481
482    while (cur_buff != NULL) {
483        old_buff = cur_buff;
484        cur_buff = old_buff->next;
485        free_buffer(link->env->buff_pool, old_buff);
486    }
487
488    old_old_buff->next   = NULL;
489
490    link->curr_o_buff    = link->o_buff;
491    link->out_base       = link->o_buff->buff;
492    link->o_frag_header  = (unsigned long *)link->out_base;
493    link->out_boundry    = link->out_finger = link->out_base + sizeof(long);
494    link->out_boundry   += buff_pool->buff_size;
495
496    *link->o_frag_header = 0;
497
498#ifndef NO_LOGGING
499    if (link->logmask & MP_LOG_INIT_EVENTS)
500        MP_LogEvent(link, MP_INIT_EVENT,
501                    "MP_ResetLink: reset link sending buffers");
502#endif
503    return MP_ClearError(link);
504}
505
506
507
508/*******************************************************************************
509 *
510 * reset_i_buff() resets all pointers associated with the input stream
511 * according to the first buffer of the stream. All buffers remain
512 * intact and unaffected by reset_i_buff.
513 *
514 ******************************************************************************/
515#ifdef __STDC__
516MP_Status_t reset_i_buff(MP_Link_pt link)
517#else
518MP_Status_t reset_i_buff(link)
519    MP_Link_pt link;
520#endif
521{
522    if (link == NULL)
523        return MP_Failure;
524
525    link->curr_i_buff   = link->i_buff;
526    link->in_finger     = link->in_base = link->curr_i_buff->buff;
527    link->i_frag_header = (unsigned long *)(link->in_base);
528    link->in_boundry    = (char *)((unsigned long)(link->in_finger) + sizeof(long)
529                          + (*(link->i_frag_header) & ~eor_mask));
530
531    return MP_Success;
532}
533
534
Note: See TracBrowser for help on using the repository browser.