1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe and others.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public License
7  * as published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20 
21 
22 /*
23  2002 : API design by Peter Hanappe and Antoine Schmitt
24  August 2002 : Implementation by Antoine Schmitt as@gratin.org
25                as part of the infiniteCD author project
26                http://www.infiniteCD.org/
27  Oct4.2002 : AS : corrected bug in heap allocation, that caused a crash during sequencer free.
28 */
29 
30 
31 #include "fluid_event_priv.h"
32 #include "fluidsynth_priv.h"
33 
34 /***************************************************************
35  *
36  *                           SEQUENCER EVENTS
37  */
38 
39 /* Event alloc/free */
40 
41 void
fluid_event_clear(fluid_event_t * evt)42 fluid_event_clear(fluid_event_t* evt)
43 {
44   FLUID_MEMSET(evt, 0, sizeof(fluid_event_t));
45 
46   // by default, no type
47   evt->dest = -1;
48   evt->src = -1;
49   evt->type = -1;
50 }
51 
52 /**
53  * Create a new sequencer event structure.
54  * @return New sequencer event structure or NULL if out of memory
55  */
56 fluid_event_t*
new_fluid_event()57 new_fluid_event()
58 {
59   fluid_event_t* evt;
60 
61   evt = FLUID_NEW(fluid_event_t);
62   if (evt == NULL) {
63     fluid_log(FLUID_PANIC, "event: Out of memory\n");
64     return NULL;
65   }
66   fluid_event_clear(evt);
67 
68   return(evt);
69 }
70 
71 /**
72  * Delete a sequencer event structure.
73  * @param evt Sequencer event structure created by new_fluid_event().
74  */
75 void
delete_fluid_event(fluid_event_t * evt)76 delete_fluid_event(fluid_event_t* evt)
77 {
78 
79   if (evt == NULL) {
80     return;
81   }
82 
83   FLUID_FREE(evt);
84 }
85 
86 /**
87  * Set the time field of a sequencer event.
88  * @internal
89  * @param evt Sequencer event structure
90  * @param time Time value to assign
91  */
92 void
fluid_event_set_time(fluid_event_t * evt,unsigned int time)93 fluid_event_set_time(fluid_event_t* evt, unsigned int time)
94 {
95 	evt->time = time;
96 }
97 
98 /**
99  * Set source of a sequencer event (DOCME).
100  * @param evt Sequencer event structure
101  * @param src DOCME
102  */
103 void
fluid_event_set_source(fluid_event_t * evt,short src)104 fluid_event_set_source(fluid_event_t* evt, short src)
105 {
106 	evt->src = src;
107 }
108 
109 /**
110  * Set destination of a sequencer event (DOCME).
111  * @param evt Sequencer event structure
112  * @param dest DOCME
113  */
114 void
fluid_event_set_dest(fluid_event_t * evt,short dest)115 fluid_event_set_dest(fluid_event_t* evt, short dest)
116 {
117 	evt->dest = dest;
118 }
119 
120 /**
121  * Set a sequencer event to be a timer event.
122  * @param evt Sequencer event structure
123  * @param data DOCME
124  */
125 void
fluid_event_timer(fluid_event_t * evt,void * data)126 fluid_event_timer(fluid_event_t* evt, void* data)
127 {
128 	evt->type = FLUID_SEQ_TIMER;
129 	evt->data = data;
130 }
131 
132 /**
133  * Set a sequencer event to be a note on event.
134  * @param evt Sequencer event structure
135  * @param channel MIDI channel number
136  * @param key MIDI note number (0-127)
137  * @param vel MIDI velocity value (0-127)
138  */
139 void
fluid_event_noteon(fluid_event_t * evt,int channel,short key,short vel)140 fluid_event_noteon(fluid_event_t* evt, int channel, short key, short vel)
141 {
142 	evt->type = FLUID_SEQ_NOTEON;
143 	evt->channel = channel;
144 	evt->key = key;
145 	evt->vel = vel;
146 }
147 
148 /**
149  * Set a sequencer event to be a note off event.
150  * @param evt Sequencer event structure
151  * @param channel MIDI channel number
152  * @param key MIDI note number (0-127)
153  */
154 void
fluid_event_noteoff(fluid_event_t * evt,int channel,short key)155 fluid_event_noteoff(fluid_event_t* evt, int channel, short key)
156 {
157 	evt->type = FLUID_SEQ_NOTEOFF;
158 	evt->channel = channel;
159 	evt->key = key;
160 }
161 
162 /**
163  * Set a sequencer event to be a note duration event.
164  * @param evt Sequencer event structure
165  * @param channel MIDI channel number
166  * @param key MIDI note number (0-127)
167  * @param vel MIDI velocity value (0-127)
168  * @param duration Duration of note (DOCME units?)
169  */
170 void
fluid_event_note(fluid_event_t * evt,int channel,short key,short vel,unsigned int duration)171 fluid_event_note(fluid_event_t* evt, int channel, short key, short vel, unsigned int duration)
172 {
173 	evt->type = FLUID_SEQ_NOTE;
174 	evt->channel = channel;
175 	evt->key = key;
176 	evt->vel = vel;
177 	evt->duration = duration;
178 }
179 
180 /**
181  * Set a sequencer event to be an all sounds off event.
182  * @param evt Sequencer event structure
183  * @param channel MIDI channel number
184  */
185 void
fluid_event_all_sounds_off(fluid_event_t * evt,int channel)186 fluid_event_all_sounds_off(fluid_event_t* evt, int channel)
187 {
188 	evt->type = FLUID_SEQ_ALLSOUNDSOFF;
189 	evt->channel = channel;
190 }
191 
192 /**
193  * Set a sequencer event to be a all notes off event.
194  * @param evt Sequencer event structure
195  * @param channel MIDI channel number
196  */
197 void
fluid_event_all_notes_off(fluid_event_t * evt,int channel)198 fluid_event_all_notes_off(fluid_event_t* evt, int channel)
199 {
200 	evt->type = FLUID_SEQ_ALLNOTESOFF;
201 	evt->channel = channel;
202 }
203 
204 /**
205  * Set a sequencer event to be a bank select event.
206  * @param evt Sequencer event structure
207  * @param channel MIDI channel number
208  * @param bank_num MIDI bank number (0-16383)
209  */
210 void
fluid_event_bank_select(fluid_event_t * evt,int channel,short bank_num)211 fluid_event_bank_select(fluid_event_t* evt, int channel, short bank_num)
212 {
213 	evt->type = FLUID_SEQ_BANKSELECT;
214 	evt->channel = channel;
215 	evt->control = bank_num;
216 }
217 
218 /**
219  * Set a sequencer event to be a program change event.
220  * @param evt Sequencer event structure
221  * @param channel MIDI channel number
222  * @param val MIDI program number (0-127)
223  */
224 void
fluid_event_program_change(fluid_event_t * evt,int channel,short val)225 fluid_event_program_change(fluid_event_t* evt, int channel, short val)
226 {
227 	evt->type = FLUID_SEQ_PROGRAMCHANGE;
228 	evt->channel = channel;
229 	evt->value = val;
230 }
231 
232 /**
233  * Set a sequencer event to be a program select event.
234  * @param evt Sequencer event structure
235  * @param channel MIDI channel number
236  * @param sfont_id SoundFont ID number
237  * @param bank_num MIDI bank number (0-16383)
238  * @param preset_num MIDI preset number (0-127)
239  */
240 void
fluid_event_program_select(fluid_event_t * evt,int channel,unsigned int sfont_id,short bank_num,short preset_num)241 fluid_event_program_select(fluid_event_t* evt, int channel,
242 						  unsigned int sfont_id, short bank_num, short preset_num)
243 {
244 	evt->type = FLUID_SEQ_PROGRAMSELECT;
245 	evt->channel = channel;
246 	evt->duration = sfont_id;
247 	evt->value = preset_num;
248 	evt->control = bank_num;
249 }
250 
251 /**
252  * Set a sequencer event to be an any control change event.
253  * @param evt Sequencer event structure
254  * @param channel MIDI channel number
255  * DOCME
256  */
257 void
fluid_event_any_control_change(fluid_event_t * evt,int channel)258 fluid_event_any_control_change(fluid_event_t* evt, int channel)
259 {
260 	evt->type = FLUID_SEQ_ANYCONTROLCHANGE;
261 	evt->channel = channel;
262 }
263 
264 /**
265  * Set a sequencer event to be a pitch bend event.
266  * @param evt Sequencer event structure
267  * @param channel MIDI channel number
268  * @param pitch MIDI pitch bend value (0-16383, 8192 = no bend)
269  */
270 void
fluid_event_pitch_bend(fluid_event_t * evt,int channel,int pitch)271 fluid_event_pitch_bend(fluid_event_t* evt, int channel, int pitch)
272 {
273 	evt->type = FLUID_SEQ_PITCHBEND;
274 	evt->channel = channel;
275 	if (pitch < 0) pitch = 0;
276 	if (pitch > 16383) pitch = 16383;
277 	evt->pitch = pitch;
278 }
279 
280 /**
281  * Set a sequencer event to be a pitch wheel sensitivity event.
282  * @param evt Sequencer event structure
283  * @param channel MIDI channel number
284  * @param value MIDI pitch wheel sensitivity value (DOCME units?)
285  */
286 void
fluid_event_pitch_wheelsens(fluid_event_t * evt,int channel,short value)287 fluid_event_pitch_wheelsens(fluid_event_t* evt, int channel, short value)
288 {
289 	evt->type = FLUID_SEQ_PITCHWHHELSENS;
290 	evt->channel = channel;
291 	evt->value = value;
292 }
293 
294 /**
295  * Set a sequencer event to be a modulation event.
296  * @param evt Sequencer event structure
297  * @param channel MIDI channel number
298  * @param val MIDI modulation value (0-127)
299  */
300 void
fluid_event_modulation(fluid_event_t * evt,int channel,short val)301 fluid_event_modulation(fluid_event_t* evt, int channel, short val)
302 {
303 	evt->type = FLUID_SEQ_MODULATION;
304 	evt->channel = channel;
305 	if (val < 0) val = 0;
306 	if (val > 127) val = 127;
307 	evt->value = val;
308 }
309 
310 /**
311  * Set a sequencer event to be a MIDI sustain event.
312  * @param evt Sequencer event structure
313  * @param channel MIDI channel number
314  * @param val MIDI sustain value (0-127)
315  */
316 void
fluid_event_sustain(fluid_event_t * evt,int channel,short val)317 fluid_event_sustain(fluid_event_t* evt, int channel, short val)
318 {
319 	evt->type = FLUID_SEQ_SUSTAIN;
320 	evt->channel = channel;
321 	if (val < 0) val = 0;
322 	if (val > 127) val = 127;
323 	evt->value = val;
324 }
325 
326 /**
327  * Set a sequencer event to be a MIDI control change event.
328  * @param evt Sequencer event structure
329  * @param channel MIDI channel number
330  * @param control MIDI control number (0-127)
331  * @param val MIDI control value (0-16383 DOCME is that true?)
332  */
333 void
fluid_event_control_change(fluid_event_t * evt,int channel,short control,short val)334 fluid_event_control_change(fluid_event_t* evt, int channel, short control, short val)
335 {
336 	evt->type = FLUID_SEQ_CONTROLCHANGE;
337 	evt->channel = channel;
338 	evt->control = control;
339 	evt->value = val;
340 }
341 
342 /**
343  * Set a sequencer event to be a stereo pan event.
344  * @param evt Sequencer event structure
345  * @param channel MIDI channel number
346  * @param val MIDI panning value (0-127, 0=left, 64 = middle, 127 = right)
347  */
348 void
fluid_event_pan(fluid_event_t * evt,int channel,short val)349 fluid_event_pan(fluid_event_t* evt, int channel, short val)
350 {
351 	evt->type = FLUID_SEQ_PAN;
352 	evt->channel = channel;
353 	if (val < 0) val = 0;
354 	if (val > 127) val = 127;
355 	evt->value = val;
356 }
357 
358 /**
359  * Set a sequencer event to be a volume event.
360  * @param evt Sequencer event structure
361  * @param channel MIDI channel number
362  * @param val Volume value (0-127)
363  */
364 void
fluid_event_volume(fluid_event_t * evt,int channel,short val)365 fluid_event_volume(fluid_event_t* evt, int channel, short val)
366 {
367 	evt->type = FLUID_SEQ_VOLUME;
368 	evt->channel = channel;
369 	if (val < 0) val = 0;
370 	if (val > 127) val = 127;
371 	evt->value = val;
372 }
373 
374 /**
375  * Set a sequencer event to be a reverb send event.
376  * @param evt Sequencer event structure
377  * @param channel MIDI channel number
378  * @param val Reverb amount (0-127)
379  */
380 void
fluid_event_reverb_send(fluid_event_t * evt,int channel,short val)381 fluid_event_reverb_send(fluid_event_t* evt, int channel, short val)
382 {
383 	evt->type = FLUID_SEQ_REVERBSEND;
384 	evt->channel = channel;
385 	if (val < 0) val = 0;
386 	if (val > 127) val = 127;
387 	evt->value = val;
388 }
389 
390 /**
391  * Set a sequencer event to be a chorus send event.
392  * @param evt Sequencer event structure
393  * @param channel MIDI channel number
394  * @param val Chorus amount (0-127)
395  */
396 void
fluid_event_chorus_send(fluid_event_t * evt,int channel,short val)397 fluid_event_chorus_send(fluid_event_t* evt, int channel, short val)
398 {
399 	evt->type = FLUID_SEQ_CHORUSSEND;
400 	evt->channel = channel;
401 	if (val < 0) val = 0;
402 	if (val > 127) val = 127;
403 	evt->value = val;
404 }
405 
406 
407 /**
408  * Set a sequencer event to be an unregistering event.
409  * @param evt Sequencer event structure
410  * @since 1.1.0
411  */
412 void
fluid_event_unregistering(fluid_event_t * evt)413 fluid_event_unregistering(fluid_event_t* evt)
414 {
415 	evt->type = FLUID_SEQ_UNREGISTERING;
416 }
417 
418 /**
419  * Set a sequencer event to be a channel-wide aftertouch event.
420  * @param evt Sequencer event structure
421  * @param channel MIDI channel number
422  * @param val Aftertouch amount (0-127)
423  * @since 1.1.0
424  */
425 void
fluid_event_channel_pressure(fluid_event_t * evt,int channel,short val)426 fluid_event_channel_pressure(fluid_event_t* evt, int channel, short val)
427 {
428 	evt->type = FLUID_SEQ_CHANNELPRESSURE;
429 	evt->channel = channel;
430 	if (val < 0) val = 0;
431 	if (val > 127) val = 127;
432 	evt->value = val;
433 }
434 
435 /**
436  * Set a sequencer event to be a midi system reset event.
437  * @param evt Sequencer event structure
438  * @since 1.1.0
439  */
440 void
fluid_event_system_reset(fluid_event_t * evt)441 fluid_event_system_reset(fluid_event_t* evt)
442 {
443 	evt->type = FLUID_SEQ_SYSTEMRESET;
444 }
445 
446 
447 
448 /*
449  * Accessing event data
450  */
451 
452 /**
453  * Get the event type (#fluid_seq_event_type) field from a sequencer event structure.
454  * @param evt Sequencer event structure
455  * @return Event type (#fluid_seq_event_type).
456  */
fluid_event_get_type(fluid_event_t * evt)457 int fluid_event_get_type(fluid_event_t* evt)
458 {
459 	return evt->type;
460 }
461 
462 /**
463  * Get the time field from a sequencer event structure.
464  * @param evt Sequencer event structure
465  * @return Time value (DOCME units?)
466  */
fluid_event_get_time(fluid_event_t * evt)467 unsigned int fluid_event_get_time(fluid_event_t* evt)
468 {
469 	return evt->time;
470 }
471 
472 /**
473  * Get the source field from a sequencer event structure.
474  * @param evt Sequencer event structure
475  * @return DOCME
476  */
fluid_event_get_source(fluid_event_t * evt)477 short fluid_event_get_source(fluid_event_t* evt)
478 {
479 	return evt->src;
480 }
481 
482 /**
483  * Get the dest field from a sequencer event structure.
484  * @param evt Sequencer event structure
485  * @return DOCME
486  */
fluid_event_get_dest(fluid_event_t * evt)487 short fluid_event_get_dest(fluid_event_t* evt)
488 {
489 	return evt->dest;
490 }
491 
492 /**
493  * Get the MIDI channel field from a sequencer event structure.
494  * @param evt Sequencer event structure
495  * @return MIDI channel number (DOCME 0-15 or more?)
496  */
fluid_event_get_channel(fluid_event_t * evt)497 int fluid_event_get_channel(fluid_event_t* evt)
498 {
499 	return evt->channel;
500 }
501 
502 /**
503  * Get the MIDI note field from a sequencer event structure.
504  * @param evt Sequencer event structure
505  * @return MIDI note number (0-127)
506  */
fluid_event_get_key(fluid_event_t * evt)507 short fluid_event_get_key(fluid_event_t* evt)
508 {
509 	return evt->key;
510 }
511 
512 /**
513  * Get the MIDI velocity field from a sequencer event structure.
514  * @param evt Sequencer event structure
515  * @return MIDI velocity value (0-127)
516  */
fluid_event_get_velocity(fluid_event_t * evt)517 short fluid_event_get_velocity(fluid_event_t* evt)
518 
519 {
520 	return evt->vel;
521 }
522 
523 /**
524  * Get the MIDI control number field from a sequencer event structure.
525  * @param evt Sequencer event structure
526  * @return MIDI control number (0-127)
527  */
fluid_event_get_control(fluid_event_t * evt)528 short fluid_event_get_control(fluid_event_t* evt)
529 {
530 	return evt->control;
531 }
532 
533 /**
534  * Get the value field from a sequencer event structure.
535  * @param evt Sequencer event structure
536  * @return Value field of event.
537  *
538  * The Value field is used by the following event types:
539  * #FLUID_SEQ_PROGRAMCHANGE, #FLUID_SEQ_PROGRAMSELECT (preset_num),
540  * #FLUID_SEQ_PITCHWHHELSENS, #FLUID_SEQ_MODULATION, #FLUID_SEQ_SUSTAIN,
541  * #FLUID_SEQ_CONTROLCHANGE, #FLUID_SEQ_PAN, #FLUID_SEQ_VOLUME,
542  * #FLUID_SEQ_REVERBSEND, #FLUID_SEQ_CHORUSSEND.
543  */
fluid_event_get_value(fluid_event_t * evt)544 short fluid_event_get_value(fluid_event_t* evt)
545 {
546 	return evt->value;
547 }
548 
549 /**
550  * Get the data field from a sequencer event structure.
551  * @param evt Sequencer event structure
552  * @return Data field of event.
553  *
554  * Used by the #FLUID_SEQ_TIMER event type.
555  */
fluid_event_get_data(fluid_event_t * evt)556 void* fluid_event_get_data(fluid_event_t* evt)
557 {
558 	return evt->data;
559 }
560 
561 /**
562  * Get the duration field from a sequencer event structure.
563  * @param evt Sequencer event structure
564  * @return Note duration value (DOCME units?)
565  *
566  * Used by the #FLUID_SEQ_NOTE event type.
567  */
fluid_event_get_duration(fluid_event_t * evt)568 unsigned int fluid_event_get_duration(fluid_event_t* evt)
569 {
570 	return evt->duration;
571 }
572 
573 /**
574  * Get the MIDI bank field from a sequencer event structure.
575  * @param evt Sequencer event structure
576  * @return MIDI bank number (0-16383)
577  *
578  * Used by the #FLUID_SEQ_BANKSELECT and #FLUID_SEQ_PROGRAMSELECT
579  * event types.
580  */
fluid_event_get_bank(fluid_event_t * evt)581 short fluid_event_get_bank(fluid_event_t* evt)
582 {
583 	return evt->control;
584 }
585 
586 /**
587  * Get the pitch field from a sequencer event structure.
588  * @param evt Sequencer event structure
589  * @return MIDI pitch bend pitch value (0-16383, 8192 = no bend)
590  *
591  * Used by the #FLUID_SEQ_PITCHBEND event type.
592  */
fluid_event_get_pitch(fluid_event_t * evt)593 int fluid_event_get_pitch(fluid_event_t* evt)
594 {
595 	return evt->pitch;
596 }
597 
598 /**
599  * Get the MIDI program field from a sequencer event structure.
600  * @param evt Sequencer event structure
601  * @return MIDI program number (0-127)
602  *
603  * Used by the #FLUID_SEQ_PROGRAMCHANGE and #FLUID_SEQ_PROGRAMSELECT
604  * event types.
605  */
606 short
fluid_event_get_program(fluid_event_t * evt)607 fluid_event_get_program(fluid_event_t* evt)
608 {
609 	return evt->value;
610 }
611 
612 /**
613  * Get the SoundFont ID field from a sequencer event structure.
614  * @param evt Sequencer event structure
615  * @return SoundFont identifier value.
616  *
617  * Used by the #FLUID_SEQ_PROGRAMSELECT event type.
618  */
619 unsigned int
fluid_event_get_sfont_id(fluid_event_t * evt)620 fluid_event_get_sfont_id(fluid_event_t* evt)
621 {
622 	return evt->duration;
623 }
624 
625 
626 
627 /********************/
628 /* heap management  */
629 /********************/
630 
631 fluid_evt_heap_t*
_fluid_evt_heap_init(int nbEvents)632 _fluid_evt_heap_init(int nbEvents)
633 {
634 #ifdef HEAP_WITH_DYNALLOC
635 
636   int i;
637   fluid_evt_heap_t* heap;
638   fluid_evt_entry *tmp;
639 
640   heap = FLUID_NEW(fluid_evt_heap_t);
641   if (heap == NULL) {
642     fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
643     return NULL;
644   }
645 
646   heap->freelist = NULL;
647   fluid_mutex_init(heap->mutex);
648 
649   /* LOCK */
650   fluid_mutex_lock(heap->mutex);
651 
652   /* Allocate the event entries */
653   for (i = 0; i < nbEvents; i++) {
654     tmp = FLUID_NEW(fluid_evt_entry);
655     tmp->next = heap->freelist;
656     heap->freelist = tmp;
657   }
658 
659   /* UNLOCK */
660   fluid_mutex_unlock(heap->mutex);
661 
662 
663 #else
664 	int i;
665 	fluid_evt_heap_t* heap;
666 	int siz = 2*sizeof(fluid_evt_entry *) + sizeof(fluid_evt_entry)*nbEvents;
667 
668 	heap = (fluid_evt_heap_t *)FLUID_MALLOC(siz);
669   if (heap == NULL) {
670     fluid_log(FLUID_PANIC, "sequencer: Out of memory\n");
671     return NULL;
672   }
673   FLUID_MEMSET(heap, 0, siz);
674 
675   /* link all heap events */
676   {
677   	fluid_evt_entry *tmp = &(heap->pool);
678 	  for (i = 0 ; i < nbEvents - 1 ; i++)
679  		 	tmp[i].next = &(tmp[i+1]);
680  	 	tmp[nbEvents-1].next = NULL;
681 
682  	 	/* set head & tail */
683  	 	heap->tail = &(tmp[nbEvents-1]);
684   	heap->head = &(heap->pool);
685   }
686 #endif
687   return (heap);
688 }
689 
690 void
_fluid_evt_heap_free(fluid_evt_heap_t * heap)691 _fluid_evt_heap_free(fluid_evt_heap_t* heap)
692 {
693 #ifdef HEAP_WITH_DYNALLOC
694   fluid_evt_entry *tmp, *next;
695 
696   /* LOCK */
697   fluid_mutex_lock(heap->mutex);
698 
699   tmp = heap->freelist;
700   while (tmp) {
701     next = tmp->next;
702     FLUID_FREE(tmp);
703     tmp = next;
704   }
705 
706   /* UNLOCK */
707   fluid_mutex_unlock(heap->mutex);
708   fluid_mutex_destroy(heap->mutex);
709 
710   FLUID_FREE(heap);
711 
712 #else
713 	FLUID_FREE(heap);
714 #endif
715 }
716 
717 fluid_evt_entry*
_fluid_seq_heap_get_free(fluid_evt_heap_t * heap)718 _fluid_seq_heap_get_free(fluid_evt_heap_t* heap)
719 {
720 #ifdef HEAP_WITH_DYNALLOC
721   fluid_evt_entry* evt = NULL;
722 
723   /* LOCK */
724   fluid_mutex_lock(heap->mutex);
725 
726 #if !defined(MACOS9)
727   if (heap->freelist == NULL) {
728     heap->freelist = FLUID_NEW(fluid_evt_entry);
729     if (heap->freelist != NULL) {
730       heap->freelist->next = NULL;
731     }
732   }
733 #endif
734 
735   evt = heap->freelist;
736 
737   if (evt != NULL) {
738     heap->freelist = heap->freelist->next;
739     evt->next = NULL;
740   }
741 
742   /* UNLOCK */
743   fluid_mutex_unlock(heap->mutex);
744 
745   return evt;
746 
747 #else
748 	fluid_evt_entry* evt;
749 	if (heap->head == NULL) return NULL;
750 
751 	/* take from head of the heap */
752 	/* critical - should threadlock ? */
753 	evt = heap->head;
754 	heap->head = heap->head->next;
755 
756 	return evt;
757 #endif
758 }
759 
760 void
_fluid_seq_heap_set_free(fluid_evt_heap_t * heap,fluid_evt_entry * evt)761 _fluid_seq_heap_set_free(fluid_evt_heap_t* heap, fluid_evt_entry* evt)
762 {
763 #ifdef HEAP_WITH_DYNALLOC
764 
765   /* LOCK */
766   fluid_mutex_lock(heap->mutex);
767 
768   evt->next = heap->freelist;
769   heap->freelist = evt;
770 
771   /* UNLOCK */
772   fluid_mutex_unlock(heap->mutex);
773 
774 #else
775 	/* append to the end of the heap */
776 	/* critical - should threadlock ? */
777 	heap->tail->next = evt;
778 	heap->tail = evt;
779 	evt->next = NULL;
780 #endif
781 }
782