]>
Commit | Line | Data |
---|---|---|
b79f73df JL |
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 | |
201853b4 JL |
19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | |
b79f73df | 21 | |
502b941f JL |
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 | ||
b79f73df JL |
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; |