OSDN Git Service

* Make-lang.in (JAVA_SRCS): Added check-init.c.
[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 "rtltypes.h"
30 #include "rts.h"
31
32 EXCEPTION (sendfail);
33
34 extern void __cause_ex1 (char *ex, char *file, int lineno);
35
36 #define CAUSE_SENDFAIL  __cause_ex1 ("sendfail", filename, lineno)
37
38 /*
39  * function __send_buffer
40  *
41  * parameters:
42  *     buffer     pointer to buffer descriptor
43  *     data       pointer to data descriptor
44  *     prio       priority for send action
45  *     timeout    pointer to timeout value
46  *     filename   source file name where function gets called
47  *     lineno     linenumber in source file
48  *
49  * returns:
50  *     int        0 .. success
51  *                1 .. timeout
52  *
53  * exceptions:
54  *     sendfail
55  *
56  * abstract:
57  *     implement the CHILL SEND buffer action.
58  */
59
60 int
61 __send_buffer (buffer, data, prio, timeout, filename, lineno)
62      Buffer_Descr    *buffer;
63      Data_Descr      *data;
64      int              prio;
65      void            *timeout;
66      char            *filename;
67      int              lineno;
68 {
69   Buffer_Queue        *bq;
70   Buffer_Send_Queue   *bsq, *bsq_entry, *prev_bsq_entry;
71   int                  cnt = 0;
72   int                  retval = 0;
73   
74   /* if we don't have anything queued on that buffer,
75      set up the structure */
76   memcpy (&bq, buffer->buf, sizeof (Buffer_Queue *));
77   if (bq == 0)
78     {
79       MALLOC (bq, sizeof (Buffer_Queue));
80       memset (bq, 0, sizeof (Buffer_Queue));
81       memcpy (buffer->buf, &bq, sizeof (Buffer_Queue *));
82     }
83
84   /* look if there is a process delayed on that buffer */
85   if (bq->waitqueue != 0)
86     {
87         Buffer_Wait_Queue       *listentry;
88         
89         /* there is already a processes waiting for that buffer,
90            check datalength and copy the data in */
91         if (bq->waitqueue->datalen < data->length)
92             CAUSE_SENDFAIL;
93         memcpy (bq->waitqueue->dataptr, data->ptr, data->length);
94         
95         /* set up the entry */
96         bq->waitqueue->is_sent = 1;
97         bq->waitqueue->who_sent = THIS;
98
99         /* continue waiting process */
100         __continue_that (bq->waitqueue->this, prio, filename, lineno);
101         
102         /* now dequeue all entries of this list */
103         listentry = bq->waitqueue->startlist;
104         while (listentry != 0)
105         {
106             Buffer_Wait_Queue   *tmp, *prev_entry, *bwq;
107             Buffer_Queue        *bq;
108
109             tmp = listentry->chain;
110             memcpy (&bq, listentry->bufferaddr, sizeof (Buffer_Queue *));
111             prev_entry = (Buffer_Wait_Queue *)&bq->waitqueue;
112             bwq = bq->waitqueue;
113
114             while (bwq != listentry)
115             {
116                 prev_entry = bwq;
117                 bwq = bwq->forward;
118             }
119             /* dequeue it */
120             prev_entry->forward = bwq->forward;
121             bq->waitqueuelength--;
122             listentry = tmp;
123         }
124         
125         /* all done */
126         return 0;
127     }
128
129   /* nothing in waitqueue, set up an entry for sendqueue.
130      Note: we allocate here space for the data too, to reduce
131      calls to malloc and let the dataptr point just behind
132      the Buffer_Send_Queue structure. */
133   MALLOC (bsq_entry, sizeof (Buffer_Send_Queue) + data->length);
134   memset (bsq_entry, 0, sizeof (Buffer_Send_Queue));
135
136   bsq_entry->priority = prio;
137   bsq_entry->this = THIS;
138   bsq_entry->datalen = data->length;
139   bsq_entry->dataptr = bsq_entry + 1;
140   memcpy (bsq_entry->dataptr, data->ptr, data->length);
141
142   /* add entry to sendqueue */
143   prev_bsq_entry = (Buffer_Send_Queue *)&bq->sendqueue;
144   bsq = bq->sendqueue;
145
146   while (bsq != 0 && bsq->priority >= prio)
147     {
148       prev_bsq_entry = bsq;
149       bsq = bsq->forward;
150     }
151   if (bsq == 0)
152     {
153       /* beginning or end of the list */
154       prev_bsq_entry->forward = bsq_entry;
155     }
156   else
157     {
158       /* somewhere in the middle */
159       bsq_entry->forward = prev_bsq_entry->forward;
160       prev_bsq_entry->forward = bsq_entry;
161     }
162
163   if (buffer->maxqueuelength != (unsigned long)-1L &&
164       bq->sendqueuelength >= buffer->maxqueuelength)
165     {
166       /* we have to delay this process */
167       bsq_entry->is_delayed = 1;
168       retval = __delay_this (wait_buffer_send, timeout, filename, lineno);
169       if (retval)
170         {
171           prev_bsq_entry->forward = bsq_entry->forward;
172           FREE (bsq_entry);
173         }
174     }
175   else
176     /* just say that there is one more entry in the queue */
177     bq->sendqueuelength++;
178   return retval;
179 }
180
181 /* force function __print_buffer to be linked */
182 extern void __print_buffer ();
183 static EntryPoint pev = __print_buffer;