1 /*
2 auxfd.c:
3
4 Copyright (C) 1991 Barry Vercoe, John ffitch
5
6 This file is part of Csound.
7
8 The Csound Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 Csound is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with Csound; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 02110-1301 USA
22 */
23
24 #include "csoundCore.h" /* AUXFD.C */
25
26 static CS_NOINLINE void auxchprint(CSOUND *, INSDS *);
27 static CS_NOINLINE void fdchprint(CSOUND *, INSDS *);
28
29 /* allocate an auxds, or expand an old one */
30 /* call only from init (xxxset) modules */
31
csoundAuxAlloc(CSOUND * csound,size_t nbytes,AUXCH * auxchp)32 void csoundAuxAlloc(CSOUND *csound, size_t nbytes, AUXCH *auxchp)
33 {
34 if (auxchp->auxp != NULL) {
35 /* if allocd with same size, just clear to zero */
36 if (nbytes == (size_t)auxchp->size) {
37 memset(auxchp->auxp, 0, nbytes);
38 return;
39 }
40 else {
41 void *tmp = auxchp->auxp;
42 /* if size change only, free the old space and re-allocate */
43 auxchp->auxp = NULL;
44 csound->Free(csound, tmp);
45 }
46 }
47 else { /* else link in new auxch blk */
48 auxchp->nxtchp = csound->curip->auxchp;
49 csound->curip->auxchp = auxchp;
50 }
51 /* now alloc the space and update the internal data */
52 auxchp->size = nbytes;
53 auxchp->auxp = csound->Calloc(csound, nbytes);
54 auxchp->endp = (char*)auxchp->auxp + nbytes;
55 if (UNLIKELY(csound->oparms->odebug))
56 auxchprint(csound, csound->curip);
57 }
58
59
alloc_thread(void * p)60 static uintptr_t alloc_thread(void *p) {
61 AUXASYNC *pp = (AUXASYNC *) p;
62 CSOUND *csound = pp->csound;
63 AUXCH newm;
64 char *ptr;
65 if (pp->auxchp->auxp == NULL) {
66 /* Allocate new memory */
67 newm.size = pp->nbytes;
68 newm.auxp = csound->Calloc(csound, pp->nbytes);
69 newm.endp = (char*) newm.auxp + pp->nbytes;
70 ptr = (char *) newm.auxp;
71 newm = *(pp->notify(csound, pp->userData, &newm));
72 /* check that the returned pointer is not
73 NULL and that is not the memory we have
74 just allocated in case the old memory was
75 never swapped back.
76 */
77 if (newm.auxp != NULL && newm.auxp != ptr)
78 csound->Free(csound, newm.auxp);
79 } else {
80 csoundAuxAlloc(csound,pp->nbytes,pp->auxchp);
81 pp->notify(csound, pp->userData, pp->auxchp);
82 }
83 return 0;
84 }
85
86
87
88 /* Allocate an auxds asynchronously and
89 pass the newly allocated memory via a
90 callback, where it can be swapped if necessary.
91 */
csoundAuxAllocAsync(CSOUND * csound,size_t nbytes,AUXCH * auxchp,AUXASYNC * as,aux_cb cb,void * userData)92 int csoundAuxAllocAsync(CSOUND *csound, size_t nbytes, AUXCH *auxchp,
93 AUXASYNC *as, aux_cb cb, void *userData) {
94 as->csound = csound;
95 as->nbytes = nbytes;
96 as->auxchp = auxchp;
97 as->notify = cb;
98 as->userData = userData;
99 if (UNLIKELY(csoundCreateThread(alloc_thread, as) == NULL))
100 return CSOUND_ERROR;
101 else
102 return CSOUND_SUCCESS;
103 }
104
105
106 /* put fdchp into chain of fd's for this instr */
107 /* call only from init (xxxset) modules */
108
fdrecord(CSOUND * csound,FDCH * fdchp)109 void fdrecord(CSOUND *csound, FDCH *fdchp)
110 {
111 fdchp->nxtchp = csound->curip->fdchp;
112 csound->curip->fdchp = fdchp;
113 if (UNLIKELY(csound->oparms->odebug))
114 fdchprint(csound, csound->curip);
115 }
116
117 /* close a file and remove from fd chain */
118 /* call only from inits, after fdrecord */
119
csound_fd_close(CSOUND * csound,FDCH * fdchp)120 void csound_fd_close(CSOUND *csound, FDCH *fdchp)
121 {
122 FDCH *prvchp = NULL, *nxtchp;
123
124 nxtchp = csound->curip->fdchp; /* from current insds, */
125 while (LIKELY(nxtchp != NULL)) { /* chain through fdlocs */
126 if (UNLIKELY(nxtchp == fdchp)) { /* till find this one */
127 void *fd = fdchp->fd;
128 if (LIKELY(fd)) {
129 fdchp->fd = NULL; /* then delete the fd */
130 csoundFileClose(csound, fd); /* close the file & */
131 }
132 if (prvchp)
133 prvchp->nxtchp = fdchp->nxtchp; /* unlnk from fdchain */
134 else
135 csound->curip->fdchp = fdchp->nxtchp;
136 if (UNLIKELY(csound->oparms->odebug))
137 fdchprint(csound, csound->curip);
138 return;
139 }
140 prvchp = nxtchp;
141 nxtchp = nxtchp->nxtchp;
142 }
143 fdchprint(csound, csound->curip);
144 csound->Die(csound, Str("csound_fd_close: no record of fd %p"), fdchp->fd);
145 }
146
147 /* release all xds in instr auxp chain */
148 /* called by insert at orcompact */
149
auxchfree(CSOUND * csound,INSDS * ip)150 void auxchfree(CSOUND *csound, INSDS *ip)
151 {
152 if (UNLIKELY(csound->oparms->odebug))
153 auxchprint(csound, ip);
154 while (LIKELY(ip->auxchp != NULL)) { /* for all auxp's in chain: */
155 void *auxp = (void*) ip->auxchp->auxp;
156 AUXCH *nxt = ip->auxchp->nxtchp;
157 memset((void*) ip->auxchp, 0, sizeof(AUXCH)); /* delete the pntr */
158 csound->Free(csound, auxp); /* & free the space */
159 ip->auxchp = nxt;
160 }
161 if (UNLIKELY(csound->oparms->odebug))
162 auxchprint(csound, ip);
163 }
164
165 /* close all files in instr fd chain */
166 /* called by insert on deact & expire */
167 /* (also musmon on s-code, & fgens for gen01) */
168
fdchclose(CSOUND * csound,INSDS * ip)169 void fdchclose(CSOUND *csound, INSDS *ip)
170 {
171 if (UNLIKELY(csound->oparms->odebug))
172 fdchprint(csound, ip);
173 /* for all fd's in chain: */
174 for ( ; ip->fdchp != NULL; ip->fdchp = ip->fdchp->nxtchp) {
175 void *fd = ip->fdchp->fd;
176 if (LIKELY(fd)) {
177 ip->fdchp->fd = NULL; /* delete the fd */
178 csoundFileClose(csound, fd); /* & close the file */
179 }
180 }
181 if (UNLIKELY(csound->oparms->odebug))
182 fdchprint(csound, ip);
183 }
184
185 /* print the xp chain for this insds blk */
186
auxchprint(CSOUND * csound,INSDS * ip)187 static CS_NOINLINE void auxchprint(CSOUND *csound, INSDS *ip)
188 {
189 AUXCH *curchp;
190 char *name = csound->engineState.instrtxtp[ip->insno]->insname;
191
192 if (name)
193 csoundMessage(csound, Str("auxlist for instr %s [%d] (%p):\n"),
194 name, ip->insno, ip);
195 else
196 csoundMessage(csound, Str("auxlist for instr %d (%p):\n"),
197 ip->insno, ip);
198 /* chain through auxlocs */
199 for (curchp = ip->auxchp; curchp != NULL; curchp = curchp->nxtchp)
200 csoundMessage(csound,
201 Str("\tauxch at %p: size %zu, auxp %p, endp %p\n"),
202 curchp, curchp->size, curchp->auxp, curchp->endp);
203 }
204
205 /* print the fd chain for this insds blk */
206
fdchprint(CSOUND * csound,INSDS * ip)207 static CS_NOINLINE void fdchprint(CSOUND *csound, INSDS *ip)
208 {
209 FDCH *curchp;
210 char *name = csound->engineState.instrtxtp[ip->insno]->insname;
211
212 if (name)
213 csoundMessage(csound, Str("fdlist for instr %s [%d] (%p):"),
214 name, ip->insno, ip);
215 else
216 csoundMessage(csound, Str("fdlist for instr %d (%p):"), ip->insno, ip);
217 /* chain through fdlocs */
218 for (curchp = ip->fdchp; curchp != NULL; curchp = curchp->nxtchp)
219 csoundMessage(csound, Str(" fd %p in %p"), curchp->fd, curchp);
220 csoundMessage(csound, "\n");
221 }
222