source: git/MP/MP/MP_Buffer.c @ 1d0eb7

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