OSDN Git Service

* parse.y (check_static_final_variable_assignment_flag): Fix spelling.
[pf3gnuchains/gcc-fork.git] / libchill / sendbuffer.c
1 /* Implement tasking-related runtime actions for CHILL.
2    Copyright (C) 1992,1993 Free Software Foundation, Inc.
3    Author: Wilfried Moser
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 #include <string.h>
30 #include "rtltypes.h"
31 #include "rts.h"
32
33 EXCEPTION (sendfail);
34
35 extern void __cause_ex1 (char *ex, char *file, int lineno);
36
37 #define CAUSE_SENDFAIL  __cause_ex1 ("sendfail", filename, lineno)
38
39 /*
40  * function __send_buffer
41  *
42  * parameters:
43  *     buffer     pointer to buffer descriptor
44  *     data       pointer to data descriptor
45  *     prio       priority for send action
46  *     timeout    pointer to timeout value
47  *     filename   source file name where function gets called
48  *     lineno     linenumber in source file
49  *
50  * returns:
51  *     int        0 .. success
52  *                1 .. timeout
53  *
54  * exceptions:
55  *     sendfail
56  *
57  * abstract:
58  *     implement the CHILL SEND buffer action.
59  */
60
61 int
62 __send_buffer (buffer, data, prio, timeout, filename, lineno)
63      Buffer_Descr    *buffer;
64      Data_Descr      *data;
65      int              prio;
66      void            *timeout;
67      char            *filename;
68      int              lineno;
69 {
70   Buffer_Queue        *bq;
71   Buffer_Send_Queue   *bsq, *bsq_entry, *prev_bsq_entry;
72   int                  cnt = 0;
73   int                  retval = 0;
74   
75   /* if we don't have anything queued on that buffer,
76      set up the structure */
77   memcpy (&bq, buffer->buf, sizeof (Buffer_Queue *));
78   if (bq == 0)
79     {
80       MALLOC (bq, sizeof (Buffer_Queue));
81       memset (bq, 0, sizeof (Buffer_Queue));
82       memcpy (buffer->buf, &bq, sizeof (Buffer_Queue *));
83     }
84
85   /* look if there is a process delayed on that buffer */
86   if (bq->waitqueue != 0)
87     {
88         Buffer_Wait_Queue       *listentry;
89         
90         /* there is already a processes waiting for that buffer,
91            check datalength and copy the data in */
92         if (bq->waitqueue->datalen < data->length)
93             CAUSE_SENDFAIL;
94         memcpy (bq->waitqueue->dataptr, data->ptr, data->length);
95         
96         /* set up the entry */
97         bq->waitqueue->is_sent = 1;
98         bq->waitqueue->who_sent = THIS;
99
100         /* continue waiting process */
101         __continue_that (bq->waitqueue->this, prio, filename, lineno);
102         
103         /* now dequeue all entries of this list */
104         listentry = bq->waitqueue->startlist;
105         while (listentry != 0)
106         {
107             Buffer_Wait_Queue   *tmp, *prev_entry, *bwq;
108             Buffer_Queue        *bq;
109
110             tmp = listentry->chain;
111             memcpy (&bq, listentry->bufferaddr, sizeof (Buffer_Queue *));
112             prev_entry = (Buffer_Wait_Queue *)&bq->waitqueue;
113             bwq = bq->waitqueue;
114
115             while (bwq != listentry)
116             {
117                 prev_entry = bwq;
118                 bwq = bwq->forward;
119             }
120             /* dequeue it */
121             prev_entry->forward = bwq->forward;
122             bq->waitqueuelength--;
123             listentry = tmp;
124         }
125         
126         /* all done */
127         return 0;
128     }
129
130   /* nothing in waitqueue, set up an entry for sendqueue.
131      Note: we allocate here space for the data too, to reduce
132      calls to malloc and let the dataptr point just behind
133      the Buffer_Send_Queue structure. */
134   MALLOC (bsq_entry, sizeof (Buffer_Send_Queue) + data->length);
135   memset (bsq_entry, 0, sizeof (Buffer_Send_Queue));
136
137   bsq_entry->priority = prio;
138   bsq_entry->this = THIS;
139   bsq_entry->datalen = data->length;
140   bsq_entry->dataptr = bsq_entry + 1;
141   memcpy (bsq_entry->dataptr, data->ptr, data->length);
142
143   /* add entry to sendqueue */
144   prev_bsq_entry = (Buffer_Send_Queue *)&bq->sendqueue;
145   bsq = bq->sendqueue;
146
147   while (bsq != 0 && bsq->priority >= prio)
148     {
149       prev_bsq_entry = bsq;
150       bsq = bsq->forward;
151     }
152   if (bsq == 0)
153     {
154       /* beginning or end of the list */
155       prev_bsq_entry->forward = bsq_entry;
156     }
157   else
158     {
159       /* somewhere in the middle */
160       bsq_entry->forward = prev_bsq_entry->forward;
161       prev_bsq_entry->forward = bsq_entry;
162     }
163
164   if (buffer->maxqueuelength != (unsigned long)-1L &&
165       bq->sendqueuelength >= buffer->maxqueuelength)
166     {
167       /* we have to delay this process */
168       bsq_entry->is_delayed = 1;
169       retval = __delay_this (wait_buffer_send, timeout, filename, lineno);
170       if (retval)
171         {
172           prev_bsq_entry->forward = bsq_entry->forward;
173           FREE (bsq_entry);
174         }
175     }
176   else
177     /* just say that there is one more entry in the queue */
178     bq->sendqueuelength++;
179   return retval;
180 }
181
182 /* force function __print_buffer to be linked */
183 extern void __print_buffer ();
184 static EntryPoint pev = __print_buffer;